Module Filesystem_core

val executable_name : File_path.t Core.Lazy.t

The currently running executable.

OCaml semantics do not guarantee an absolute path here.

File I/O Wrappers

These functions abstract over either In_channel and Out_channel, or Async.Reader and Async.Writer.

val read_file : File_path.t -> string Core.Monad.Ident.t
val write_file : ?perm:Filesystem_types.File_permissions.t -> File_path.t -> contents:string -> unit Core.Monad.Ident.t
val load_sexps : File_path.t -> Core.Sexp.t list Core.Monad.Ident.t
val load_as_sexp : File_path.t -> of_sexp:(Core.Sexp.t -> 'a) -> 'a Core.Monad.Ident.t
val load_as_sexps : File_path.t -> of_sexp:(Core.Sexp.t -> 'a) -> 'a list Core.Monad.Ident.t
val save_as_sexp : ?perm:Filesystem_types.File_permissions.t -> File_path.t -> 'a -> sexp_of:('a -> Core.Sexp.t) -> unit Core.Monad.Ident.t
val save_as_sexps : ?perm:Filesystem_types.File_permissions.t -> File_path.t -> 'a list -> sexp_of:('a -> Core.Sexp.t) -> unit Core.Monad.Ident.t

Filename Wrappers

These functions abstract over Filename_unix.

val realpath_relative_to_cwd : File_path.t -> File_path.Absolute.t Core.Monad.Ident.t

Sys Wrappers

These functions abstract over either Core.Sys or Async.Sys.

val exists : ?follow_symlinks:bool -> File_path.t -> [ `Yes | `No | `Unknown ] Core.Monad.Ident.t
val exists_exn : ?follow_symlinks:bool -> File_path.t -> bool Core.Monad.Ident.t
val is_directory : ?follow_symlinks:bool -> File_path.t -> [ `Yes | `No | `Unknown ] Core.Monad.Ident.t
val is_directory_exn : ?follow_symlinks:bool -> File_path.t -> bool Core.Monad.Ident.t
val is_file : ?follow_symlinks:bool -> File_path.t -> [ `Yes | `No | `Unknown ] Core.Monad.Ident.t
val is_file_exn : ?follow_symlinks:bool -> File_path.t -> bool Core.Monad.Ident.t

Unix Wrappers

These functions abstract over either Core_unix or Async.Unix.

val rmdir : File_path.t -> unit Core.Monad.Ident.t

Please note that rmdir raises on a non-empty directory. If you want to delete a directory and all of its contents, see rm.

val chdir : File_path.t -> unit Core.Monad.Ident.t
val rename : src:File_path.t -> dst:File_path.t -> unit Core.Monad.Ident.t
val mkdir : ?parents:bool -> ?perm:Filesystem_types.File_permissions.t -> File_path.t -> unit Core.Monad.Ident.t
val update_timestamps : ?at:Core.Time_ns.t -> File_path.t -> unit Core.Monad.Ident.t

Set the file's access_time and modify_time to at.

val update_timestamps_separately : File_path.t -> access_time:Core.Time_ns.t -> modify_time:Core.Time_ns.t -> unit Core.Monad.Ident.t

Set the file's access_time and modify_time to the given values.

Command-line tool functionality

These functions provide similar functionality to command-line tools like rm, either by mimicking them or by calling them directly.

val rm : ?force:bool -> ?recursive:bool -> File_path.t -> unit Core.Monad.Ident.t

Removes files.

If ~recursive:true is supplied, also recursively removes directories.

If ~force:false is supplied, will raise if given nonexistent or write-protected files. Defaults to true because programmatically-called rm is not interactive, we expect it to just succeed silently.

Links, both hard and symbolic

Creates the given path as a hard link to referring_to.

Creates the given path as a symbolic link to referring_to.

Reads the contents of a symbolic link.

As symlink. Raises if referring_to is not a valid path, but preserves non-canonical paths such as "multiple//and//trailing/".

As readlink. Preserves non-canonical paths such as "multiple//and//trailing/".

Current Directory Functions

These functions combine File_path and getcwd.

val make_absolute_under_cwd : File_path.t -> File_path.Absolute.t Core.Monad.Ident.t

Like File_path.make_absolute ~under:(getcwd ()). Avoids calling getcwd unless necessary.

val make_relative_to_cwd : File_path.t -> File_path.Relative.t option Core.Monad.Ident.t

Like File_path.make_relative ~if_under:(getcwd ()). Avoids calling getcwd unless necessary.

val make_relative_to_cwd_exn : File_path.t -> File_path.Relative.t Core.Monad.Ident.t

Like make_relative_to_cwd. Raises instead of returning None.

val make_relative_to_cwd_if_possible : File_path.t -> File_path.t Core.Monad.Ident.t

Like make_relative_to_cwd. Returns the original path instead of None.

Temporary Files and Directories

val default_temp_dir : File_path.t Core.Lazy.t

The system-determined default temporary directory.

Has the same value as Core.Filename.temp_dir_name. OCaml semantics do not guarantee an absolute path here.

val within_temp_dir : ?in_dir:File_path.t -> ?on_cleanup_error:unit Core.Monad.Ident.t Filesystem_types.On_cleanup_error.t -> ?perm:Filesystem_types.File_permissions.t -> ?prefix:string -> ?suffix:string -> (unit -> 'a Core.Monad.Ident.t) -> 'a Core.Monad.Ident.t

Creates a new directory with a unique name, chdirs to it, runs the given function, chdirs back, and then recursively deletes the temporary directory and its contents.

If the directory is renamed or removed before the function ends, there is a race condition. Some other function or process may create a temporary directory or file by the same name, and this function may attempt to delete that.

val with_temp_dir : ?in_dir:File_path.t -> ?on_cleanup_error:unit Core.Monad.Ident.t Filesystem_types.On_cleanup_error.t -> ?perm:Filesystem_types.File_permissions.t -> ?prefix:string -> ?suffix:string -> (File_path.Absolute.t -> 'a Core.Monad.Ident.t) -> 'a Core.Monad.Ident.t

Creates a new directory with a unique name, runs the given function with the directory's path, and then recursively deletes the temporary directory and its contents.

Has the same race condition as within_temp_dir if the path is renamed or removed before the function finishes.

val with_temp_file : ?in_dir:File_path.t -> ?on_cleanup_error:unit Core.Monad.Ident.t Filesystem_types.On_cleanup_error.t -> ?perm:Filesystem_types.File_permissions.t -> ?prefix:string -> ?suffix:string -> (File_path.Absolute.t -> 'a Core.Monad.Ident.t) -> 'a Core.Monad.Ident.t

Creates a new file with a unique name, runs the given function with the file's path, and then deletes the temporary file.

Has the same race condition as within_temp_dir if the path is renamed or removed before the function finishes. Overwriting the file atomically by renaming something else to it should not have the same race condition.

val create_temp_dir : ?in_dir:File_path.t -> ?perm:Filesystem_types.File_permissions.t -> ?prefix:string -> ?suffix:string -> unit -> File_path.Absolute.t Core.Monad.Ident.t

Creates a new directory with a unique name.

val create_temp_file : ?in_dir:File_path.t -> ?perm:Filesystem_types.File_permissions.t -> ?prefix:string -> ?suffix:string -> unit -> File_path.Absolute.t Core.Monad.Ident.t

Creates a new, empty file with a unique name.

Advisory File Locks

The flock system call supports mutual exclusion. When an exclusive lock on a file is held, other attempts to lock it fail or block. When a shared lock on a file is held, other attempts at shared locks succeed and attempts at exclusive locks fail or block.

No other access is controlled by these locks. For locks to affect access such as reading and writing, processes must cooperate with a locking protocol.

As of Linux 2.6.12, flock-based locks do function over NFS.

module Fd : Core.T with type t = Core_unix.File_descr.t
module Flock : Core.T
val flock : ?shared:bool -> File_path.t -> Flock.t Core.Monad.Ident.t

Locks the given file via the flock system call, returning when the lock has been acquired. If the file does not exist, this call raises.

If the file cannot be locked immediately due to an existing lock, this call waits until the file can be locked. If this lock and existing locks are shared, the file can be locked immediately.

If the same process calls flock twice on the same file you will end up with two competing locks. You have been warned!

val flock_of_fd : ?shared:bool -> Fd.t -> Flock.t Core.Monad.Ident.t

Like flock above. Uses an already-open file descriptor for locking.

val flock_create : ?perm:Filesystem_types.File_permissions.t -> ?shared:bool -> File_path.t -> Flock.t Core.Monad.Ident.t

Like flock above. If the file does not exist, creates it with the given permissions before locking.

val try_flock : ?shared:bool -> File_path.t -> Flock.t option Core.Monad.Ident.t

Like flock above. If the file cannot be locked immediately due to an existing lock, this call returns None instead of waiting.

val try_flock_of_fd : ?shared:bool -> Fd.t -> Flock.t option Core.Monad.Ident.t

Like try_flock above. Uses an already-open file descriptor for locking.

val try_flock_create : ?perm:Filesystem_types.File_permissions.t -> ?shared:bool -> File_path.t -> Flock.t option Core.Monad.Ident.t

Like try_flock above. If the file does not exist, creates it with the given permissions before locking.

val funlock : Flock.t -> unit Core.Monad.Ident.t

Releases the given lock. These locks are automatically released on exit or exec, so this only needs to be used if the lock needs to be released during the execution of the program. Does not close any file descriptors passed to *_of_fd creators.

val flock_fd : Flock.t -> Fd.t

Produces the file descriptor underlying a lock.

val with_flock : ?shared:bool -> File_path.t -> f:(Flock.t -> 'a Core.Monad.Ident.t) -> 'a Core.Monad.Ident.t

Acquires a lock for the duration of f. Calls flock before f, and funlock after f returns or raises.

val with_flock_of_fd : ?shared:bool -> Fd.t -> f:(Flock.t -> 'a Core.Monad.Ident.t) -> 'a Core.Monad.Ident.t

Like with_flock. Uses an already-open file descriptor for locking.

val with_flock_create : ?perm:Filesystem_types.File_permissions.t -> ?shared:bool -> File_path.t -> f:(Flock.t -> 'a Core.Monad.Ident.t) -> 'a Core.Monad.Ident.t

Like with_flock above. Calls flock_create instead of flock.