# File Events

`FileWatching.poll_fd` — Function

    poll_fd(fd, timeout_s::Real=-1; readable=false, writable=false)

Monitor a file descriptor `fd` for changes in the read or write availability, and with a timeout given by `timeout_s` seconds.

The keyword arguments determine which of read and/or write status should be monitored; at least one of them must be set to `true`.

The returned value is an object with boolean fields `readable`, `writable`, and `timedout`, giving the result of the polling.

This is a thin wrapper over calling `wait` on a `FDWatcher`, which implements the functionality but requires the user to call `close` manually when finished with it, or risk serious crashes.

source
`FileWatching.poll_file` — Function

    poll_file(path::AbstractString, interval_s::Real=5.007, timeout_s::Real=-1) -> (previous::StatStruct, current)

Monitor a file for changes by polling every `interval_s` seconds until a change occurs or `timeout_s` seconds have elapsed. The `interval_s` should be a long period; the default is 5.007 seconds.

Returns a pair of status objects `(previous, current)` when a change is detected. The `previous` status is always a `StatStruct`, but it may have all of the fields zeroed (indicating the file didn't previously exist, or wasn't previously accessible).

The `current` status object may be a `StatStruct`, an `EOFError` (indicating the timeout elapsed), or some other `Exception` subtype (if the `stat` operation failed: for example, if the path does not exist).

To determine when a file was modified, compare `!(current isa StatStruct && prev == current)` to detect notification of changes to the mtime or inode. However, using `watch_file` for this operation is preferred, since it is more reliable and efficient, although in some situations it may not be available.

This is a thin wrapper over calling `wait` on a `PollingFileWatcher`, which implements the functionality, but this function has a small race window between consecutive calls to `poll_file` where the file might change without being detected.

source
`FileWatching.watch_file` — Function

    watch_file(path::AbstractString, timeout_s::Real=-1)

Watch file or directory `path` for changes until a change occurs or `timeout_s` seconds have elapsed. This function does not poll the file system and instead uses platform-specific functionality to receive notifications from the operating system (e.g. via inotify on Linux). See the NodeJS documentation linked below for details.

The returned value is an object with boolean fields `renamed`, `changed`, and `timedout`, giving the result of watching the file.

This behavior of this function varies slightly across platforms. See https://nodejs.org/api/fs.html#fs_caveats for more detailed information.

This is a thin wrapper over calling `wait` on a `FileMonitor`. This function has a small race window between consecutive calls to `watch_file` where the file might change without being detected. To avoid this race, use

    fm = FileMonitor(path)
    wait(fm)

directly, re-using the same `fm` each time you `wait`.

source
`FileWatching.watch_folder` — Function

    watch_folder(path::AbstractString, timeout_s::Real=-1)

Watch a file or directory `path` for changes until a change has occurred or `timeout_s` seconds have elapsed. This function does not poll the file system and instead uses platform-specific functionality to receive notifications from the operating system (e.g. via inotify on Linux). See the NodeJS documentation linked below for details.

This will continuing tracking changes for `path` in the background until `unwatch_folder` is called on the same `path`.

The returned value is an pair where the first field is the name of the changed file (if available) and the second field is an object with boolean fields `renamed`, `changed`, and `timedout`, giving the event.

This behavior of this function varies slightly across platforms. See https://nodejs.org/api/fs.html#fs_caveats for more detailed information.

This function is a thin wrapper over calling `wait` on a `FolderMonitor`, with added timeout support.

source
`FileWatching.unwatch_folder` — Function

    unwatch_folder(path::AbstractString)

Stop background tracking of changes for `path`. It is not recommended to do this while another task is waiting for `watch_folder` to return on the same path, as the result may be unpredictable.

source
`FileWatching.FileMonitor` — Type

    FileMonitor(path::AbstractString)

Watch file or directory `path` (which must exist) for changes until a change occurs. This function does not poll the file system and instead uses platform-specific functionality to receive notifications from the operating system (e.g. via inotify on Linux). See the NodeJS documentation linked below for details.

`fm = FileMonitor(path)` acts like an auto-reset Event, so `wait(fm)` blocks until there has been at least one event in the file originally at the given path and then returns an object with boolean fields `renamed`, `changed`, `timedout` summarizing all changes that have occurred since the last call to `wait` returned.

This behavior of this function varies slightly across platforms. See https://nodejs.org/api/fs.html#fs_caveats for more detailed information.

source
`FileWatching.FolderMonitor` — Type

    FolderMonitor(folder::AbstractString)

Watch a file or directory `path` for changes until a change has occurred. This function does not poll the file system and instead uses platform-specific functionality to receive notifications from the operating system (e.g. via inotify on Linux). See the NodeJS documentation linked below for details.

This acts similar to a Channel, so calling `take!` (or `wait`) blocks until some change has occurred. The `wait` function will return a pair where the first field is the name of the changed file (if available) and the second field is an object with boolean fields `renamed` and `changed`, giving the event that occurred on it.

This behavior of this function varies slightly across platforms. See https://nodejs.org/api/fs.html#fs_caveats for more detailed information.

source
`FileWatching.PollingFileWatcher` — Type

    PollingFileWatcher(path::AbstractString, interval_s::Real=5.007)

Monitor a file for changes by polling `stat` every `interval_s` seconds until a change occurs or `timeout_s` seconds have elapsed. The `interval_s` should be a long period; the default is 5.007 seconds. Call `stat` on it to get the most recent, but old, result.

This acts like an auto-reset Event, so calling `wait` blocks until the `stat` result has changed since the previous value captured upon entry to the `wait` call. The `wait` function will return a pair of status objects `(previous, current)` once any `stat` change is detected since the previous time that `wait` was called. The `previous` status is always a `StatStruct`, but it may have all of the fields zeroed (indicating the file didn't previously exist, or wasn't previously accessible).

The `current` status object may be a `StatStruct`, an `EOFError` (if the wait is canceled by closing this object), or some other `Exception` subtype (if the `stat` operation failed: for example, if the path is removed). Note that `stat` value may be outdated if the file has changed again multiple times.

Using `FileMonitor` for this operation is preferred, since it is more reliable and efficient, although in some situations it may not be available.

source
`FileWatching.FDWatcher` — Type

    FDWatcher(fd::Union{RawFD,WindowsRawSocket}, readable::Bool, writable::Bool)

Monitor a file descriptor `fd` for changes in the read or write availability.

The keyword arguments determine which of read and/or write status should be monitored; at least one of them must be set to `true`.

The returned value is an object with boolean fields `readable`, `writable`, and `timedout`, giving the result of the polling.

This acts like a level-set event, so calling `wait` blocks until one of those conditions is met, but then continues to return without blocking until the condition is cleared (either there is no more to read, or no more space in the write buffer, or both).

Warning

You must call `close` manually, when finished with this object, before the fd argument is closed. Failure to do so risks serious crashes.

source

# Pidfile

A simple utility tool for creating advisory pidfiles (lock files).

## Primary Functions

`FileWatching.Pidfile.mkpidlock` — Function

    mkpidlock([f::Function], at::String, [pid::Cint]; kwopts...)
    mkpidlock(at::String, proc::Process; kwopts...)

Create a pidfile lock for the path "at" for the current process or the process identified by pid or proc. Can take a function to execute once locked, for usage in `do` blocks, after which the lock will be automatically closed. If the lock fails and `wait` is false, then an error is thrown.

The lock will be released by either `close`, a `finalizer`, or shortly after `proc` exits. Make sure the return value is live through the end of the critical section of your program, so the `finalizer` does not reclaim it early.

Optional keyword arguments:

- `mode`: file access mode (modified by the process umask). Defaults to world-readable.
- `poll_interval`: Specify the maximum time to between attempts (if `watch_file` doesn't work)
- `stale_age`: Delete an existing pidfile (ignoring the lock) if it is older than this many seconds, based on its mtime. The file won't be deleted until 5x longer than this if the pid in the file appears that it may be valid. Or 25x longer if `refresh` is overridden to 0 to disable lock refreshing. By default this is disabled (`stale_age` = 0), but a typical recommended value would be about 3-5x an estimated normal completion time.
- `refresh`: Keeps a lock from becoming stale by updating the mtime every interval of time that passes. By default, this is set to `stale_age/2`, which is the recommended value.
- `wait`: If true, block until we get the lock, if false, raise error if lock fails.

source
`FileWatching.Pidfile.trymkpidlock` — Function

    trymkpidlock([f::Function], at::String, [pid::Cint]; kwopts...)
    trymkpidlock(at::String, proc::Process; kwopts...)

Like `mkpidlock` except returns `false` instead of waiting if the file is already locked.

Julia 1.10

This function requires at least Julia 1.10.

source
`Base.close` — Method

    close(lock::LockMonitor)

Release a pidfile lock.

source

## Helper Functions

`FileWatching.Pidfile.open_exclusive` — Function

    open_exclusive(path::String; mode, poll_interval, wait, stale_age, refresh) :: File

Create a new a file for read-write advisory-exclusive access. If `wait` is `false` then error out if the lock files exist otherwise block until we get the lock.

For a description of the keyword arguments, see `mkpidlock`.

source
`FileWatching.Pidfile.tryopen_exclusive` — Function

    tryopen_exclusive(path::String, mode::Integer = 0o444) :: Union{Void, File}

Try to create a new file for read-write advisory-exclusive access, return nothing if it already exists.

source
`FileWatching.Pidfile.write_pidfile` — Function

    write_pidfile(io, pid)

Write our pidfile format to an open IO descriptor.

source
`FileWatching.Pidfile.parse_pidfile` — Function

    parse_pidfile(file::Union{IO, String}) => (pid, hostname, age)

Attempt to parse our pidfile format, replaced an element with (0, "", 0.0), respectively, for any read that failed.

source
`FileWatching.Pidfile.stale_pidfile` — Function

    stale_pidfile(path::String, stale_age::Real, refresh::Real) :: Bool

Helper function for `open_exclusive` for deciding if a pidfile is stale.

source
`FileWatching.Pidfile.isvalidpid` — Function

    isvalidpid(hostname::String, pid::Cuint) :: Bool

Attempt to conservatively estimate whether pid is a valid process id.

source
`Base.Filesystem.touch` — Method

    Base.touch(::Pidfile.LockMonitor)

Update the `mtime` on the lock, to indicate it is still fresh.

See also the `refresh` keyword in the `mkpidlock` constructor.

source

Theme

This document was generated with Documenter.jl version 1.16.0 on Thursday 20 November 2025. Using Julia version 1.12.2.