self-exe#
The absolute path of the currently running executable, cross-platform.
There is no portable way to ask "where is my own binary?": each operating
system needs its own mechanism, and one (OpenBSD) cannot answer it reliably at
all. self-exe wraps them behind a single call, canonicalised to an absolute,
symlink-resolved path. It is the OCaml counterpart of Rust's
std::env::current_exe, Go's os.Executable, and the C single-header
whereami.
Sys.executable_name does not cover this: it is derived from argv[0] and is
unreliable on macOS and under unusual invocation. Reach for self-exe when a
program re-execs itself (on-demand daemons, privilege-separated workers), needs
to find its install directory (sibling binaries, bundled data), or must be
relocatable.
Installation#
$ opam install self-exe
If opam cannot find the package, it may not yet be released in the public
opam-repository. Add the overlay repository, then install it:
$ opam repo add samoht https://tangled.org/gazagnaire.org/opam-overlay.git
$ opam update
$ opam install self-exe
Usage#
(* Re-exec ourselves, or locate a sibling tool installed next to us. *)
let me = Self_exe.path ()
let helper = Filename.concat (Self_exe.dir ()) "worker"
(* [path_opt] tells a guess from an authoritative answer. *)
let trustworthy = Self_exe.path_opt () <> None
path always returns a string -- best-effort, which is what re-exec callers
want. path_opt is the strict variant: it is Some p only when the OS reported
the path authoritatively, and None when only the argv[0] fallback was
available.
Platform support#
| Platform | Mechanism | Authoritative |
|---|---|---|
| Linux | readlink("/proc/self/exe") |
yes |
| macOS | _NSGetExecutablePath, then realpath |
yes |
| FreeBSD / NetBSD / DragonFly | sysctl KERN_PROC_PATHNAME |
yes |
| OpenBSD | argv[0] + $PATH/cwd resolution |
no (fallback) |
| any, on failure | argv[0] resolution |
no (fallback) |
The fallback resolves Sys.argv.(0) the way the launching shell would: a path
is taken relative to the current directory, a bare name is searched along
$PATH. It can be wrong if the cwd or $PATH changed since launch, or if the
binary was moved -- use path_opt when you must know the answer is reliable.
License#
ISC. See LICENSE.