feat(process): fork/exec/id/session + system/popen
This commit is contained in:
@@ -261,6 +261,21 @@ tmpfile(void);
|
||||
__attribute__((pure)) int
|
||||
fileno(FILE *stream);
|
||||
|
||||
/*
|
||||
* Run command in a subshell ("sh -c command") with a pipe attached to
|
||||
* its standard output (mode "r") or standard input (mode "w"). Only the
|
||||
* two POSIX modes are accepted (the glibc "re"/"we" close-on-exec
|
||||
* extension is not). Returns the stream, or NULL with errno set.
|
||||
* pclose closes the stream, waits for the shell, and returns its
|
||||
* termination status (the raw wait status, e.g. 0 for "exit 0"), or -1
|
||||
* when the stream was not opened by popen or the wait failed.
|
||||
*/
|
||||
FILE *
|
||||
popen(const char *command, const char *mode);
|
||||
|
||||
int
|
||||
pclose(FILE *stream);
|
||||
|
||||
/* getc/putc/getchar/putchar as macros over fgetc/fputc (see above). */
|
||||
#define getc(stream) fgetc(stream)
|
||||
#define putc(c, stream) fputc((c), (stream))
|
||||
|
||||
@@ -463,6 +463,19 @@ mkstemp(char *);
|
||||
char *
|
||||
mkdtemp(char *);
|
||||
|
||||
/* process control (todo 20) */
|
||||
|
||||
/*
|
||||
* Pass string to the command language interpreter: "sh -c string".
|
||||
* Returns the shell's wait status (e.g. 768 for "exit 3"), 1 when
|
||||
* string is NULL (a shell is always available), or -1 with errno set
|
||||
* when the child cannot be created or reaped. During the run, SIGCHLD
|
||||
* is blocked and SIGINT/SIGQUIT are ignored in the caller, as POSIX
|
||||
* requires.
|
||||
*/
|
||||
int
|
||||
system(const char *string);
|
||||
|
||||
#if VLIBC_LEVEL_GE(2)
|
||||
/* Level 2 (muslmimic): XSI and BSD environment extras. */
|
||||
|
||||
|
||||
+167
-2
@@ -15,6 +15,15 @@
|
||||
* Level 2 (muslmimic): dup3, pipe2 (Linux extensions), truncate (XSI),
|
||||
* lseek64 (glibc LFS alias of lseek on x86_64).
|
||||
*
|
||||
* Process control (todo 20) is declared further down:
|
||||
*
|
||||
* Level 1 (onlyposix): fork, exec family (execl/execlp/execle/execv/
|
||||
* execvp/execve/fexecve), getpid, getppid, getuid,
|
||||
* geteuid, getgid, getegid, setuid, seteuid, setgid,
|
||||
* setegid, getgroups, setpgid, getpgrp, setsid.
|
||||
* Level 2 (muslmimic): vfork, setpgrp (obsolescent), setgroups, getpgid,
|
||||
* getsid, tcgetpgrp, tcsetpgrp (XSI).
|
||||
*
|
||||
* The open-flag constants (O_RDONLY, O_CREAT, O_CLOEXEC, ...) belong to
|
||||
* <fcntl.h> and are deliberately not defined here; the oflag arguments below
|
||||
* are plain int and take their values from that header. The optional mode
|
||||
@@ -23,7 +32,10 @@
|
||||
*
|
||||
* None of these declarations carry an intent attribute: every function
|
||||
* performs I/O with side effects and reports failures through errno, so
|
||||
* const/pure would be unsound.
|
||||
* const/pure would be unsound. The process functions additionally must not
|
||||
* be const/pure because their results are process state — marking getpid
|
||||
* const, for example, would let the compiler hoist it across fork() and
|
||||
* observe the parent's pid inside the child.
|
||||
*/
|
||||
|
||||
#include <vlibc/features.h>
|
||||
@@ -174,8 +186,119 @@ access(const char *path, int amode);
|
||||
int
|
||||
faccessat(int fd, const char *path, int amode, int flag);
|
||||
|
||||
/* Level 1 (POSIX base): process control. */
|
||||
|
||||
/*
|
||||
* Create a child process that is a copy of the caller: fork() returns 0
|
||||
* in the child, the child's pid in the parent, and -1 with errno set on
|
||||
* failure.
|
||||
*
|
||||
* Around the fork, the atfork hook table runs: the prepare handlers in
|
||||
* reverse registration order before the fork, then the child handlers in
|
||||
* the child and the parent handlers in the parent, both in registration
|
||||
* order (POSIX pthread_atfork protocol). The table is registered by
|
||||
* pthread_atfork() (todo 45) and is empty — a no-op — in a process
|
||||
* without threads.
|
||||
*/
|
||||
pid_t
|
||||
fork(void);
|
||||
|
||||
/*
|
||||
* Replace the calling process image. Success never returns; -1 with
|
||||
* errno set otherwise. execl/execle/execlp take the arguments as a
|
||||
* varargs list terminated by (char *)NULL (execle is followed by one
|
||||
* final char *const envp[] argument); execv/execvp take an argv array.
|
||||
* execvp and execlp search the PATH environment variable (default
|
||||
* "/bin:/usr/bin") when file contains no '/'. execv/execvp/execl/execlp
|
||||
* use the caller's environment; execve/execle/fexecve take envp.
|
||||
*/
|
||||
// NOLINTBEGIN(bugprone-easily-swappable-parameters)
|
||||
int
|
||||
execl(const char *path, const char *arg0, ...);
|
||||
|
||||
int
|
||||
execle(const char *path, const char *arg0, ...);
|
||||
|
||||
int
|
||||
execlp(const char *file, const char *arg0, ...);
|
||||
// NOLINTEND(bugprone-easily-swappable-parameters)
|
||||
|
||||
int
|
||||
execv(const char *path, char *const argv[]);
|
||||
|
||||
int
|
||||
execvp(const char *file, char *const argv[]);
|
||||
|
||||
int
|
||||
execve(const char *path, char *const argv[], char *const envp[]);
|
||||
|
||||
/*
|
||||
* Like execve, but the image is the open descriptor fd.
|
||||
*/
|
||||
int
|
||||
fexecve(int fd, char *const argv[], char *const envp[]);
|
||||
|
||||
/*
|
||||
* Process ids. getpid/getppid/getuid/geteuid/getgid/getegid read the
|
||||
* kernel's per-process ids; setuid/seteuid/setgid/setegid change them.
|
||||
* seteuid/setegid change only the effective id (setresuid/setresgid
|
||||
* underneath: Linux has no seteuid/setegid syscall).
|
||||
*/
|
||||
pid_t
|
||||
getpid(void);
|
||||
|
||||
pid_t
|
||||
getppid(void);
|
||||
|
||||
uid_t
|
||||
getuid(void);
|
||||
|
||||
uid_t
|
||||
geteuid(void);
|
||||
|
||||
gid_t
|
||||
getgid(void);
|
||||
|
||||
gid_t
|
||||
getegid(void);
|
||||
|
||||
int
|
||||
setuid(uid_t uid);
|
||||
|
||||
int
|
||||
seteuid(uid_t euid);
|
||||
|
||||
int
|
||||
setgid(gid_t gid);
|
||||
|
||||
int
|
||||
setegid(gid_t egid);
|
||||
|
||||
/*
|
||||
* Supplementary groups: getgroups fills grouplist with up to gidsetsize
|
||||
* group ids and returns the total count (0 can be passed to count only);
|
||||
* setgroups (level 2, XSI) installs the list.
|
||||
*/
|
||||
int
|
||||
getgroups(int gidsetsize, gid_t grouplist[]);
|
||||
|
||||
/*
|
||||
* Session control: setpgid moves pid into process group pgid (0 means
|
||||
* the caller / the caller's pid); getpgrp returns the caller's process
|
||||
* group; setsid creates a new session with the caller as leader and
|
||||
* returns the new session id.
|
||||
*/
|
||||
int
|
||||
setpgid(pid_t pid, pid_t pgid);
|
||||
|
||||
pid_t
|
||||
getpgrp(void);
|
||||
|
||||
pid_t
|
||||
setsid(void);
|
||||
|
||||
#if VLIBC_LEVEL_GE(2)
|
||||
/* Level 2 (muslmimic): Linux extensions + XSI. */
|
||||
/* Level 2 (muslmimic): Linux extensions + XSI + obsolescent. */
|
||||
|
||||
/*
|
||||
* Like dup2(), but with descriptor flags (O_CLOEXEC from <fcntl.h>) applied
|
||||
@@ -205,6 +328,48 @@ truncate(const char *path, off_t length);
|
||||
*/
|
||||
off_t
|
||||
lseek64(int fildes, off_t offset, int whence);
|
||||
|
||||
/*
|
||||
* vfork (obsolescent): like fork(), but the child borrows the parent's
|
||||
* address space until it execs or exits.
|
||||
*/
|
||||
pid_t
|
||||
vfork(void);
|
||||
|
||||
/*
|
||||
* setpgrp (obsolescent): setpgid(0, 0) — the caller becomes the leader
|
||||
* of its own process group.
|
||||
*/
|
||||
int
|
||||
setpgrp(void);
|
||||
|
||||
/*
|
||||
* setgroups (XSI): install the supplementary group list of gidsetsize
|
||||
* entries. Requires privilege.
|
||||
*/
|
||||
int
|
||||
setgroups(size_t gidsetsize, const gid_t *grouplist);
|
||||
|
||||
/*
|
||||
* getpgid/getsid (XSI): the process group / session of pid (0 = the
|
||||
* caller).
|
||||
*/
|
||||
pid_t
|
||||
getpgid(pid_t pid);
|
||||
|
||||
pid_t
|
||||
getsid(pid_t pid);
|
||||
|
||||
/*
|
||||
* Controlling-terminal foreground process group (XSI): tcgetpgrp reads
|
||||
* the foreground group of the terminal on fildes; tcsetpgrp makes pgid
|
||||
* the foreground group.
|
||||
*/
|
||||
pid_t
|
||||
tcgetpgrp(int fildes);
|
||||
|
||||
int
|
||||
tcsetpgrp(int fildes, pid_t pgid);
|
||||
#endif /* VLIBC_LEVEL_GE(2) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
Reference in New Issue
Block a user