skalibs

Mirror/fork of https://skarnet.org/software/skalibs/
git clone https://ccx.te2000.cz/git/skalibs
Log | Files | Refs | README | LICENSE

commit 8ba811fb48d666a23d60a5ce3a947dcac7baf6ea
parent ab2813a10a7fe6edbbef2acdfd22c0666171f566
Author: Laurent Bercot <ska-skaware@skarnet.org>
Date:   Sat,  9 Sep 2023 14:10:40 +0000

 Document cspawn

Signed-off-by: Laurent Bercot <ska@appnovation.com>

Diffstat:
MNEWS | 2+-
Mdoc/crosscompile.html | 6+++++-
Adoc/libstddjb/cspawn.html | 130+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mdoc/libstddjb/djbunix.html | 47++---------------------------------------------
Mdoc/libstddjb/index.html | 1+
Mdoc/license.html | 2+-
6 files changed, 140 insertions(+), 48 deletions(-)

diff --git a/NEWS b/NEWS @@ -1,6 +1,6 @@ Changelog for skalibs. -In 2.13.2.0 +In 2.14.0.0 ----------- - Bugfixes. diff --git a/doc/crosscompile.html b/doc/crosscompile.html @@ -83,13 +83,17 @@ the time <tt>yes</tt> or <tt>no</tt>. <p> At all times, <tt>./configure --help</tt> provides the list of sysdeps you need to provide a <tt>--with-sysdep-*</tt> option for. As of -skalibs-2.9.3.0, there is only one sysdep in this case: +skalibs-2.14.0.0, there are two sysdeps in this case: </p> <ul> <li> <tt>devurandom</tt>: <tt>yes</tt> if the target has a valid pseudorandom generation device in <tt>/dev/urandom</tt>, and <tt>no</tt> otherwise. </li> + <li> <tt>posixspawnearlyreturn</tt>: <tt>yes</tt> if the target has a broken +<a href="https://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_spawn.html">posix_spawn()</a> +implementation that can return before the child has successfully exec'ed. +That happens with old glibcs and some virtual platforms. </li> </ul> </body> diff --git a/doc/libstddjb/cspawn.html b/doc/libstddjb/cspawn.html @@ -0,0 +1,130 @@ +<html> + <head> + <meta name="viewport" content="width=device-width, initial-scale=1.0" /> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <meta http-equiv="Content-Language" content="en" /> + <title>skalibs: the cspawn library interface</title> + <meta name="Description" content="skalibs: the cspawn library interface" /> + <meta name="Keywords" content="skalibs c unix cspawn fork posix_spawn child process exec library libstddjb" /> + <!-- <link rel="stylesheet" type="text/css" href="//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="//skarnet.org/software/">Software</a><br /> +<a href="//skarnet.org/">skarnet.org</a> +</p> + +<h1> The <tt>cspawn</tt> library interface </h1> + +<p> + The following functions are declared in the <tt>skalibs/cspawn.h</tt> header, +and implemented in the <tt>libskarnet.a</tt> or <tt>libskarnet.so</tt> library. +</p> + +<h2> General information </h2> + +<p> + <tt>cspawn</tt> is a unifier API to spawn child processes with +<a href="https://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_spawn.html">posix_spawn()</a> +as a backend if supported by the system, falling back on +<a href="https://pubs.opengroup.org/onlinepubs/9699919799/functions/fork.html">fork()</a> + +<a href="https://pubs.opengroup.org/onlinepubs/9699919799/functions/execve.html">execve()</a> +otherwise. +</p> + +<h2> Functions </h2> + +<h3> Primitive </h3> + +<p> +<code> pid_t cspawn (char const *file, char const *const *argv, char const *const *envp, uint32_t flags, cspawn_fileaction const *fa, size_t n) </code> <br /> +Forks and execs a child as with <tt>exec_ae(file, argv, envp)</tt>. +Returns 0 if it fails, and the pid of the child if it succeeds. +Before execing, the following operations are performed in the child: +</p> + +<ul> + <li> If <em>flags</em> contains (the or-able value) CSPAWN_FLAGS_SIGBLOCKNONE, +the child's signal processing mask is reset - no signal will be blocked. </li> + <li> Alternatively, if <em>flags</em> contains (the or-able value) CSPAWN_FLAGS_SELFPIPE_FINISH, +the child's signal state is reset to what it was before the invocation of +<tt>selfpipe_init()</tt> in the parent. </li> + <li> The file actions described in the array <em>fa</em>, which must have at least <em>n</em> elements, +are processed in order. For every <em>i</em> from 0 to <em>n</em>-1: + <ul> + <li> if <tt>fa[i].type</tt> is CSPAWN_FA_CLOSE, then file descriptor <tt>fa[i].x.fd</tt> is closed </li> + <li> else if <tt>fa[i].type</tt> is CSPAWN_FA_MOVE, then file descriptor <tt>fa[i].x.fd2[1]</tt> +is moved to <tt>fa[i].x.fd2[0]</tt> </li> + <li> else if <tt>fa[i].type</tt> is CSPAWN_FA_COPY, then file descriptor <tt>fa[i].x.fd2[1]</tt> +is copied to <tt>fa[i].x.fd2[0]</tt>, as with <tt>dup2(fa[i].x.fd2[1], fa[i].x.fd2[0])</tt> </li> + <li> else if <tt>fa[i].type</tt> is CSPAWN_FA_OPEN, then file <tt>fa[i].x.openinfo.file</tt> is +opened with flags <tt>fa[i].x.openinfo.oflag</tt> and mode <tt>fa[i].x.openinfo.mode</tt>, and file +descriptor <tt>fa[i].x.openinfo.fd</tt> points to it. </li> + </ul> </li> +</ul> + +<h3> Higher level interfaces </h3> + +<p> +<code> pid_t child_spawn1_pipe (char const *file, char const *const *argv, char const *const *envp, int *fd, int w) </code> <br /> +Spawns <em>file</em> as with <tt>cspawn()</tt> with a <em>flags</em> value of CSPAWN_FLAGS_SIGBLOCKNONE; +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_spawn1_socket (char const *file, char const *const *argv, char const *const *envp, int *fd) </code> <br /> +Like <tt>child_spawn1</tt>, except that a socket, not a pipe is created between the parent +and the child. Both the child's stdin and stdout point to the socket; the parent has +its end of the socket available in *<em>fd</em>. +</p> + +<p> +<code> pid_t child_spawn2 (char const *file, char const *const *argv, char const *const *envp, int *fds) </code> <br /> +Two pipes are created between the +parent and the child. <em>fds</em> must point to an array of 2 ints: this +array is read as well as written by <tt>child_spawn2()</tt>. On function +call, the numbers in <em>fds</em> must describe what fds should be used +in the child to contain the communication pipes (for instance, if the child +will read from its parent on stdin and write to its parent on stdout, <em>fds</em> +must contain 0 and 1). On function return, <em>fds</em> contains the +descriptors for the pipes that read from / write to the child. +</p> + +<p> +<code> pid_t child_spawn3 (char const *file, char const *const *argv, char const *const *envp, int *fds) </code> <br /> +Three pipes are created between the +parent and the child. <em>fds</em> must point to an array of 3 ints: this +array is read as well as written by <tt>child_spawn2()</tt>. On function +call, the numbers in <em>fds[0]</em> and <em>fds[1]</em> must describe what fds should be used +in the child to read from (resp. write to) the parent. +On function return, <em>fds</em> contains the +descriptors for the pipes that read from / write to the child. <em>fds[2]</em> is +the reading end of a pipe; the writing end is present in the child, and its number +is available as the value of the <tt>SKALIBS_CHILD_SPAWN_FDS</tt> environment variable. +</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>cspawn</tt> with a flags value +of CSPAWN_FLAGS_SIGBLOCKNONE. </li> + <li> If <em>nfds</em> is 1 or more, then <em>fds</em> will contain pipes between the +child and the parent. The parent will read on even-numbered ones +and write on odd-numbered ones. The child will read on <em>fds[0]</em>, write on <em>fds[1]</em>, +then any additional fds are available to it in the <tt>SKALIBS_CHILD_SPAWN_FDS</tt> environment +variable as a comma-separated list of integers. </li> +</ul> + +</body> +</html> diff --git a/doc/libstddjb/djbunix.html b/doc/libstddjb/djbunix.html @@ -357,53 +357,10 @@ 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>exec_ae(file, argv, envp)</tt>. -Returns 0 if it fails, and the pid of the child if it succeeds. -Implemented via <a href="https://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_spawn.html">posix_spawn()</a> -on systems that support it. +The <tt>child_spawn</tt> family of functions has been moved to the +<a href="cspawn.html">skalibs/cspawn.h</a> header. </p> -<p> -<code> pid_t child_spawn1_pipe (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_spawn1_socket (char const *file, char const *const *argv, char const *const *envp, int *fd) </code> <br /> -Like <tt>child_spawn0</tt>, except that a socket is created between the parent -and the child. Both the child's stdin and stdout point to the socket; the parent has -its end of the socket available in *<em>fd</em>. -</p> - -<p> -<code> pid_t child_spawn2 (char const *file, char const *const *argv, char const *const *envp, int *fds) </code> <br /> -Like <tt>child_spawn0()</tt>, except that two pipes are created between the -parent and the child. <em>fds</em> must point to an array of 2 ints: this -array is read as well as written by <tt>child_spawn2()</tt>. On function -call, the numbers in <em>fds</em> must describe what fds should be used -in the child to contain the communication pipes (for instance, if the child -will read from its parent on stdin and writes to its parent on stdout, <em>fds</em> -must contain 0 and 1). On function return, <em>fds</em> contains the -descriptors for the pipes that read from / write to the child. -</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 ignored signals will be un-ignored in the child </li> - <li> If <em>nfds</em> is 1 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> diff --git a/doc/libstddjb/index.html b/doc/libstddjb/index.html @@ -57,6 +57,7 @@ wrappers</a> around I/O functions, extra I/O functions </li> <a href="https://en.wikipedia.org/wiki/Cdb_%28software%29">cdb</a> files </li> <li> <a href="cdbmake.html">skalibs/cdbmake.h</a>: how to write <a href="https://en.wikipedia.org/wiki/Cdb_%28software%29">cdb</a> files </li> + <li> <a href="cspawn.html">skalibs/cspawn.h</a>: child spawning primitives that use posix_spawn instead of fork when supported </li> <li> <a href="direntry.html">skalibs/direntry.h</a>: portable directory operations </li> <li> <a href="djbtime.html">skalibs/djbtime.h</a>: conversions between date and time formats </li> <li> <a href="djbunix.html">skalibs/djbunix.h</a>: management of basic Unix concepts </li> diff --git a/doc/license.html b/doc/license.html @@ -74,7 +74,7 @@ color, or different text font. </li> <p> <em>I am aware that the previous restrictions sound completely ridiculous while the official skalibs documentation is incomplete. -As of 2.13.1.1, I'm not going to enforce those restrictions, but if you're +As of 2.14.0.0, I'm not going to enforce those restrictions, but if you're going to provide documentation for skalibs, don't keep it to yourself, please send it to me instead. :-) </em> </p>