380 lines
10 KiB
C
380 lines
10 KiB
C
#ifndef VLIBC_UNISTD_H
|
|
#define VLIBC_UNISTD_H
|
|
|
|
/*
|
|
* vlibc — <unistd.h>.
|
|
*
|
|
* File descriptors, file I/O, and the access/whence symbolic constants
|
|
* (POSIX.1-2008). Every function here is an unbuffered pass-through to the
|
|
* kernel: failures are reported as -1 (or the fd/offset on success) with
|
|
* errno set by the syscall layer.
|
|
*
|
|
* Level 1 (onlyposix): read, write, pread, pwrite, open, openat, close,
|
|
* lseek, dup, dup2, pipe, fsync, fdatasync, ftruncate,
|
|
* sync, access, faccessat.
|
|
* 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
|
|
* argument of open/openat is a mode_t supplied only when oflag contains
|
|
* O_CREAT or O_TMPFILE.
|
|
*
|
|
* 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. 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>
|
|
|
|
#include <stddef.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/* Level 1 (POSIX base). */
|
|
|
|
/* Access-check modes for access() and faccessat(). */
|
|
#define F_OK 0 /* existence only */
|
|
#define X_OK 1 /* execute (search for a directory) */
|
|
#define W_OK 2 /* write */
|
|
#define R_OK 4 /* read */
|
|
|
|
/* whence values for lseek() and lseek64() (also defined by <stdio.h>). */
|
|
#define SEEK_SET 0 /* from the beginning of the file */
|
|
#define SEEK_CUR 1 /* from the current position */
|
|
#define SEEK_END 2 /* from the end of the file */
|
|
|
|
/*
|
|
* Read up to nbyte bytes from fildes into buf and return the number of
|
|
* bytes read, 0 at end of file, or -1 with errno set on error. Unbuffered.
|
|
*/
|
|
ssize_t
|
|
read(int fildes, void *buf, size_t nbyte);
|
|
|
|
/*
|
|
* Write up to nbyte bytes from buf to fildes and return the number of
|
|
* bytes written, or -1 with errno set on error. Unbuffered.
|
|
*/
|
|
ssize_t
|
|
write(int fildes, const void *buf, size_t nbyte);
|
|
|
|
/*
|
|
* Read nbyte bytes from fildes starting at offset, without changing the
|
|
* file position; return the number of bytes read, or -1 with errno set.
|
|
*/
|
|
ssize_t
|
|
pread(int fildes, void *buf, size_t nbyte, off_t offset);
|
|
|
|
/*
|
|
* Write nbyte bytes from buf to fildes starting at offset, without
|
|
* changing the file position; return the number of bytes written, or -1
|
|
* with errno set.
|
|
*/
|
|
ssize_t
|
|
pwrite(int fildes, const void *buf, size_t nbyte, off_t offset);
|
|
|
|
/*
|
|
* Open path with the oflag access mode (from <fcntl.h>) and return a file
|
|
* descriptor, or -1 with errno set. A mode argument is required — and read
|
|
* from the varargs — only when oflag contains O_CREAT or O_TMPFILE.
|
|
*/
|
|
int
|
|
open(const char *path, int oflag, ...);
|
|
|
|
/*
|
|
* Like open(), but path is relative to the directory named by fd (use
|
|
* AT_FDCWD from <fcntl.h> for the current working directory). The mode
|
|
* varargs rule is the same as open().
|
|
*/
|
|
int
|
|
openat(int fd, const char *path, int oflag, ...);
|
|
|
|
/*
|
|
* Close the file descriptor fildes; return 0, or -1 with errno set.
|
|
*/
|
|
int
|
|
close(int fildes);
|
|
|
|
/*
|
|
* Reposition the file offset of fildes to offset per whence (SEEK_SET,
|
|
* SEEK_CUR, SEEK_END) and return the resulting offset, or (off_t)-1 with
|
|
* errno set. The full 64-bit offset is returned; errno is untouched on
|
|
* success.
|
|
*/
|
|
off_t
|
|
lseek(int fildes, off_t offset, int whence);
|
|
|
|
/*
|
|
* Duplicate fildes to the lowest-numbered free descriptor; return it, or
|
|
* -1 with errno set. The copy shares the file description (position,
|
|
* flags, locks) with the original.
|
|
*/
|
|
int
|
|
dup(int fildes);
|
|
|
|
/*
|
|
* Duplicate fildes onto fildes2, closing fildes2 first if it was open;
|
|
* return fildes2, or -1 with errno set. dup2(f, f) returns f without
|
|
* doing anything (POSIX).
|
|
*/
|
|
int
|
|
dup2(int fildes, int fildes2);
|
|
|
|
/*
|
|
* Create a pipe: fildes[0] becomes the read end, fildes[1] the write end.
|
|
* Return 0, or -1 with errno set. No descriptor flags are set (unlike
|
|
* pipe2, this is plain POSIX).
|
|
*/
|
|
int
|
|
pipe(int fildes[2]);
|
|
|
|
/*
|
|
* Flush all buffered modifications of fildes and its metadata to stable
|
|
* storage; return 0, or -1 with errno set.
|
|
*/
|
|
int
|
|
fsync(int fildes);
|
|
|
|
/*
|
|
* Like fsync(), but may skip the metadata work needed only to preserve
|
|
* file contents; return 0, or -1 with errno set.
|
|
*/
|
|
int
|
|
fdatasync(int fildes);
|
|
|
|
/*
|
|
* Truncate fildes to length bytes; return 0, or -1 with errno set.
|
|
*/
|
|
int
|
|
ftruncate(int fildes, off_t length);
|
|
|
|
/*
|
|
* Flush all filesystem caches to stable storage. Returns nothing.
|
|
*/
|
|
void
|
|
sync(void);
|
|
|
|
/*
|
|
* Check accessibility of path under amode (R_OK, W_OK, X_OK, F_OK); return
|
|
* 0, or -1 with errno set. Uses the real IDs of the calling process.
|
|
*/
|
|
int
|
|
access(const char *path, int amode);
|
|
|
|
/*
|
|
* Like access(), but path is relative to the directory named by fd (use
|
|
* AT_FDCWD for the current working directory) and flag may hold
|
|
* AT_EACCESS; return 0, or -1 with errno set.
|
|
*/
|
|
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 + obsolescent. */
|
|
|
|
/*
|
|
* Like dup2(), but with descriptor flags (O_CLOEXEC from <fcntl.h>) applied
|
|
* atomically; return fildes2, or -1 with errno set. Linux-specific.
|
|
*/
|
|
int
|
|
dup3(int fildes, int fildes2, int flags);
|
|
|
|
/*
|
|
* Like pipe(), but with descriptor flags (e.g. O_CLOEXEC) applied
|
|
* atomically; return 0, or -1 with errno set. Linux-specific.
|
|
*/
|
|
int
|
|
pipe2(int fildes[2], int flags);
|
|
|
|
/*
|
|
* Truncate the file named by path to length bytes; return 0, or -1 with
|
|
* errno set. XSI.
|
|
*/
|
|
int
|
|
truncate(const char *path, off_t length);
|
|
|
|
/*
|
|
* glibc LFS alias of lseek(): on x86_64 the LFS and non-LFS off_t are
|
|
* identical (both 64-bit), so this simply calls lseek(). Provided for
|
|
* source compatibility only.
|
|
*/
|
|
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
|
|
}
|
|
#endif
|
|
|
|
#endif /* VLIBC_UNISTD_H */
|