diff options
author | Laurent Bercot <ska-skaware@skarnet.org> | 2014-09-18 18:55:44 +0000 |
---|---|---|
committer | Laurent Bercot <ska-skaware@skarnet.org> | 2014-09-18 18:55:44 +0000 |
commit | 3534b428629be185e096be99e3bd5fdfe32d5544 (patch) | |
tree | 210ef3198ed66bc7f7b7bf6a85e4579f455e5a36 /doc/libstddjb/djbunix.html | |
download | skalibs-3534b428629be185e096be99e3bd5fdfe32d5544.tar.xz |
initial commit with rc for skalibs-2.0.0.0
Diffstat (limited to 'doc/libstddjb/djbunix.html')
-rw-r--r-- | doc/libstddjb/djbunix.html | 760 |
1 files changed, 760 insertions, 0 deletions
diff --git a/doc/libstddjb/djbunix.html b/doc/libstddjb/djbunix.html new file mode 100644 index 0000000..0d6c89f --- /dev/null +++ b/doc/libstddjb/djbunix.html @@ -0,0 +1,760 @@ +<html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Language" content="en" /> + <title>skalibs: the djbunix library interface</title> + <meta name="Description" content="skalibs: the djbunix library interface" /> + <meta name="Keywords" content="skalibs c unix djbunix library libstddjb" /> + <!-- <link rel="stylesheet" type="text/css" href="http://www.skarnet.org/default.css" /> --> + </head> +<body> + +<p> +<a href="index.html">libstddjb</a><br /> +<a href="../libskarnet.html">libskarnet</a><br /> +<a href="../index.html">skalibs</a><br /> +<a href="http://skarnet.org/software/">Software</a><br /> +<a href="http://skarnet.org/">skarnet.org</a> +</p> + +<h1> The <tt>djbunix</tt> library interface </h1> + +<p> + The following functions are declared in the <tt>skalibs/djbunix.h</tt> header, +and implemented in the <tt>libskarnet.a</tt> or <tt>libskarnet.so</tt> library. +</p> + +<h2> General information </h2> + +<p> + <tt>djbunix</tt> is an alternative API to management of basic Unix +concepts: file descriptors, files, environment, and so on. It is a +rather chaotic mix of <a href="safewrappers.html">safe wrappers</a> +around Unix system calls, better reimplementations of standard libc +functionalities, and higher-level manipulations of Unix concepts. +</p> + +<p> + Understanding <tt>djbunix</tt> is essential to understanding any piece +of code depending on skalibs. +</p> + +<h2> Functions </h2> + +<h3> Basic fd operations </h3> + +<p> +<code> int coe (int fd) </code> <br /> +Sets the close-on-exec flag on <em>fd</em>. +Returns 0 if it succeeds, or -1 (and sets errno) if it fails. +</p> + +<p> +<code> int uncoe (int fd) </code> <br /> +Clears the close-on-exec flag on <em>fd</em>. +Returns 0 if it succeeds, or -1 (and sets errno) if it fails. +</p> + +<p> +<code> int ndelay_on (int fd) </code> <br /> +Sets the O_NONBLOCK flag on <em>fd</em>: sets it to non-blocking mode. +Returns 0 if it succeeds, or -1 (and sets errno) if it fails. +</p> + +<p> +<code> int ndelay_off (int fd) </code> <br /> +Clears the O_NONBLOCK flag on <em>fd</em>: sets it to blocking mode. +Returns 0 if it succeeds, or -1 (and sets errno) if it fails. +</p> + +<p> +<code> int pipenb (int *p) </code> <br /> +Like +<a href="http://www.opengroup.org/onlinepubs/9699919799/functions/pipe.html">pipe()</a>, +but both ends of the created pipe are in non-blocking mode. +</p> + +<p> +<code> int pipecoe (int *p) </code> <br /> +Like +<a href="http://www.opengroup.org/onlinepubs/9699919799/functions/pipe.html">pipe()</a>, +but both ends of the created pipe are close-on-exec. +</p> + +<p> +<code> int pipenbcoe (int *p) </code> <br /> +Like +<a href="http://www.opengroup.org/onlinepubs/9699919799/functions/pipe.html">pipe()</a>, +but both ends of the created pipe are in non-blocking mode <em>and</em> close-on-exec. +</p> + +<p> +<code> int fd_copy (int to, int from) </code> <br /> +Copies the open fd <em>from</em> to number <em>to</em>. <em>to</em> +must not refer to an already open fd. +Returns 0 if it succeeds, or -1 (and sets errno) if it fails. +</p> + +<p> +<code> int fd_copy2 (int to1, int from1, int to2, int from2) </code> <br /> +Copies the open fd <em>from1</em> to number <em>to2</em>. Also copies +<em>from2</em> to <em>to2</em> at the same time. +Returns 0 if it succeeds, or -1 (and sets errno) if it fails. +</p> + +<p> +<code> int fd_move (int to, int from) </code> <br /> +Moves the open fd <em>from</em> to number <em>to</em>. <em>to</em> +must not refer to an already open fd, unless it's equal to <em>from</em>. +Returns 0 if it succeeds, or -1 (and sets errno) if it fails. +</p> + +<p> +<code> int fd_move2 (int to1, int from1, int to2, int from2) </code> <br /> +Moves the open fd <em>from</em> to number <em>to</em>. Also moves +<em>from2</em> to <em>to2</em> at the same time. This is useful for instance +when you want to swap two fds: <tt>fd_move2</tt> will handle the situation +correctly. +Returns 0 if it succeeds, or -1 (and sets errno) if it fails. +</p> + +<p> +<code> int fd_close (int fd) </code> <br /> +Closes <em>fd</em>. +Returns 0 if it succeeds, or -1 (and sets errno) if it fails. +This is a <a href="safewrappers.html">safe wrapper</a> around +<a href="http://www.opengroup.org/onlinepubs/9699919799/functions/close.html">close()</a>, +or rather as safe a wrapper as is possible to write: the <tt>close()</tt> +specification does not allow a 100% safe behaviour. So, in rare cases +it is possible for <tt>fd_close()</tt> to return 0 (instead of -1 EBADF) +when it is provided an argument that is not an open fd. This should not +be a problem, because giving wrong arguments to <tt>fd_close()</tt> is +always a static programming error. +</p> + +<p> +<code> int fd_chmod (int fd, unsigned int mode) </code> <br /> +Safe wrapper around +<a href="http://www.opengroup.org/onlinepubs/9699919799/functions/fchmod.html">fchmod()</a>. +</p> + +<p> +<code> int fd_chown (int fd, unsigned int uid, unsigned int gid) </code> <br /> +Safe wrapper around +<a href="http://www.opengroup.org/onlinepubs/9699919799/functions/fchown.html">fchown()</a>. +This function requires root privileges. +</p> + +<p> +<code> int fd_sync (int fd) </code> <br /> +Safe wrapper around +<a href="http://www.opengroup.org/onlinepubs/9699919799/functions/fsync.html">fsync()</a>. +</p> + +<p> +<code> int fd_chdir (int fd) </code> <br /> +Safe wrapper around +<a href="http://www.opengroup.org/onlinepubs/9699919799/functions/fchdir.html">fchdir()</a>. +</p> + +<p> +<code> int fd_cat (int from, int to) </code> <br /> +Synchronously copies data from fd <em>from</em> to fd <em>to</em>, +until it encounters EOF or an error. Returns -1 (and sets errno) if +it fails; returns the number of transmitted bytes if it gets an EOF. +</p> + +<p> +When the underlying OS allows it, zero-copy transmission is +performed. Currently, the following zero-copy implementations are +supported: +</p> + +<ul> + <li> <a href="http://www.kernel.org/doc/man-pages/online/pages/man2/splice.2.html">splice()</a>, +in Linux 2.6.17 and later </li> +</ul> + +<p> +<code> unsigned int fd_catn (int from, int to, unsigned int n) </code> <br /> +Synchronously copies at most <em>n</em> bytes from fd <em>from</em> to fd <em>to</em>. +Returns the total number of transmitted bytes; sets errno if this number +is lesser than <em>n</em>. EOF is reported as EPIPE. See above for zero-copy +transmission; zero-copy transmission is not attempted for less than 64k of data. +</p> + +<p> +<code> int fd_ensure_open (int fd, int w) </code> <br /> +If <em>fd</em> is not open, opens it to <tt>/dev/null</tt>, +for reading if <em>w</em> is zero, and for writing otherwise. +Returns 1 if it succeeds and 0 if it fails. +</p> + +<p> +<code> int fd_sanitize (void) </code> <br /> +Ensures stdin and stdout are open. If one of those +file descriptors was closed, it now points to <tt>/dev/null</tt>. +Returns 1 if it succeeds and 0 if it fails. +</p> + +<p> +<code> int lock_ex (int fd) </code> <br /> +Gets an exclusive advisory lock on <em>fd</em>. <em>fd</em> must point to +a regular file, open for writing. Blocks until the lock can be obtained. +Returns 0 if it succeeds, or -1 (and sets errno) if it fails. +</p> + +<p> +<code> int lock_exnb (int fd) </code> <br /> +Gets an exclusive advisory lock on <em>fd</em>. <em>fd</em> must point to +a regular file, open for writing. +Returns 0 if it succeeds, or -1 (and sets errno) if it fails. If the lock +is held and the function would block, it immediately returns with -1 EWOULDBLOCK. +</p> + +<p> +<code> int lock_sh (int fd) </code> <br /> +Gets a shared advisory lock on <em>fd</em>. <em>fd</em> must point to +a regular file, open for reading. Blocks until the lock can be obtained. +Returns 0 if it succeeds, or -1 (and sets errno) if it fails. +</p> + +<p> +<code> int lock_shnb (int fd) </code> <br /> +Gets a shared advisory lock on <em>fd</em>. <em>fd</em> must point to +a regular file, open for reading. +Returns 0 if it succeeds, or -1 (and sets errno) if it fails. If the lock +is held and the function would block, it immediately returns with -1 EWOULDBLOCK. +</p> + +<p> +<code> int lock_un (int fd) </code> <br /> +Releases a previously held lock on <em>fd</em>. +Returns 0 if it succeeds, or -1 (and sets errno) if it fails. +</p> + +<p> +<code> int open2 (char const *file, unsigned int flags) </code> <br /> +Safe wrapper around +<a href="http://www.opengroup.org/onlinepubs/9699919799/functions/open.html">open()</a> +when it takes 2 arguments. +</p> + +<p> +<code> int open3 (char const *file, unsigned int flags) </code> <br /> +Safe wrapper around +<a href="http://www.opengroup.org/onlinepubs/9699919799/functions/open.html">open()</a> +when it takes 3 arguments. +</p> + +<p> +<code> int open_read (char const *file) </code> <br /> +Opens <em>file</em> in read-only, non-blocking mode. +Returns a valid fd number if it succeeds, or -1 (and sets errno) if it fails. +</p> + +<p> +<code> int open_readb (char const *file) </code> <br /> +Opens <em>file</em> in read-only, blocking mode. +Returns a valid fd number if it succeeds, or -1 (and sets errno) if it fails. +<em>This call does not block.</em> The +<a href="http://www.opengroup.org/onlinepubs/9699919799/functions/open.html">open()</a> +system call is actually performed with the O_NONBLOCK option, and blocking mode +is set afterwards; this behaviour allows for more transparent interactions +with FIFOs. +</p> + +<p> +<code> int open_excl (char const *file) </code> <br /> +Opens <em>file</em> in write-only, non-blocking mode, with the +additional O_EXCL and O_CREAT flags. +Returns a valid fd number if it succeeds, or -1 (and sets errno) if it fails. +</p> + +<p> +<code> int open_append (char const *file) </code> <br /> +Opens <em>file</em> in write-only, non-blocking mode, with the +additional O_APPEND and O_CREAT flags. +Returns a valid fd number if it succeeds, or -1 (and sets errno) if it fails. +</p> + +<p> +<code> int open_trunc (char const *file) </code> <br /> +Opens <em>file</em> in write-only, non-blocking mode, with the +additional O_TRUNC and O_CREAT flags. +Returns a valid fd number if it succeeds, or -1 (and sets errno) if it fails. +</p> + +<p> +<code> int open_create (char const *file) </code> <br /> +Opens <em>file</em> in write-only, non-blocking mode, with the +additional O_CREAT flag. +Returns a valid fd number if it succeeds, or -1 (and sets errno) if it fails. +</p> + +<p> +<code> int open_write (char const *file) </code> <br /> +Opens <em>file</em> in write-only, non-blocking mode. +Returns a valid fd number if it succeeds, or -1 (and sets errno) if it fails. +</p> + +<h3> Seek operations </h3> + +<p> +<code> long seek_cur (int fd) </code> <br /> +Returns the current file offset for descriptor <em>fd</em>. +</p> + +<p> +<code> int seek_set (int fd, long pos) </code> <br /> +Sets the current file offset for <em>fd</em> to <em>pos</em>. +Returns 0 if it succeeds, or -1 (and sets errno) if it fails. +</p> + +<h3> Privilege management </h3> + +<p> +<code> int prot_readgroups (char const *name, gid_t *tab, unsigned int max) </code> <br /> +Reads the group database (normally <tt>/etc/group</tt>, but it can be +altered via NSS) to get the list of supplementary groups for user <em>name</em>. +Stores that list into the array pointed to by <em>tab</em>, which must be +preallocated. Stores at most <em>max</em> elements into <em>tab</em>. +Returns -1 and sets errno if it fails; else, returns the number of elements actually +stored into <em>tab</em>. +</p> + +<p> +<code> int prot_grps (char const *name) </code> <br /> +Sets the kernel-maintained list of supplementary groups for the current process +to the list of supplementary groups for user <em>name</em> according to the +group database. This is a privileged operation. +Returns -1 and sets errno if it fails; returns 0 if it succeeds. +</p> + +<p> +<code> int prot_gid (int gid) </code> <br /> +Alias to <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/setgid.html">setgid</a>. +</p> + +<p> +<code> int prot_uid (int uid) </code> <br /> +Alias to <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/setuid.html">setuid</a>. +</p> + +<h3> Executable search and execution, and environment </h3> + +<p> +<code> void execvep (char const *file, char const *const *argv, char const *const *envp, char const *path) </code> <br /> +Executes into the executable file at <em>file</em>, with the command line +set to <em>argv</em> and the environment set to <em>envp</em>. +If <em>file</em> is not an absolute path, it is searched in the +<em>path</em> string, which must contain a colon-separated list of +search directories such as the contents of the PATH environment variable. +The function returns if it fails, and sets errno to the most relevant +error that happened. +</p> + +<p> +<code> void pathexec_run (char const *file, char const *const *argv, char const *const *envp) </code> <br /> +Performs <tt>execvep(file, argv, envp, path)</tt>, <em>path</em> being the +contents of the PATH environment variable. If PATH is not set, <em>path</em> +is set to the contents of the <tt>conf-compile/conf-defaultpath</tt> file in +the skalibs distribution. +The function returns if it fails, and sets errno appropriately. +</p> + +<p> + <tt>pathexec_run()</tt> is the standard skalibs API to perform an +<tt>exec</tt> call with a path search. It is recommended that you use +it instead of the Single Unix +<a href="http://www.opengroup.org/onlinepubs/9699919799/functions/execvp.html">execvp()</a> or +<a href="http://www.opengroup.org/onlinepubs/9699919799/functions/execlp.html">execlp()</a> +functions, because <tt>execvp</tt> and <tt>execlp</tt> default to execution of +the <tt>/bin/sh</tt> interpreter with <em>file</em> as an argument if they +cannot find a suitable executable <em>file</em>, and this is: +</p> + +<ol> + <li> a security risk, </li> + <li> probably not what you want. </li> +</ol> + +<p> + <tt>execvep()</tt> and <tt>pathexec_run()</tt> just fail with ENOENT +when they cannot find a <em>file</em> to exec into, which is the +sensible behaviour. +</p> + +<p> +<code> void pathexec0_run (char const *const *argv, char const *const *envp) </code> <br /> +Performs <tt>pathexec_run(argv[0], argv, envp)</tt>. If <em>argv</em> is empty, i.e. +<em>argv</em>[0] is null, the process exits 0 instead. Rationale: executing +the empty command line should amount to executing <tt>true</tt>, i.e. +simply exiting 0. +</p> + +<p> +<code> void pathexec_r_name (char const *file, char const *const *argv, char const *const *envp, unsigned int envlen, char const *modifs, unsigned int modiflen) </code> <br /> +Alters <em>envp</em> (which does not have to be NULL-terminated, but the +number <em>envlen</em> of elements must be provided) with the modifier +string <em>modifs</em> of length <em>modiflen</em>, then performs +<tt>pathexec_run(file, argv, altered-envp)</tt>. +</p> + +<p> +<code> void pathexec_r (char const *const *argv, char const *const *envp, unsigned int envlen, char const *modifs, unsigned int modiflen) </code> <br /> +Same as <tt>pathexec_r_name</tt>, except that the <em>file</em> argument is read from <em>argv</em>[0]. +</p> + +<p> +<code> int pathexec_env (char const *var, char const *value) </code> <br /> +Adds the "add variable <em>var</em> with value <em>value</em>" instruction +(if <em>value</em> is not null) or the "unset <em>var</em>" instruction +(if <em>value</em> is null) to a static hidden modifier string, used by the +following three functions. +Returns 1 if it succeeds and 0 (and sets errno) if it fails. +</p> + +<p> +<code> void pathexec_fromenv (char const *const *argv, char const *const *envp, unsigned int envlen) </code> <br /> +Performs <tt>pathexec_r()</tt> with the given arguments and the hidden modifier +string. +</p> + +<p> +<code> void pathexec (char const *const *argv) </code> <br /> +Executes into the <em>argv</em> command line, with the current environment +modified by the hidden modifier string. +</p> + +<p> +<code> void pathexec0 (char const *const *argv) </code> <br /> +Executes into the <em>argv</em> command line, with the current environment +modified by the hidden modifier string. If this command line is empty, +exit 0 instead. +</p> + +<p> + The <a href="env.html">env</a> library interface provides additional functions +to manipulate modifier strings and environments. +</p> + +<h3> Forking children </h3> + +<p> +<code> int doublefork () </code> <br /> +Performs a double fork. Returns -1 if it fails (and +sets errno, EINTR meaning that the intermediate process +was killed by a signal), 0 if the current process is the grandchild, +and the grandchild's PID if the current process is the parent. +</p> + +<p> +<code> pid_t child_spawn0 (char const *file, char const *const *argv, char const *const *envp) </code> <br /> +Forks and executes a child as with <tt>pathexec_run(file, argv, envp)</tt>. +Returns 0 if it fails, and the pid of the child if it succeeds. +Implemented via <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_spawn.html">posix_spawn()</a> +on systems that support it. +</p> + +<p> +<code> pid_t child_spawn1 (char const *file, char const *const *argv, char const *const *envp, int *fd, int w) </code> <br /> +Like <tt>child_spawn0()</tt>, except that a pipe is created between the child's +stdin (if <em>w</em> is 0) or stdout (if <em>w</em> is nonzero) and the parent. +The parent's end of the pipe will be stored in *<em>fd</em>. +</p> + +<p> +<code> pid_t child_spawn (char const *file, char const *const *argv, char const *const *envp, int *fds, unsigned int nfds) </code> <br /> +More generic spawning function. <em>fds</em> must point to an array of at least <em>nfds</em> ints; +file descriptors reading from or writing to the child will be stored there. The function returns +0 on failure or the pid of the child on success. +</p> +<ul> + <li> If <em>nfds</em> is 0, then the function behaves like <tt>child_spawn0</tt>, except +all signals will be reset to the default behaviour in the child </li> + <li> If <em>nfds</em> is 1, then <em>fds</em>[0] will contain a Unix domain socket +connected to the child's stdin and stdout. </li> + <li> If <em>nfds</em> is 2 or more, then <em>fds</em> will contain pipes between the +child and the parent. The parent will read on even-numbered ones (starting on <em>fds</em>[0]) +and write on odd-numbered ones. </li> +</ul> + +<h3> Waiting for children </h3> + +<p> +<code> unsigned int wait_reap () </code> <br /> +Instantly reaps all the pending zombies, without blocking, without a look at +the exit codes. +Returns the number of reaped zombies. +</p> + +<p> +<code> int waitn (pid_t *pids, unsigned int n) </code> <br /> +Waits until all processes whose PIDs are stored in the +<em>pids</em> array, of size <em>n</em>, have died. +Returns 1 if it succeeds, and 0 (and sets errno) if it fails. The +<em>pid</em> array is not guaranteed to be unchanged. +</p> + +<p> +<code> int waitn_reap (pid_t *pids, unsigned int n) </code> <br /> +Instantly reaps all zombies whose PIDs are stored in the +<em>pids</em> array, of size <em>n</em>. +Returns -1 (and sets errno) if it fails, and the number of reaped +zombies if it succeeds. The <em>pid</em> array is not guaranteed to +be unchanged. +</p> + +<p> +<code> int wait_nohang (int *wstat) </code> <br /> +Instantly reaps one zombie, and stores the status information into +*<em>wstat</em>. +Returns the PID of the reaped zombie if it succeeds, 0 if there was +nothing to reap (and the current process still has children), -1 ECHILD +if there was nothing to reap (and the current process has no children), +or -1 (and sets errno) if it fails. +</p> + +<p> +<code> int waitpid_nointr (pid_t pid, int *wstat, int flags) </code> <br /> +Safe wrapper around +<a href="http://www.opengroup.org/onlinepubs/9699919799/functions/waitpid.html">waitpid()</a>. +</p> + +<p> +<code> int wait_pid_nohang (pid_t pid, int *wstat) </code> <br /> +Instantly reaps an undetermined number of zombies until it finds <em>pid</em>. +Stores the status information for dead <em>pid</em> into *<em>wstat</em>. +Returns <em>pid</em> if it succeeds, 0 if there was +nothing to reap (and the current process still has children), -1 ECHILD +if there was nothing to reap (and the current process has no children), +or -1 (and sets errno) if it fails. +</p> + +<p> +<code> int wait_pids_nohang (pid_t const *pids, unsigned int len, int *wstat) </code> <br /> +Instantly reaps an undetermined number of zombies until it finds one whose +PID is in the <em>pids</em> array, of size <em>len</em>. +Stores the status information for that dead process into *<em>wstat</em>. +Returns the index of the found PID in <em>pids</em>, starting at 1. +Returns 0 if there was +nothing to reap (and the current process still has children), -1 ECHILD +if there was nothing to reap (and the current process has no children), +or -1 (and sets errno) if it fails. +</p> + +<p> + When asynchronously dealing with a child (resp. several children) and +getting a SIGCHLD - which should be handled via a +<a href="selfpipe.html">selfpipe</a> - it is generally a good idea to +use the <tt>wait_pid_nohang()</tt> (resp. <tt>wait_pids_nohang()</tt>) +function over the basic Unix APIs. This allows a program to: +</p> + +<ul> + <li> Automatically and silently take care of children it does not know +it has. This situation can happen when a process forks and the parent +execs. When the child dies, the new parent process has to drag the +"zombie bastard" along, which is ugly; <tt>wait_pids_nohang()</tt> +prevents this. </li> + <li> Still take appropriate care of its legitimate children, in +any order. </li> +</ul> + +<h3> Reading and writing whole files </h3> + +<p> +<code> int slurp (stralloc *sa, int fd) </code> <br /> +Slurps the contents of open descriptor <em>fd</em> into +the *<em>sa</em> <a href="stralloc.html">stralloc</a>. If you are +doing this, you should either have full control over the slurped +file, or run your process with suitable +<a href="http://www.skarnet.org/software/s6/s6-softlimit.html">limits</a> +to the amount of heap memory it can get. +The function returns 1 if it succeeds, or 0 (and sets errno) if it fails. +</p> + +<p> +<code> int openslurpclose (stralloc *sa, char const *file) </code> <br /> +Slurps the contents of file <em>file</em> into *<em>sa</em>. +Returns 1 if it succeeds, and 0 (and sets errno) if it fails. +</p> + +<p> +<code> int openreadclose (char const *file, stralloc *sa, unsigned int dummy) </code> <br /> +Legacy interface for <code>openslurpclose(sa, file)</code>. The <em>dummy</em> +argument is unused. Returns 0 if it succeeds, and -1 (and sets errno) if it fails. +</p> + +<p> +<code> int openreadnclose (char const *file, char *s, unsigned int n) </code> <br /> +Reads at most <em>n</em> bytes from file <em>file</em> into preallocated +buffer <em>s</em>. Returns -1 (and sets errno) if it fails; else returns the +number of read bytes. If that number is not <em>n</em>, errno is set to EPIPE. +</p> + +<p> +<code> int openreadfileclose (char const *file, stralloc *sa, unsigned int n) </code> <br /> +Reads at most <em>n</em> bytes from file <em>file</em> into the *<em>sa</em> +stralloc, which is grown (if needed) to <em>just</em> accommodate the file +size. Returns 1 if it succeeds and 0 (and sets errno) if it fails. +</p> + +<p> +<code> int openwritenclose_unsafe_internal (char const *file, char const *s, unsigned int len, uint64 *dev, uint64 *ino, unsigned char dosync) </code> <br /> +Writes the <em>n</em> bytes stored at <em>s</em> into file <em>file</em>. +The previous contents of <em>file</em> are destroyed even if the function +fails. If <em>dosync</em> is nonzero, the new contents of <em>file</em> +are synced to disk before the function returns. If <em>dev</em> and <em>ino</em> +are not null, they're used to store the device and inode number of <em>file</em>. +The function returns 1 if it succeeds, or 0 (and sets errno) if it fails. +</p> + +<p> +<code> int openwritenclose_unsafe (char const *file, char const *s, unsigned int len) <br /> +int openwritenclose_unsafe_sync (char const *file, char const *s, unsigned int len) <br /> +int openwritenclose_unsafe_devino (char const *file, char const *s, unsigned int len, uint64 *dev, uint64 *ino) <br /> +int openwritenclose_unsafe_devino_sync (char const *file, char const *s, unsigned int len, uint64 *dev, uint64 *ino) </code> <br /> +Trivial shortcuts around <tt>openwritenclose_unsafe_internal()</tt>. The +reader can easily figure out what they do. +</p> + +<p> +<code> int openwritenclose_suffix_internal (char const *file, char const *s, unsigned int len, uint64 *dev, uint64 *ino, unsigned char dosync, char const *suffix) </code> <br /> +Writes the <em>n</em> bytes stored at <em>s</em> into file <em>file</em>, +by first writing into <em>filesuffix</em> and atomically renaming +<em>filesuffix</em> to <em>file</em>. IOW, the old contents of <em>file</em> +are preserved if the operation fails, and are atomically replaced with the +new contents if the operation succeeds. +If <em>dosync</em> is nonzero, the new contents of <em>filesuffix</em> +are synced to disk before the atomic replace. If <em>dev</em> and <em>ino</em> +are not null, they're used to store the device and inode number of <em>file</em>. +The function returns 1 if it succeeds, or 0 (and sets errno) if it fails. +</p> + +<p> +<code> int openwritenclose_suffix (char const *file, char const *s, unsigned int len, char const *suffix) <br /> +int openwritenclose_suffix_sync (char const *file, char const *s, unsigned int len, char const *suffix) <br /> +int openwritenclose_suffix_devino (char const *file, char const *s, unsigned int len, uint64 *dev, uint64 *ino, char const *suffix) <br /> +int openwritenclose_suffix_devino_sync (char const *file, char const *s, unsigned int len, uint64 *dev, uint64 *ino, char const *suffix) </code> <br /> +Trivial shortcuts around <tt>openwritenclose_suffix_internal()</tt>. The +reader can easily figure out what they do. +</p> + +<h3> Filesystem deletion </h3> + +<p> +The following operations are not atomic, so if they fail, the +relevant subtree might end up partially deleted. +</p> + +<p> +<code> int rm_rf (char const *path) </code> <br /> +Deletes the filesystem subtree at <em>path</em>. +Returns 0 if it succeeds or -1 (and sets errno) if it fails. +</p> + +<p> +<code> int rm_rf_tmp (char const *path, stralloc *tmp) </code> <br /> +Deletes the filesystem subtree at <em>path</em>, using *<em>tmp</em> +as heap-allocated temporary space. +Returns 0 if it succeeds or -1 (and sets errno) if it fails. +</p> + +<p> +<code> int rm_rf_in_tmp (stralloc *tmp, unsigned int n) </code> <br /> +Deletes a filesystem subtree, using *<em>tmp</em> +as heap-allocated temporary space. +Returns 0 if it succeeds or -1 (and sets errno) if it fails. +When the function is called, *<em>tmp</em> must contain the +null-terminated name of the subtree to delete at offset <em>n</em>. +</p> + +<p> +<code> int rmstar (char const *dir) </code> <br /> +Deletes all the filesystem subtrees in directory <em>dir</em>. +Returns 0 if it succeeds or -1 (and sets errno) if it fails. +</p> + +<p> +<code> int rmstar_tmp (char const *dir, stralloc *tmp) </code> <br /> +Deletes all the filesystem subtrees in directory <em>dir</em>, +using *<em>tmp</em> as heap-allocated temporary space. +Returns 0 if it succeeds or -1 (and sets errno) if it fails. +</p> + +<h3> Variable length wrappers around Single Unix calls </h3> + +<p> +<code> int sarealpath (stralloc *sa, char const *path) </code> <br /> +Resolves <em>path</em> into a symlink-free absolute path, appending +the result to the *<em>sa</em> +<a href="stralloc.html">stralloc</a>. +Returns 0 if it succeeds and -1 (and sets errno) if it fails. +</p> + +<p> +<code> int sarealpath_tmp (stralloc *sa, char const *path, stralloc *tmp) </code> <br /> +Resolves <em>path</em> into a symlink-free absolute path, appending +the result to *<em>sa</em>. Uses *<em>tmp</em> as heap-allocated +temporary space. +Returns 0 if it succeeds and -1 (and sets errno) if it fails. +</p> + +<p> +<code> int sabasename (stralloc *sa, char const *s, unsigned int len) </code> <br /> +Appends the basename of filename <em>s</em> (of length <em>len</em>) +to *<em>sa</em>. +Returns 1 if it succeeds and 0 (and sets errno) if it fails. +</p> + +<p> +<code> int sadirname (stralloc *sa, char const *s, unsigned int len) </code> <br /> +Appends the dirname of filename <em>s</em> (of length <em>len</em>) +to *<em>sa</em>. +Returns 1 if it succeeds and 0 (and sets errno) if it fails. +</p> + +<p> +<code> int sagetcwd (stralloc *sa) </code> <br /> +Appends the current working directory to *<em>sa</em>. +Returns 0 if it succeeds and -1 (and sets errno) if it fails. +</p> + +<p> +<code> int sareadlink (stralloc *sa, char const *link) </code> <br /> +Appends the contents of symbolic link <em>link</em> to *<em>sa</em>. +Returns 0 if it succeeds and -1 (and sets errno) if it fails. +</p> + +<p> +<code> int sagethostname (stralloc *sa) </code> <br /> +Appends the machine's hostname to *<em>sa</em>. +Returns 0 if it succeeds and -1 (and sets errno) if it fails. +</p> + +<h3> Temporization </h3> + +<p> +<code> void deepsleepuntil (tain_t const *deadline, tain_t *stamp) </code> <br /> +Sleeps until the absolute time represented by the +<a href="tai.html">tain_t</a> *<em>deadline</em>. *<em>stamp</em> +must contain the current time. When the function returns, *<em>stamp</em> +has been updated to reflect the new current time. +</p> + +<p> +<code> void deepsleep (unsigned int n) </code> <br /> +Sleeps <em>n</em> seconds. Signals received during that time are handled, +but <em>do not</em> interrupt the sleep. +</p> + +<p> +<code> void deepmillisleep (unsigned long n) </code> <br /> +Sleeps <em>n</em> milliseconds. Signals received during that time are handled, +but <em>do not</em> interrupt the sleep. +</p> + +</body> +</html> |