From 3534b428629be185e096be99e3bd5fdfe32d5544 Mon Sep 17 00:00:00 2001 From: Laurent Bercot Date: Thu, 18 Sep 2014 18:55:44 +0000 Subject: initial commit with rc for skalibs-2.0.0.0 --- doc/libstddjb/djbunix.html | 760 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 760 insertions(+) create mode 100644 doc/libstddjb/djbunix.html (limited to 'doc/libstddjb/djbunix.html') 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 @@ + + + + + skalibs: the djbunix library interface + + + + + + +

+libstddjb
+libskarnet
+skalibs
+Software
+skarnet.org +

+ +

The djbunix library interface

+ +

+ The following functions are declared in the skalibs/djbunix.h header, +and implemented in the libskarnet.a or libskarnet.so library. +

+ +

General information

+ +

+ djbunix is an alternative API to management of basic Unix +concepts: file descriptors, files, environment, and so on. It is a +rather chaotic mix of safe wrappers +around Unix system calls, better reimplementations of standard libc +functionalities, and higher-level manipulations of Unix concepts. +

+ +

+ Understanding djbunix is essential to understanding any piece +of code depending on skalibs. +

+ +

Functions

+ +

Basic fd operations

+ +

+ int coe (int fd)
+Sets the close-on-exec flag on fd. +Returns 0 if it succeeds, or -1 (and sets errno) if it fails. +

+ +

+ int uncoe (int fd)
+Clears the close-on-exec flag on fd. +Returns 0 if it succeeds, or -1 (and sets errno) if it fails. +

+ +

+ int ndelay_on (int fd)
+Sets the O_NONBLOCK flag on fd: sets it to non-blocking mode. +Returns 0 if it succeeds, or -1 (and sets errno) if it fails. +

+ +

+ int ndelay_off (int fd)
+Clears the O_NONBLOCK flag on fd: sets it to blocking mode. +Returns 0 if it succeeds, or -1 (and sets errno) if it fails. +

+ +

+ int pipenb (int *p)
+Like +pipe(), +but both ends of the created pipe are in non-blocking mode. +

+ +

+ int pipecoe (int *p)
+Like +pipe(), +but both ends of the created pipe are close-on-exec. +

+ +

+ int pipenbcoe (int *p)
+Like +pipe(), +but both ends of the created pipe are in non-blocking mode and close-on-exec. +

+ +

+ int fd_copy (int to, int from)
+Copies the open fd from to number to. to +must not refer to an already open fd. +Returns 0 if it succeeds, or -1 (and sets errno) if it fails. +

+ +

+ int fd_copy2 (int to1, int from1, int to2, int from2)
+Copies the open fd from1 to number to2. Also copies +from2 to to2 at the same time. +Returns 0 if it succeeds, or -1 (and sets errno) if it fails. +

+ +

+ int fd_move (int to, int from)
+Moves the open fd from to number to. to +must not refer to an already open fd, unless it's equal to from. +Returns 0 if it succeeds, or -1 (and sets errno) if it fails. +

+ +

+ int fd_move2 (int to1, int from1, int to2, int from2)
+Moves the open fd from to number to. Also moves +from2 to to2 at the same time. This is useful for instance +when you want to swap two fds: fd_move2 will handle the situation +correctly. +Returns 0 if it succeeds, or -1 (and sets errno) if it fails. +

+ +

+ int fd_close (int fd)
+Closes fd. +Returns 0 if it succeeds, or -1 (and sets errno) if it fails. +This is a safe wrapper around +close(), +or rather as safe a wrapper as is possible to write: the close() +specification does not allow a 100% safe behaviour. So, in rare cases +it is possible for fd_close() 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 fd_close() is +always a static programming error. +

+ +

+ int fd_chmod (int fd, unsigned int mode)
+Safe wrapper around +fchmod(). +

+ +

+ int fd_chown (int fd, unsigned int uid, unsigned int gid)
+Safe wrapper around +fchown(). +This function requires root privileges. +

+ +

+ int fd_sync (int fd)
+Safe wrapper around +fsync(). +

+ +

+ int fd_chdir (int fd)
+Safe wrapper around +fchdir(). +

+ +

+ int fd_cat (int from, int to)
+Synchronously copies data from fd from to fd to, +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. +

+ +

+When the underlying OS allows it, zero-copy transmission is +performed. Currently, the following zero-copy implementations are +supported: +

+ + + +

+ unsigned int fd_catn (int from, int to, unsigned int n)
+Synchronously copies at most n bytes from fd from to fd to. +Returns the total number of transmitted bytes; sets errno if this number +is lesser than n. EOF is reported as EPIPE. See above for zero-copy +transmission; zero-copy transmission is not attempted for less than 64k of data. +

+ +

+ int fd_ensure_open (int fd, int w)
+If fd is not open, opens it to /dev/null, +for reading if w is zero, and for writing otherwise. +Returns 1 if it succeeds and 0 if it fails. +

+ +

+ int fd_sanitize (void)
+Ensures stdin and stdout are open. If one of those +file descriptors was closed, it now points to /dev/null. +Returns 1 if it succeeds and 0 if it fails. +

+ +

+ int lock_ex (int fd)
+Gets an exclusive advisory lock on fd. fd 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. +

+ +

+ int lock_exnb (int fd)
+Gets an exclusive advisory lock on fd. fd 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. +

+ +

+ int lock_sh (int fd)
+Gets a shared advisory lock on fd. fd 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. +

+ +

+ int lock_shnb (int fd)
+Gets a shared advisory lock on fd. fd 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. +

+ +

+ int lock_un (int fd)
+Releases a previously held lock on fd. +Returns 0 if it succeeds, or -1 (and sets errno) if it fails. +

+ +

+ int open2 (char const *file, unsigned int flags)
+Safe wrapper around +open() +when it takes 2 arguments. +

+ +

+ int open3 (char const *file, unsigned int flags)
+Safe wrapper around +open() +when it takes 3 arguments. +

+ +

+ int open_read (char const *file)
+Opens file in read-only, non-blocking mode. +Returns a valid fd number if it succeeds, or -1 (and sets errno) if it fails. +

+ +

+ int open_readb (char const *file)
+Opens file in read-only, blocking mode. +Returns a valid fd number if it succeeds, or -1 (and sets errno) if it fails. +This call does not block. The +open() +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. +

+ +

+ int open_excl (char const *file)
+Opens file 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. +

+ +

+ int open_append (char const *file)
+Opens file 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. +

+ +

+ int open_trunc (char const *file)
+Opens file 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. +

+ +

+ int open_create (char const *file)
+Opens file 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. +

+ +

+ int open_write (char const *file)
+Opens file in write-only, non-blocking mode. +Returns a valid fd number if it succeeds, or -1 (and sets errno) if it fails. +

+ +

Seek operations

+ +

+ long seek_cur (int fd)
+Returns the current file offset for descriptor fd. +

+ +

+ int seek_set (int fd, long pos)
+Sets the current file offset for fd to pos. +Returns 0 if it succeeds, or -1 (and sets errno) if it fails. +

+ +

Privilege management

+ +

+ int prot_readgroups (char const *name, gid_t *tab, unsigned int max)
+Reads the group database (normally /etc/group, but it can be +altered via NSS) to get the list of supplementary groups for user name. +Stores that list into the array pointed to by tab, which must be +preallocated. Stores at most max elements into tab. +Returns -1 and sets errno if it fails; else, returns the number of elements actually +stored into tab. +

+ +

+ int prot_grps (char const *name)
+Sets the kernel-maintained list of supplementary groups for the current process +to the list of supplementary groups for user name according to the +group database. This is a privileged operation. +Returns -1 and sets errno if it fails; returns 0 if it succeeds. +

+ +

+ int prot_gid (int gid)
+Alias to setgid. +

+ +

+ int prot_uid (int uid)
+Alias to setuid. +

+ +

Executable search and execution, and environment

+ +

+ void execvep (char const *file, char const *const *argv, char const *const *envp, char const *path)
+Executes into the executable file at file, with the command line +set to argv and the environment set to envp. +If file is not an absolute path, it is searched in the +path 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. +

+ +

+ void pathexec_run (char const *file, char const *const *argv, char const *const *envp)
+Performs execvep(file, argv, envp, path), path being the +contents of the PATH environment variable. If PATH is not set, path +is set to the contents of the conf-compile/conf-defaultpath file in +the skalibs distribution. +The function returns if it fails, and sets errno appropriately. +

+ +

+ pathexec_run() is the standard skalibs API to perform an +exec call with a path search. It is recommended that you use +it instead of the Single Unix +execvp() or +execlp() +functions, because execvp and execlp default to execution of +the /bin/sh interpreter with file as an argument if they +cannot find a suitable executable file, and this is: +

+ +
    +
  1. a security risk,
  2. +
  3. probably not what you want.
  4. +
+ +

+ execvep() and pathexec_run() just fail with ENOENT +when they cannot find a file to exec into, which is the +sensible behaviour. +

+ +

+ void pathexec0_run (char const *const *argv, char const *const *envp)
+Performs pathexec_run(argv[0], argv, envp). If argv is empty, i.e. +argv[0] is null, the process exits 0 instead. Rationale: executing +the empty command line should amount to executing true, i.e. +simply exiting 0. +

+ +

+ void pathexec_r_name (char const *file, char const *const *argv, char const *const *envp, unsigned int envlen, char const *modifs, unsigned int modiflen)
+Alters envp (which does not have to be NULL-terminated, but the +number envlen of elements must be provided) with the modifier +string modifs of length modiflen, then performs +pathexec_run(file, argv, altered-envp). +

+ +

+ void pathexec_r (char const *const *argv, char const *const *envp, unsigned int envlen, char const *modifs, unsigned int modiflen)
+Same as pathexec_r_name, except that the file argument is read from argv[0]. +

+ +

+ int pathexec_env (char const *var, char const *value)
+Adds the "add variable var with value value" instruction +(if value is not null) or the "unset var" instruction +(if value 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. +

+ +

+ void pathexec_fromenv (char const *const *argv, char const *const *envp, unsigned int envlen)
+Performs pathexec_r() with the given arguments and the hidden modifier +string. +

+ +

+ void pathexec (char const *const *argv)
+Executes into the argv command line, with the current environment +modified by the hidden modifier string. +

+ +

+ void pathexec0 (char const *const *argv)
+Executes into the argv command line, with the current environment +modified by the hidden modifier string. If this command line is empty, +exit 0 instead. +

+ +

+ The env library interface provides additional functions +to manipulate modifier strings and environments. +

+ +

Forking children

+ +

+ int doublefork ()
+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. +

+ +

+ pid_t child_spawn0 (char const *file, char const *const *argv, char const *const *envp)
+Forks and executes a child as with pathexec_run(file, argv, envp). +Returns 0 if it fails, and the pid of the child if it succeeds. +Implemented via posix_spawn() +on systems that support it. +

+ +

+ pid_t child_spawn1 (char const *file, char const *const *argv, char const *const *envp, int *fd, int w)
+Like child_spawn0(), except that a pipe is created between the child's +stdin (if w is 0) or stdout (if w is nonzero) and the parent. +The parent's end of the pipe will be stored in *fd. +

+ +

+ pid_t child_spawn (char const *file, char const *const *argv, char const *const *envp, int *fds, unsigned int nfds)
+More generic spawning function. fds must point to an array of at least nfds 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. +

+ + +

Waiting for children

+ +

+ unsigned int wait_reap ()
+Instantly reaps all the pending zombies, without blocking, without a look at +the exit codes. +Returns the number of reaped zombies. +

+ +

+ int waitn (pid_t *pids, unsigned int n)
+Waits until all processes whose PIDs are stored in the +pids array, of size n, have died. +Returns 1 if it succeeds, and 0 (and sets errno) if it fails. The +pid array is not guaranteed to be unchanged. +

+ +

+ int waitn_reap (pid_t *pids, unsigned int n)
+Instantly reaps all zombies whose PIDs are stored in the +pids array, of size n. +Returns -1 (and sets errno) if it fails, and the number of reaped +zombies if it succeeds. The pid array is not guaranteed to +be unchanged. +

+ +

+ int wait_nohang (int *wstat)
+Instantly reaps one zombie, and stores the status information into +*wstat. +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. +

+ +

+ int waitpid_nointr (pid_t pid, int *wstat, int flags)
+Safe wrapper around +waitpid(). +

+ +

+ int wait_pid_nohang (pid_t pid, int *wstat)
+Instantly reaps an undetermined number of zombies until it finds pid. +Stores the status information for dead pid into *wstat. +Returns pid 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. +

+ +

+ int wait_pids_nohang (pid_t const *pids, unsigned int len, int *wstat)
+Instantly reaps an undetermined number of zombies until it finds one whose +PID is in the pids array, of size len. +Stores the status information for that dead process into *wstat. +Returns the index of the found PID in pids, 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. +

+ +

+ When asynchronously dealing with a child (resp. several children) and +getting a SIGCHLD - which should be handled via a +selfpipe - it is generally a good idea to +use the wait_pid_nohang() (resp. wait_pids_nohang()) +function over the basic Unix APIs. This allows a program to: +

+ + + +

Reading and writing whole files

+ +

+ int slurp (stralloc *sa, int fd)
+Slurps the contents of open descriptor fd into +the *sa stralloc. If you are +doing this, you should either have full control over the slurped +file, or run your process with suitable +limits +to the amount of heap memory it can get. +The function returns 1 if it succeeds, or 0 (and sets errno) if it fails. +

+ +

+ int openslurpclose (stralloc *sa, char const *file)
+Slurps the contents of file file into *sa. +Returns 1 if it succeeds, and 0 (and sets errno) if it fails. +

+ +

+ int openreadclose (char const *file, stralloc *sa, unsigned int dummy)
+Legacy interface for openslurpclose(sa, file). The dummy +argument is unused. Returns 0 if it succeeds, and -1 (and sets errno) if it fails. +

+ +

+ int openreadnclose (char const *file, char *s, unsigned int n)
+Reads at most n bytes from file file into preallocated +buffer s. Returns -1 (and sets errno) if it fails; else returns the +number of read bytes. If that number is not n, errno is set to EPIPE. +

+ +

+ int openreadfileclose (char const *file, stralloc *sa, unsigned int n)
+Reads at most n bytes from file file into the *sa +stralloc, which is grown (if needed) to just accommodate the file +size. Returns 1 if it succeeds and 0 (and sets errno) if it fails. +

+ +

+ int openwritenclose_unsafe_internal (char const *file, char const *s, unsigned int len, uint64 *dev, uint64 *ino, unsigned char dosync)
+Writes the n bytes stored at s into file file. +The previous contents of file are destroyed even if the function +fails. If dosync is nonzero, the new contents of file +are synced to disk before the function returns. If dev and ino +are not null, they're used to store the device and inode number of file. +The function returns 1 if it succeeds, or 0 (and sets errno) if it fails. +

+ +

+ int openwritenclose_unsafe (char const *file, char const *s, unsigned int len)
+int openwritenclose_unsafe_sync (char const *file, char const *s, unsigned int len)
+int openwritenclose_unsafe_devino (char const *file, char const *s, unsigned int len, uint64 *dev, uint64 *ino)
+int openwritenclose_unsafe_devino_sync (char const *file, char const *s, unsigned int len, uint64 *dev, uint64 *ino)

+Trivial shortcuts around openwritenclose_unsafe_internal(). The +reader can easily figure out what they do. +

+ +

+ int openwritenclose_suffix_internal (char const *file, char const *s, unsigned int len, uint64 *dev, uint64 *ino, unsigned char dosync, char const *suffix)
+Writes the n bytes stored at s into file file, +by first writing into filesuffix and atomically renaming +filesuffix to file. IOW, the old contents of file +are preserved if the operation fails, and are atomically replaced with the +new contents if the operation succeeds. +If dosync is nonzero, the new contents of filesuffix +are synced to disk before the atomic replace. If dev and ino +are not null, they're used to store the device and inode number of file. +The function returns 1 if it succeeds, or 0 (and sets errno) if it fails. +

+ +

+ int openwritenclose_suffix (char const *file, char const *s, unsigned int len, char const *suffix)
+int openwritenclose_suffix_sync (char const *file, char const *s, unsigned int len, char const *suffix)
+int openwritenclose_suffix_devino (char const *file, char const *s, unsigned int len, uint64 *dev, uint64 *ino, char const *suffix)
+int openwritenclose_suffix_devino_sync (char const *file, char const *s, unsigned int len, uint64 *dev, uint64 *ino, char const *suffix)

+Trivial shortcuts around openwritenclose_suffix_internal(). The +reader can easily figure out what they do. +

+ +

Filesystem deletion

+ +

+The following operations are not atomic, so if they fail, the +relevant subtree might end up partially deleted. +

+ +

+ int rm_rf (char const *path)
+Deletes the filesystem subtree at path. +Returns 0 if it succeeds or -1 (and sets errno) if it fails. +

+ +

+ int rm_rf_tmp (char const *path, stralloc *tmp)
+Deletes the filesystem subtree at path, using *tmp +as heap-allocated temporary space. +Returns 0 if it succeeds or -1 (and sets errno) if it fails. +

+ +

+ int rm_rf_in_tmp (stralloc *tmp, unsigned int n)
+Deletes a filesystem subtree, using *tmp +as heap-allocated temporary space. +Returns 0 if it succeeds or -1 (and sets errno) if it fails. +When the function is called, *tmp must contain the +null-terminated name of the subtree to delete at offset n. +

+ +

+ int rmstar (char const *dir)
+Deletes all the filesystem subtrees in directory dir. +Returns 0 if it succeeds or -1 (and sets errno) if it fails. +

+ +

+ int rmstar_tmp (char const *dir, stralloc *tmp)
+Deletes all the filesystem subtrees in directory dir, +using *tmp as heap-allocated temporary space. +Returns 0 if it succeeds or -1 (and sets errno) if it fails. +

+ +

Variable length wrappers around Single Unix calls

+ +

+ int sarealpath (stralloc *sa, char const *path)
+Resolves path into a symlink-free absolute path, appending +the result to the *sa +stralloc. +Returns 0 if it succeeds and -1 (and sets errno) if it fails. +

+ +

+ int sarealpath_tmp (stralloc *sa, char const *path, stralloc *tmp)
+Resolves path into a symlink-free absolute path, appending +the result to *sa. Uses *tmp as heap-allocated +temporary space. +Returns 0 if it succeeds and -1 (and sets errno) if it fails. +

+ +

+ int sabasename (stralloc *sa, char const *s, unsigned int len)
+Appends the basename of filename s (of length len) +to *sa. +Returns 1 if it succeeds and 0 (and sets errno) if it fails. +

+ +

+ int sadirname (stralloc *sa, char const *s, unsigned int len)
+Appends the dirname of filename s (of length len) +to *sa. +Returns 1 if it succeeds and 0 (and sets errno) if it fails. +

+ +

+ int sagetcwd (stralloc *sa)
+Appends the current working directory to *sa. +Returns 0 if it succeeds and -1 (and sets errno) if it fails. +

+ +

+ int sareadlink (stralloc *sa, char const *link)
+Appends the contents of symbolic link link to *sa. +Returns 0 if it succeeds and -1 (and sets errno) if it fails. +

+ +

+ int sagethostname (stralloc *sa)
+Appends the machine's hostname to *sa. +Returns 0 if it succeeds and -1 (and sets errno) if it fails. +

+ +

Temporization

+ +

+ void deepsleepuntil (tain_t const *deadline, tain_t *stamp)
+Sleeps until the absolute time represented by the +tain_t *deadline. *stamp +must contain the current time. When the function returns, *stamp +has been updated to reflect the new current time. +

+ +

+ void deepsleep (unsigned int n)
+Sleeps n seconds. Signals received during that time are handled, +but do not interrupt the sleep. +

+ +

+ void deepmillisleep (unsigned long n)
+Sleeps n milliseconds. Signals received during that time are handled, +but do not interrupt the sleep. +

+ + + -- cgit v1.2.3