title: pidfd_getfd(2)

text:
# pidfd_getfd(2)

## NAME
pidfd_getfd - obtain a duplicate of another process's file descriptor

## LIBRARY
Standard C library (libc, -lc)

## SYNOPSIS

```
#include <sys/syscall.h>      /* Definition of SYS_* constants */
#include <unistd.h>
```

```
int syscall(SYS_pidfd_getfd, int pidfd, int targetfd,
            unsigned int flags);
```

Note: glibc provides no wrapper for pidfd_getfd(), necessitating the use of syscall(2).

## DESCRIPTION
The pidfd_getfd() system call allocates a new file descriptor in the calling process. This new file descriptor is a duplicate of an existing file descriptor, targetfd, in the process referred to by the PID file descriptor pidfd.

The duplicate file descriptor refers to the same open file description (see open(2)) as the original file descriptor in the process referred to by pidfd. The two file descriptors thus share file status flags and file offset. Furthermore, operations on the underlying file object (for example, assigning an address to a socket object using bind(2)) can equally be performed via the duplicate file descriptor.

The close-on-exec flag (FD_CLOEXEC; see fcntl(2)) is set on the file descriptor returned by pidfd_getfd().

The flags argument is reserved for future use. Currently, it must be specified as 0.

Permission to duplicate another process's file descriptor is governed by a ptrace access mode PTRACE_MODE_ATTACH_REALCREDS check (see ptrace(2)).

## RETURN VALUE
On success, pidfd_getfd() returns a file descriptor (a nonnegative integer). On error, -1 is returned and errno is set to indicate the error.

## ERRORS
EBADF

pidfd is not a valid PID file descriptor.

EBADF

targetfd is not an open file descriptor in the process referred to by pidfd.

EINVAL

flags is not 0.

EMFILE

The per-process limit on the number of open file descriptors has been reached (see the description of RLIMIT_NOFILE in getrlimit(2)).

ENFILE

The system-wide limit on the total number of open files has been reached.

EPERM

The calling process did not have PTRACE_MODE_ATTACH_REALCREDS permissions (see ptrace(2)) over the process referred to by pidfd.

ESRCH

The process referred to by pidfd does not exist (i.e., it has terminated and been waited on).

## STANDARDS
Linux.

## HISTORY
Linux 5.6.

## NOTES
For a description of PID file descriptors, see pidfd_open(2).

The effect of pidfd_getfd() is similar to the use of SCM_RIGHTS messages described in unix(7), but differs in the following respects:

•

In order to pass a file descriptor using an SCM_RIGHTS message, the two processes must first establish a UNIX domain socket connection.

•

The use of SCM_RIGHTS requires cooperation on the part of the process whose file descriptor is being copied. By contrast, no such cooperation is necessary when using pidfd_getfd().

•

The ability to use pidfd_getfd() is restricted by a PTRACE_MODE_ATTACH_REALCREDS ptrace access mode check.

## SEE ALSO
clone3(2), dup(2), kcmp(2), pidfd_open(2)


package: man-pages

title: pidfd_open(2)

text:
# pidfd_open(2)

## NAME
pidfd_open - obtain a file descriptor that refers to a process

## LIBRARY
Standard C library (libc, -lc)

## SYNOPSIS

```
#include <sys/syscall.h>      /* Definition of SYS_* constants */
#include <unistd.h>
```

```
int syscall(SYS_pidfd_open, pid_t pid, unsigned int flags);
```

Note: glibc provides no wrapper for pidfd_open(), necessitating the use of syscall(2).

## DESCRIPTION
The pidfd_open() system call creates a file descriptor that refers to the process whose PID is specified in pid. The file descriptor is returned as the function result; the close-on-exec flag is set on the file descriptor.

The flags argument either has the value 0, or contains the following flag:

PIDFD_NONBLOCK (since Linux 5.10)

Return a nonblocking file descriptor. If the process referred to by the file descriptor has not yet terminated, then an attempt to wait on the file descriptor using waitid(2) will immediately return the error EAGAIN rather than blocking.

## RETURN VALUE
On success, pidfd_open() returns a file descriptor (a nonnegative integer). On error, -1 is returned and errno is set to indicate the error.

## ERRORS
EINVAL

flags is not valid.

EINVAL

pid is not valid.

EMFILE

The per-process limit on the number of open file descriptors has been reached (see the description of RLIMIT_NOFILE in getrlimit(2)).

ENFILE

The system-wide limit on the total number of open files has been reached.

ENODEV

The anonymous inode filesystem is not available in this kernel.

ENOMEM

Insufficient kernel memory was available.

ESRCH

The process specified by pid does not exist.

## STANDARDS
Linux.

## HISTORY
Linux 5.3.

## NOTES
The following code sequence can be used to obtain a file descriptor for the child of fork(2):

```
pid = fork();
if (pid > 0) {     /* If parent */

    pidfd = pidfd_open(pid, 0);

    ...
}
```

Even if the child has already terminated by the time of the pidfd_open() call, its PID will not have been recycled and the returned file descriptor will refer to the resulting zombie process. Note, however, that this is guaranteed only if the following conditions hold true:

•

the disposition of SIGCHLD has not been explicitly set to SIG_IGN (see sigaction(2));

•

the SA_NOCLDWAIT flag was not specified while establishing a handler for SIGCHLD or while setting the disposition of that signal to SIG_DFL (see sigaction(2)); and

•

the zombie process was not reaped elsewhere in the program (e.g., either by an asynchronously executed signal handler or by wait(2) or similar in another thread).

If any of these conditions does not hold, then the child process (along with a PID file descriptor that refers to it) should instead be created using clone(2) with the CLONE_PIDFD flag.

### Use cases for PID file descriptors
A PID file descriptor returned by pidfd_open() (or by clone(2) with the CLONE_PID flag) can be used for the following purposes:

•

The pidfd_send_signal(2) system call can be used to send a signal to the process referred to by a PID file descriptor.

•

A PID file descriptor can be monitored using poll(2), select(2), and epoll(7). When the process that it refers to terminates, these interfaces indicate the file descriptor as readable. Note, however, that in the current implementation, nothing can be read from the file descriptor (read(2) on the file descriptor fails with the error EINVAL).

•

If the PID file descriptor refers to a child of the calling process, then it can be waited on using waitid(2).

•

The pidfd_getfd(2) system call can be used to obtain a duplicate of a file descriptor of another process referred to by a PID file descriptor.

•

A PID file descriptor can be used as the argument of setns(2) in order to move into one or more of the same namespaces as the process referred to by the file descriptor.

•

A PID file descriptor can be used as the argument of process_madvise(2) in order to provide advice on the memory usage patterns of the process referred to by the file descriptor.

The pidfd_open() system call is the preferred way of obtaining a PID file descriptor for an already existing process. The alternative is to obtain a file descriptor by opening a /proc/pid directory. However, the latter technique is possible only if the proc(5) filesystem is mounted; furthermore, the file descriptor obtained in this way is not pollable and can't be waited on with waitid(2).

## EXAMPLES
The program below opens a PID file descriptor for the process whose PID is specified as its command-line argument. It then uses poll(2) to monitor the file descriptor for process exit, as indicated by an EPOLLIN event.

### Program source

```
#define _GNU_SOURCE
#include <poll.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/syscall.h>
#include <unistd.h>
static int
pidfd_open(pid_t pid, unsigned int flags)
{

    return syscall(SYS_pidfd_open, pid, flags);
}
int
main(int argc, char *argv[])
{

    int            pidfd, ready;

    struct pollfd  pollfd;

    if (argc != 2) {

        fprintf(stderr, "Usage: %s <pid>\n", argv[0]);

        exit(EXIT_SUCCESS);

    }

    pidfd = pidfd_open(atoi(argv[1]), 0);

    if (pidfd == -1) {

        perror("pidfd_open");

        exit(EXIT_FAILURE);

    }

    pollfd.fd = pidfd;

    pollfd.events = POLLIN;

    ready = poll(&pollfd, 1, -1);

    if (ready == -1) {

        perror("poll");

        exit(EXIT_FAILURE);

    }

    printf("Events (%#x): POLLIN is %sset\n", pollfd.revents,

           (pollfd.revents & POLLIN) ? "" : "not ");

    close(pidfd);

    exit(EXIT_SUCCESS);
}
```

## SEE ALSO
clone(2), kill(2), pidfd_getfd(2), pidfd_send_signal(2), poll(2), process_madvise(2), select(2), setns(2), waitid(2), epoll(7)


title: pidfd_send_signal(2)

text:
# pidfd_send_signal(2)

## NAME
pidfd_send_signal - send a signal to a process specified by a file descriptor

## LIBRARY
Standard C library (libc, -lc)

## SYNOPSIS

```
#include <linux/signal.h>     /* Definition of SIG* constants */
#include <signal.h>           /* Definition of SI_* constants */
#include <sys/syscall.h>      /* Definition of SYS_* constants */
#include <unistd.h>
```

```
int syscall(SYS_pidfd_send_signal, int pidfd, int sig,
            siginfo_t *_Nullable info, unsigned int flags);
```

Note: glibc provides no wrapper for pidfd_send_signal(), necessitating the use of syscall(2).

## DESCRIPTION
The pidfd_send_signal() system call sends the signal sig to the target process referred to by pidfd, a PID file descriptor that refers to a process.

If the info argument points to a siginfo_t buffer, that buffer should be populated as described in rt_sigqueueinfo(2).

If the info argument is a NULL pointer, this is equivalent to specifying a pointer to a siginfo_t buffer whose fields match the values that are implicitly supplied when a signal is sent using kill(2):

•

si_signo is set to the signal number;

•

si_errno is set to 0;

•

si_code is set to SI_USER;

•

si_pid is set to the caller's PID; and

•

si_uid is set to the caller's real user ID.

The calling process must either be in the same PID namespace as the process referred to by pidfd, or be in an ancestor of that namespace.

The flags argument is reserved for future use; currently, this argument must be specified as 0.

## RETURN VALUE
On success, pidfd_send_signal() returns 0. On error, -1 is returned and errno is set to indicate the error.

## ERRORS
EBADF

pidfd is not a valid PID file descriptor.

EINVAL

sig is not a valid signal.

EINVAL

The calling process is not in a PID namespace from which it can send a signal to the target process.

EINVAL

flags is not 0.

EPERM

The calling process does not have permission to send the signal to the target process.

EPERM

pidfd doesn't refer to the calling process, and info.si_code is invalid (see rt_sigqueueinfo(2)).

ESRCH

The target process does not exist (i.e., it has terminated and been waited on).

## STANDARDS
Linux.

## HISTORY
Linux 5.1.

## NOTES

### PID file descriptors
The pidfd argument is a PID file descriptor, a file descriptor that refers to process. Such a file descriptor can be obtained in any of the following ways:

•

by opening a /proc/pid directory;

•

using pidfd_open(2); or

•

via the PID file descriptor that is returned by a call to clone(2) or clone3(2) that specifies the CLONE_PIDFD flag.

The pidfd_send_signal() system call allows the avoidance of race conditions that occur when using traditional interfaces (such as kill(2)) to signal a process. The problem is that the traditional interfaces specify the target process via a process ID (PID), with the result that the sender may accidentally send a signal to the wrong process if the originally intended target process has terminated and its PID has been recycled for another process. By contrast, a PID file descriptor is a stable reference to a specific process; if that process terminates, pidfd_send_signal() fails with the error ESRCH.

## EXAMPLES

```
#define _GNU_SOURCE
#include <fcntl.h>
#include <limits.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/syscall.h>
#include <unistd.h>
static int
pidfd_send_signal(int pidfd, int sig, siginfo_t *info,

                  unsigned int flags)
{

    return syscall(SYS_pidfd_send_signal, pidfd, sig, info, flags);
}
int
main(int argc, char *argv[])
{

    int        pidfd, sig;

    char       path[PATH_MAX];

    siginfo_t  info;

    if (argc != 3) {

        fprintf(stderr, "Usage: %s <pid> <signal>\n", argv[0]);

        exit(EXIT_FAILURE);

    }

    sig = atoi(argv[2]);

    /* Obtain a PID file descriptor by opening the /proc/PID directory

       of the target process. */

    snprintf(path, sizeof(path), "/proc/%s", argv[1]);

    pidfd = open(path, O_RDONLY);

    if (pidfd == -1) {

        perror("open");

        exit(EXIT_FAILURE);

    }

    /* Populate a 'siginfo_t' structure for use with

       pidfd_send_signal(). */

    memset(&info, 0, sizeof(info));

    info.si_code = SI_QUEUE;

    info.si_signo = sig;

    info.si_errno = 0;

    info.si_uid = getuid();

    info.si_pid = getpid();

    info.si_value.sival_int = 1234;

    /* Send the signal. */

    if (pidfd_send_signal(pidfd, sig, &info, 0) == -1) {

        perror("pidfd_send_signal");

        exit(EXIT_FAILURE);

    }

    exit(EXIT_SUCCESS);
}
```

## SEE ALSO
clone(2), kill(2), pidfd_open(2), rt_sigqueueinfo(2), sigaction(2), pid_namespaces(7), signal(7)


pipe

title: pipe(2)

summary: create pipe

text:
# pipe(2)

## NAME
pipe, pipe2 - create pipe

## LIBRARY
Standard C library (libc, -lc)

## SYNOPSIS

```
#include <unistd.h>
```

```
int pipe(int pipefd[2]);
```

```
#define _GNU_SOURCE             /* See feature_test_macros(7) */
#include <fcntl.h>              /* Definition of O_* constants */
#include <unistd.h>
```

```
int pipe2(int pipefd[2], int flags);
```

```
/* On Alpha, IA-64, MIPS, SuperH, and SPARC/SPARC64, pipe() has the

   following prototype; see VERSIONS */
```

```
#include <unistd.h>
```

```
struct fd_pair {
    long fd[2];
};
struct fd_pair pipe(void);
```

## DESCRIPTION
pipe() creates a pipe, a unidirectional data channel that can be used for interprocess communication. The array pipefd is used to return two file descriptors referring to the ends of the pipe. pipefd[0] refers to the read end of the pipe. pipefd[1] refers to the write end of the pipe. Data written to the write end of the pipe is buffered by the kernel until it is read from the read end of the pipe. For further details, see pipe(7).

If flags is 0, then pipe2() is the same as pipe(). The following values can be bitwise ORed in flags to obtain different behavior:

O_CLOEXEC

Set the close-on-exec (FD_CLOEXEC) flag on the two new file descriptors. See the description of the same flag in open(2) for reasons why this may be useful.

O_DIRECT (since Linux 3.4)

Create a pipe that performs I/O in "packet" mode. Each write(2) to the pipe is dealt with as a separate packet, and read(2)s from the pipe will read one packet at a time. Note the following points:

•

Writes of greater than PIPE_BUF bytes (see pipe(7)) will be split into multiple packets. The constant PIPE_BUF is defined in <limits.h>.

•

If a read(2) specifies a buffer size that is smaller than the next packet, then the requested number of bytes are read, and the excess bytes in the packet are discarded. Specifying a buffer size of PIPE_BUF will be sufficient to read the largest possible packets (see the previous point).

•

Zero-length packets are not supported. (A read(2) that specifies a buffer size of zero is a no-op, and returns 0.)

Older kernels that do not support this flag will indicate this via an EINVAL error.

Since Linux 4.5, it is possible to change the O_DIRECT setting of a pipe file descriptor using fcntl(2).

O_NONBLOCK

Set the O_NONBLOCK file status flag on the open file descriptions referred to by the new file descriptors. Using this flag saves extra calls to fcntl(2) to achieve the same result.

O_NOTIFICATION_PIPE

Since Linux 5.8, general notification mechanism is built on the top of the pipe where kernel splices notification messages into pipes opened by user space. The owner of the pipe has to tell the kernel which sources of events to watch and filters can also be applied to select which subevents should be placed into the pipe.

## RETURN VALUE
On success, zero is returned. On error, -1 is returned, errno is set to indicate the error, and pipefd is left unchanged.

On Linux (and other systems), pipe() does not modify pipefd on failure. A requirement standardizing this behavior was added in POSIX.1-2008 TC2. The Linux-specific pipe2() system call likewise does not modify pipefd on failure.

## ERRORS
EFAULT

pipefd is not valid.

EINVAL

(pipe2()) Invalid value in flags.

EMFILE

The per-process limit on the number of open file descriptors has been reached.

ENFILE

The system-wide limit on the total number of open files has been reached.

ENFILE

The user hard limit on memory that can be allocated for pipes has been reached and the caller is not privileged; see pipe(7).

ENOPKG

(pipe2()) O_NOTIFICATION_PIPE was passed in flags and support for notifications (CONFIG_WATCH_QUEUE) is not compiled into the kernel.

## VERSIONS
The System V ABI on some architectures allows the use of more than one register for returning multiple values; several architectures (namely, Alpha, IA-64, MIPS, SuperH, and SPARC/SPARC64) (ab)use this feature in order to implement the pipe() system call in a functional manner: the call doesn't take any arguments and returns a pair of file descriptors as the return value on success. The glibc pipe() wrapper function transparently deals with this. See syscall(2) for information regarding registers used for storing second file descriptor.

## STANDARDS
pipe()

POSIX.1-2008.

pipe2()

Linux.

## HISTORY
pipe()

POSIX.1-2001.

pipe2()

Linux 2.6.27, glibc 2.9.

## EXAMPLES
The following program creates a pipe, and then fork(2)s to create a child process; the child inherits a duplicate set of file descriptors that refer to the same pipe. After the fork(2), each process closes the file descriptors that it doesn't need for the pipe (see pipe(7)). The parent then writes the string contained in the program's command-line argument to the pipe, and the child reads this string a byte at a time from the pipe and echoes it on standard output.

### Program source

```
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
int
main(int argc, char *argv[])
{

    int    pipefd[2];

    char   buf;

    pid_t  cpid;

    if (argc != 2) {

        fprintf(stderr, "Usage: %s <string>\n", argv[0]);

        exit(EXIT_FAILURE);

    }

    if (pipe(pipefd) == -1) {

        perror("pipe");

        exit(EXIT_FAILURE);

    }

    cpid = fork();

    if (cpid == -1) {

        perror("fork");

        exit(EXIT_FAILURE);

    }

    if (cpid == 0) {    /* Child reads from pipe */

        close(pipefd[1]);          /* Close unused write end */

        while (read(pipefd[0], &buf, 1) > 0)

            write(STDOUT_FILENO, &buf, 1);

        write(STDOUT_FILENO, "\n", 1);

        close(pipefd[0]);

        _exit(EXIT_SUCCESS);

    } else {            /* Parent writes argv[1] to pipe */

        close(pipefd[0]);          /* Close unused read end */

        write(pipefd[1], argv[1], strlen(argv[1]));

        close(pipefd[1]);          /* Reader will see EOF */

        wait(NULL);                /* Wait for child */

        exit(EXIT_SUCCESS);

    }
}
```

## SEE ALSO
fork(2), read(2), socketpair(2), splice(2), tee(2), vmsplice(2), write(2), popen(3), pipe(7)


title: pivot_root(2)

summary: change the root mount

text:
# pivot_root(2)

## NAME
pivot_root - change the root mount

## LIBRARY
Standard C library (libc, -lc)

## SYNOPSIS

```
#include <sys/syscall.h>      /* Definition of SYS_* constants */
#include <unistd.h>
```

```
int syscall(SYS_pivot_root, const char *new_root, const char *put_old);
```

Note: glibc provides no wrapper for pivot_root(), necessitating the use of syscall(2).

## DESCRIPTION
pivot_root() changes the root mount in the mount namespace of the calling process. More precisely, it moves the root mount to the directory put_old and makes new_root the new root mount. The calling process must have the CAP_SYS_ADMIN capability in the user namespace that owns the caller's mount namespace.

pivot_root() changes the root directory and the current working directory of each process or thread in the same mount namespace to new_root if they point to the old root directory. (See also NOTES.) On the other hand, pivot_root() does not change the caller's current working directory (unless it is on the old root directory), and thus it should be followed by a chdir("/") call.

The following restrictions apply:

•

new_root and put_old must be directories.

•

new_root and put_old must not be on the same mount as the current root.

•

put_old must be at or underneath new_root; that is, adding some nonnegative number of "/.." suffixes to the pathname pointed to by put_old must yield the same directory as new_root.

•

new_root must be a path to a mount point, but can't be "/". A path that is not already a mount point can be converted into one by bind mounting the path onto itself.

•

The propagation type of the parent mount of new_root and the parent mount of the current root directory must not be MS_SHARED; similarly, if put_old is an existing mount point, its propagation type must not be MS_SHARED. These restrictions ensure that pivot_root() never propagates any changes to another mount namespace.

•

The current root directory must be a mount point.

## RETURN VALUE
On success, zero is returned. On error, -1 is returned, and errno is set to indicate the error.

## ERRORS
pivot_root() may fail with any of the same errors as stat(2). Additionally, it may fail with the following errors:

EBUSY

new_root or put_old is on the current root mount. (This error covers the pathological case where new_root is "/".)

EINVAL

new_root is not a mount point.

EINVAL

put_old is not at or underneath new_root.

EINVAL

The current root directory is not a mount point (because of an earlier chroot(2)).

EINVAL

The current root is on the rootfs (initial ramfs) mount; see NOTES.

EINVAL

Either the mount point at new_root, or the parent mount of that mount point, has propagation type MS_SHARED.

EINVAL

put_old is a mount point and has the propagation type MS_SHARED.

ENOTDIR

new_root or put_old is not a directory.

EPERM

The calling process does not have the CAP_SYS_ADMIN capability.

## STANDARDS
Linux.

## HISTORY
Linux 2.3.41.

## NOTES
A command-line interface for this system call is provided by pivot_root(8).

pivot_root() allows the caller to switch to a new root filesystem while at the same time placing the old root mount at a location under new_root from where it can subsequently be unmounted. (The fact that it moves all processes that have a root directory or current working directory on the old root directory to the new root frees the old root directory of users, allowing the old root mount to be unmounted more easily.)

One use of pivot_root() is during system startup, when the system mounts a temporary root filesystem (e.g., an initrd(4)), then mounts the real root filesystem, and eventually turns the latter into the root directory of all relevant processes and threads. A modern use is to set up a root filesystem during the creation of a container.

The fact that pivot_root() modifies process root and current working directories in the manner noted in DESCRIPTION is necessary in order to prevent kernel threads from keeping the old root mount busy with their root and current working directories, even if they never access the filesystem in any way.

The rootfs (initial ramfs) cannot be pivot_root()ed. The recommended method of changing the root filesystem in this case is to delete everything in rootfs, overmount rootfs with the new root, attach stdin/stdout/stderr to the new /dev/console, and exec the new init(1). Helper programs for this process exist; see switch_root(8).

### pivot_root(".", ".")
new_root and put_old may be the same directory. In particular, the following sequence allows a pivot-root operation without needing to create and remove a temporary directory:

```
chdir(new_root);
pivot_root(".", ".");
umount2(".", MNT_DETACH);
```

This sequence succeeds because the pivot_root() call stacks the old root mount point on top of the new root mount point at /. At that point, the calling process's root directory and current working directory refer to the new root mount point (new_root). During the subsequent umount() call, resolution of "." starts with new_root and then moves up the list of mounts stacked at /, with the result that old root mount point is unmounted.

### Historical notes
For many years, this manual page carried the following text:

pivot_root() may or may not change the current root and the current working directory of any processes or threads which use the old root directory. The caller of pivot_root() must ensure that processes with root or current working directory at the old root operate correctly in either case. An easy way to ensure this is to change their root and current working directory to new_root before invoking pivot_root().

This text, written before the system call implementation was even finalized in the kernel, was probably intended to warn users at that time that the implementation might change before final release. However, the behavior stated in DESCRIPTION has remained consistent since this system call was first implemented and will not change now.

## EXAMPLES
The program below demonstrates the use of pivot_root() inside a mount namespace that is created using clone(2). After pivoting to the root directory named in the program's first command-line argument, the child created by clone(2) then executes the program named in the remaining command-line arguments.

We demonstrate the program by creating a directory that will serve as the new root filesystem and placing a copy of the (statically linked) busybox(1) executable in that directory.

```
$ mkdir /tmp/rootfs
$ ls -id /tmp/rootfs    # Show inode number of new root directory
319459 /tmp/rootfs
$ cp $(which busybox) /tmp/rootfs
$ PS1='bbsh$ ' sudo ./pivot_root_demo /tmp/rootfs /busybox sh
bbsh$ PATH=/
bbsh$ busybox ln busybox ln
bbsh$ ln busybox echo
bbsh$ ln busybox ls
bbsh$ ls
busybox  echo     ln       ls
bbsh$ ls -id /          # Compare with inode number above
319459 /
bbsh$ echo 'hello world'
hello world
```

### Program source

```
/* pivot_root_demo.c */
#define _GNU_SOURCE
#include <err.h>
#include <limits.h>
#include <sched.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/wait.h>
#include <unistd.h>
static int
pivot_root(const char *new_root, const char *put_old)
{

    return syscall(SYS_pivot_root, new_root, put_old);
}
#define STACK_SIZE (1024 * 1024)
static int              /* Startup function for cloned child */
child(void *arg)
{

    char        path[PATH_MAX];

    char        **args = arg;

    char        *new_root = args[0];

    const char  *put_old = "/oldrootfs";

    /* Ensure that 'new_root' and its parent mount don't have

       shared propagation (which would cause pivot_root() to

       return an error), and prevent propagation of mount

       events to the initial mount namespace. */

    if (mount(NULL, "/", NULL, MS_REC | MS_PRIVATE, NULL) == -1)

        err(EXIT_FAILURE, "mount-MS_PRIVATE");

    /* Ensure that 'new_root' is a mount point. */

    if (mount(new_root, new_root, NULL, MS_BIND, NULL) == -1)

        err(EXIT_FAILURE, "mount-MS_BIND");

    /* Create directory to which old root will be pivoted. */

    snprintf(path, sizeof(path), "%s/%s", new_root, put_old);

    if (mkdir(path, 0777) == -1)

        err(EXIT_FAILURE, "mkdir");

    /* And pivot the root filesystem. */

    if (pivot_root(new_root, path) == -1)

        err(EXIT_FAILURE, "pivot_root");

    /* Switch the current working directory to "/". */

    if (chdir("/") == -1)

        err(EXIT_FAILURE, "chdir");

    /* Unmount old root and remove mount point. */

    if (umount2(put_old, MNT_DETACH) == -1)

        perror("umount2");

    if (rmdir(put_old) == -1)

        perror("rmdir");

    /* Execute the command specified in argv[1]... */

    execv(args[1], &args[1]);

    err(EXIT_FAILURE, "execv");
}
int
main(int argc, char *argv[])
{

    char *stack;

    /* Create a child process in a new mount namespace. */

    stack = mmap(NULL, STACK_SIZE, PROT_READ | PROT_WRITE,

                 MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0);

    if (stack == MAP_FAILED)

        err(EXIT_FAILURE, "mmap");

    if (clone(child, stack + STACK_SIZE,

              CLONE_NEWNS | SIGCHLD, &argv[1]) == -1)

        err(EXIT_FAILURE, "clone");

    /* Parent falls through to here; wait for child. */

    if (wait(NULL) == -1)

        err(EXIT_FAILURE, "wait");

    exit(EXIT_SUCCESS);
}
```

## SEE ALSO
chdir(2), chroot(2), mount(2), stat(2), initrd(4), mount_namespaces(7), pivot_root(8), switch_root(8)


title: pkey_alloc(2)

summary: allocate or free a protection key

text:
# pkey_alloc(2)

## NAME
pkey_alloc, pkey_free - allocate or free a protection key

## LIBRARY
Standard C library (libc, -lc)

## SYNOPSIS

```
#define _GNU_SOURCE             /* See feature_test_macros(7) */
#include <sys/mman.h>
```

```
int pkey_alloc(unsigned int flags, unsigned int access_rights);
int pkey_free(int pkey);
```

## DESCRIPTION
pkey_alloc() allocates a protection key (pkey) and allows it to be passed to pkey_mprotect(2).

The pkey_alloc() flags is reserved for future use and currently must always be specified as 0.

The pkey_alloc() access_rights argument may contain zero or more disable operations:

PKEY_DISABLE_ACCESS

Disable all data access to memory covered by the returned protection key.

PKEY_DISABLE_WRITE

Disable write access to memory covered by the returned protection key.

pkey_free() frees a protection key and makes it available for later allocations. After a protection key has been freed, it may no longer be used in any protection-key-related operations.

An application should not call pkey_free() on any protection key which has been assigned to an address range by pkey_mprotect(2) and which is still in use. The behavior in this case is undefined and may result in an error.

## RETURN VALUE
On success, pkey_alloc() returns a positive protection key value. On success, pkey_free() returns zero. On error, -1 is returned, and errno is set to indicate the error.

## ERRORS
EINVAL

pkey, flags, or access_rights is invalid.

ENOSPC

(pkey_alloc()) All protection keys available for the current process have been allocated. The number of keys available is architecture-specific and implementation-specific and may be reduced by kernel-internal use of certain keys. There are currently 15 keys available to user programs on x86.

This error will also be returned if the processor or operating system does not support protection keys. Applications should always be prepared to handle this error, since factors outside of the application's control can reduce the number of available pkeys.

## STANDARDS
Linux.

## HISTORY
Linux 4.9, glibc 2.27.

## NOTES
pkey_alloc() is always safe to call regardless of whether or not the operating system supports protection keys. It can be used in lieu of any other mechanism for detecting pkey support and will simply fail with the error ENOSPC if the operating system has no pkey support.

The kernel guarantees that the contents of the hardware rights register (PKRU) will be preserved only for allocated protection keys. Any time a key is unallocated (either before the first call returning that key from pkey_alloc() or after it is freed via pkey_free()), the kernel may make arbitrary changes to the parts of the rights register affecting access to that key.

## EXAMPLES
See pkeys(7).

## SEE ALSO
pkey_mprotect(2), pkeys(7)


poll

title: poll(2)

text:
# poll(2)

## NAME
poll, ppoll - wait for some event on a file descriptor

## LIBRARY
Standard C library (libc, -lc)

## SYNOPSIS

```
#include <poll.h>
```

```
int poll(struct pollfd *fds, nfds_t nfds, int timeout);
```

```
#define _GNU_SOURCE         /* See feature_test_macros(7) */
#include <poll.h>
```

```
int ppoll(struct pollfd *fds, nfds_t nfds,
          const struct timespec *_Nullable tmo_p,
          const sigset_t *_Nullable sigmask);
```

## DESCRIPTION
poll() performs a similar task to select(2): it waits for one of a set of file descriptors to become ready to perform I/O. The Linux-specific epoll(7) API performs a similar task, but offers features beyond those found in poll().

The set of file descriptors to be monitored is specified in the fds argument, which is an array of structures of the following form:

```
struct pollfd {

    int   fd;         /* file descriptor */

    short events;     /* requested events */

    short revents;    /* returned events */
};
```

The caller should specify the number of items in the fds array in nfds.

The field fd contains a file descriptor for an open file. If this field is negative, then the corresponding events field is ignored and the revents field returns zero. (This provides an easy way of ignoring a file descriptor for a single poll() call: simply set the fd field to its bitwise complement.)

The field events is an input parameter, a bit mask specifying the events the application is interested in for the file descriptor fd. This field may be specified as zero, in which case the only events that can be returned in revents are POLLHUP, POLLERR, and POLLNVAL (see below).

The field revents is an output parameter, filled by the kernel with the events that actually occurred. The bits returned in revents can include any of those specified in events, or one of the values POLLERR, POLLHUP, or POLLNVAL. (These three bits are meaningless in the events field, and will be set in the revents field whenever the corresponding condition is true.)

If none of the events requested (and no error) has occurred for any of the file descriptors, then poll() blocks until one of the events occurs.

The timeout argument specifies the number of milliseconds that poll() should block waiting for a file descriptor to become ready. The call will block until either:

•

a file descriptor becomes ready;

•

the call is interrupted by a signal handler; or

•

the timeout expires.

Being "ready" means that the requested operation will not block; thus, poll()ing regular files, block devices, and other files with no reasonable polling semantic always returns instantly as ready to read and write.

Note that the timeout interval will be rounded up to the system clock granularity, and kernel scheduling delays mean that the blocking interval may overrun by a small amount. Specifying a negative value in timeout means an infinite timeout. Specifying a timeout of zero causes poll() to return immediately, even if no file descriptors are ready.

The bits that may be set/returned in events and revents are defined in <poll.h>:

POLLIN

There is data to read.

POLLPRI

There is some exceptional condition on the file descriptor. Possibilities include:

•

There is out-of-band data on a TCP socket (see tcp(7)).

•

A pseudoterminal master in packet mode has seen a state change on the slave (see ioctl_tty(2)).

•

A cgroup.events file has been modified (see cgroups(7)).

POLLOUT

Writing is now possible, though a write larger than the available space in a socket or pipe will still block (unless O_NONBLOCK is set).

POLLRDHUP (since Linux 2.6.17)

Stream socket peer closed connection, or shut down writing half of connection. The _GNU_SOURCE feature test macro must be defined (before including any header files) in order to obtain this definition.

POLLERR

Error condition (only returned in revents; ignored in events). This bit is also set for a file descriptor referring to the write end of a pipe when the read end has been closed.

POLLHUP

Hang up (only returned in revents; ignored in events). Note that when reading from a channel such as a pipe or a stream socket, this event merely indicates that the peer closed its end of the channel. Subsequent reads from the channel will return 0 (end of file) only after all outstanding data in the channel has been consumed.

POLLNVAL

Invalid request: fd not open (only returned in revents; ignored in events).

When compiling with _XOPEN_SOURCE defined, one also has the following, which convey no further information beyond the bits listed above:

POLLRDNORM

Equivalent to POLLIN.

POLLRDBAND

Priority band data can be read (generally unused on Linux).

POLLWRNORM

Equivalent to POLLOUT.

POLLWRBAND

Priority data may be written.

Linux also knows about, but does not use POLLMSG.

### ppoll()
The relationship between poll() and ppoll() is analogous to the relationship between select(2) and pselect(2): like pselect(2), ppoll() allows an application to safely wait until either a file descriptor becomes ready or until a signal is caught.

Other than the difference in the precision of the timeout argument, the following ppoll() call:

```
ready = ppoll(&fds, nfds, tmo_p, &sigmask);
```

is nearly equivalent to atomically executing the following calls:

```
sigset_t origmask;
int timeout;
timeout = (tmo_p == NULL) ? -1 :

          (tmo_p->tv_sec * 1000 + tmo_p->tv_nsec / 1000000);
pthread_sigmask(SIG_SETMASK, &sigmask, &origmask);
ready = poll(&fds, nfds, timeout);
pthread_sigmask(SIG_SETMASK, &origmask, NULL);
```

The above code segment is described as nearly equivalent because whereas a negative timeout value for poll() is interpreted as an infinite timeout, a negative value expressed in *tmo_p results in an error from ppoll().

See the description of pselect(2) for an explanation of why ppoll() is necessary.

If the sigmask argument is specified as NULL, then no signal mask manipulation is performed (and thus ppoll() differs from poll() only in the precision of the timeout argument).

The tmo_p argument specifies an upper limit on the amount of time that ppoll() will block. This argument is a pointer to a timespec(3) structure.

If tmo_p is specified as NULL, then ppoll() can block indefinitely.

## RETURN VALUE
On success, poll() returns a nonnegative value which is the number of elements in the pollfds whose revents fields have been set to a nonzero value (indicating an event or an error). A return value of zero indicates that the system call timed out before any file descriptors became ready.

On error, -1 is returned, and errno is set to indicate the error.

## ERRORS
EFAULT

fds points outside the process's accessible address space. The array given as argument was not contained in the calling program's address space.

EINTR

A signal occurred before any requested event; see signal(7).

EINVAL

The nfds value exceeds the RLIMIT_NOFILE value.

EINVAL

(ppoll()) The timeout value expressed in *tmo_p is invalid (negative).

ENOMEM

Unable to allocate memory for kernel data structures.

## VERSIONS
On some other UNIX systems, poll() can fail with the error EAGAIN if the system fails to allocate kernel-internal resources, rather than ENOMEM as Linux does. POSIX permits this behavior. Portable programs may wish to check for EAGAIN and loop, just as with EINTR.

Some implementations define the nonstandard constant INFTIM with the value -1 for use as a timeout for poll(). This constant is not provided in glibc.

### C library/kernel differences
The Linux ppoll() system call modifies its tmo_p argument. However, the glibc wrapper function hides this behavior by using a local variable for the timeout argument that is passed to the system call. Thus, the glibc ppoll() function does not modify its tmo_p argument.

The raw ppoll() system call has a fifth argument, size_t sigsetsize, which specifies the size in bytes of the sigmask argument. The glibc ppoll() wrapper function specifies this argument as a fixed value (equal to sizeof(kernel_sigset_t)). See sigprocmask(2) for a discussion on the differences between the kernel and the libc notion of the sigset.

## STANDARDS
poll()

POSIX.1-2008.

ppoll()

Linux.

## HISTORY
poll()

POSIX.1-2001. Linux 2.1.23.

On older kernels that lack this system call, the glibc poll() wrapper function provides emulation using select(2).

ppoll()

Linux 2.6.16, glibc 2.4.

## NOTES
The operation of poll() and ppoll() is not affected by the O_NONBLOCK flag.

For a discussion of what may happen if a file descriptor being monitored by poll() is closed in another thread, see select(2).

## BUGS
See the discussion of spurious readiness notifications under the BUGS section of select(2).

## EXAMPLES
The program below opens each of the files named in its command-line arguments and monitors the resulting file descriptors for readiness to read (POLLIN). The program loops, repeatedly using poll() to monitor the file descriptors, printing the number of ready file descriptors on return. For each ready file descriptor, the program:

•

displays the returned revents field in a human-readable form;

•

if the file descriptor is readable, reads some data from it, and displays that data on standard output; and

•

if the file descriptor was not readable, but some other event occurred (presumably POLLHUP), closes the file descriptor.

Suppose we run the program in one terminal, asking it to open a FIFO:

```
$ mkfifo myfifo
$ ./poll_input myfifo
```

In a second terminal window, we then open the FIFO for writing, write some data to it, and close the FIFO:

```
$ echo aaaaabbbbbccccc > myfifo
```

In the terminal where we are running the program, we would then see:

```
Opened "myfifo" on fd 3
About to poll()
Ready: 1

  fd=3; events: POLLIN POLLHUP

    read 10 bytes: aaaaabbbbb
About to poll()
Ready: 1

  fd=3; events: POLLIN POLLHUP

    read 6 bytes: ccccc
About to poll()
Ready: 1

  fd=3; events: POLLHUP

    closing fd 3
All file descriptors closed; bye
```

In the above output, we see that poll() returned three times:

•

On the first return, the bits returned in the revents field were POLLIN, indicating that the file descriptor is readable, and POLLHUP, indicating that the other end of the FIFO has been closed. The program then consumed some of the available input.

•

The second return from poll() also indicated POLLIN and POLLHUP; the program then consumed the last of the available input.

•

On the final return, poll() indicated only POLLHUP on the FIFO, at which point the file descriptor was closed and the program terminated.

### Program source

```
/* poll_input.c

   Licensed under GNU General Public License v2 or later.
*/
#include <fcntl.h>
#include <poll.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define errExit(msg)    do { perror(msg); exit(EXIT_FAILURE); \

                        } while (0)
int
main(int argc, char *argv[])
{

    int            ready;

    char           buf[10];

    nfds_t         num_open_fds, nfds;

    ssize_t        s;

    struct pollfd  *pfds;

    if (argc < 2) {

       fprintf(stderr, "Usage: %s file...\n", argv[0]);

       exit(EXIT_FAILURE);

    }

    num_open_fds = nfds = argc - 1;

    pfds = calloc(nfds, sizeof(struct pollfd));

    if (pfds == NULL)

        errExit("malloc");

    /* Open each file on command line, and add it to 'pfds' array. */

    for (nfds_t j = 0; j < nfds; j++) {

        pfds[j].fd = open(argv[j + 1], O_RDONLY);

        if (pfds[j].fd == -1)

            errExit("open");

        printf("Opened \"%s\" on fd %d\n", argv[j + 1], pfds[j].fd);

        pfds[j].events = POLLIN;

    }

    /* Keep calling poll() as long as at least one file descriptor is

       open. */

    while (num_open_fds > 0) {

        printf("About to poll()\n");

        ready = poll(pfds, nfds, -1);

        if (ready == -1)

            errExit("poll");

        printf("Ready: %d\n", ready);

        /* Deal with array returned by poll(). */

        for (nfds_t j = 0; j < nfds; j++) {

            if (pfds[j].revents != 0) {

                printf("  fd=%d; events: %s%s%s\n", pfds[j].fd,

                       (pfds[j].revents & POLLIN)  ? "POLLIN "  : "",

                       (pfds[j].revents & POLLHUP) ? "POLLHUP " : "",

                       (pfds[j].revents & POLLERR) ? "POLLERR " : "");

                if (pfds[j].revents & POLLIN) {

                    s = read(pfds[j].fd, buf, sizeof(buf));

                    if (s == -1)

                        errExit("read");

                    printf("    read %zd bytes: %.*s\n",

                           s, (int) s, buf);

                } else {                /* POLLERR | POLLHUP */

                    printf("    closing fd %d\n", pfds[j].fd);

                    if (close(pfds[j].fd) == -1)

                        errExit("close");

                    num_open_fds--;

                }

            }

        }

    }

    printf("All file descriptors closed; bye\n");

    exit(EXIT_SUCCESS);
}
```

## SEE ALSO
restart_syscall(2), select(2), select_tut(2), timespec(3), epoll(7), time(7)


title: posix_fadvise(2)

text:
# posix_fadvise(2)

## NAME
posix_fadvise - predeclare an access pattern for file data

## LIBRARY
Standard C library (libc, -lc)

## SYNOPSIS

```
#include <fcntl.h>
```

```
int posix_fadvise(int fd, off_t offset, off_t len, int advice);
```

Feature Test Macro Requirements for glibc (see feature_test_macros(7)):

posix_fadvise():

```
    _POSIX_C_SOURCE >= 200112L
```

## DESCRIPTION
Programs can use posix_fadvise() to announce an intention to access file data in a specific pattern in the future, thus allowing the kernel to perform appropriate optimizations.

The advice applies to a (not necessarily existent) region starting at offset and extending for len bytes (or until the end of the file if len is 0) within the file referred to by fd. The advice is not binding; it merely constitutes an expectation on behalf of the application.

Permissible values for advice include:

POSIX_FADV_NORMAL

Indicates that the application has no advice to give about its access pattern for the specified data. If no advice is given for an open file, this is the default assumption.

POSIX_FADV_SEQUENTIAL

The application expects to access the specified data sequentially (with lower offsets read before higher ones).

POSIX_FADV_RANDOM

The specified data will be accessed in random order.

POSIX_FADV_NOREUSE

The specified data will be accessed only once.

Before Linux 2.6.18, POSIX_FADV_NOREUSE had the same semantics as POSIX_FADV_WILLNEED. This was probably a bug; since Linux 2.6.18, this flag is a no-op.

POSIX_FADV_WILLNEED

The specified data will be accessed in the near future.

POSIX_FADV_WILLNEED initiates a nonblocking read of the specified region into the page cache. The amount of data read may be decreased by the kernel depending on virtual memory load. (A few megabytes will usually be fully satisfied, and more is rarely useful.)

POSIX_FADV_DONTNEED

The specified data will not be accessed in the near future.

POSIX_FADV_DONTNEED attempts to free cached pages associated with the specified region. This is useful, for example, while streaming large files. A program may periodically request the kernel to free cached data that has already been used, so that more useful cached pages are not discarded instead.

Requests to discard partial pages are ignored. It is preferable to preserve needed data than discard unneeded data. If the application requires that data be considered for discarding, then offset and len must be page-aligned.

The implementation may attempt to write back dirty pages in the specified region, but this is not guaranteed. Any unwritten dirty pages will not be freed. If the application wishes to ensure that dirty pages will be released, it should call fsync(2) or fdatasync(2) first.

## RETURN VALUE
On success, zero is returned. On error, an error number is returned.

## ERRORS
EBADF

The fd argument was not a valid file descriptor.

EINVAL

An invalid value was specified for advice.

ESPIPE

The specified file descriptor refers to a pipe or FIFO. (ESPIPE is the error specified by POSIX, but before Linux 2.6.16, Linux returned EINVAL in this case.)

## VERSIONS
Under Linux, POSIX_FADV_NORMAL sets the readahead window to the default size for the backing device; POSIX_FADV_SEQUENTIAL doubles this size, and POSIX_FADV_RANDOM disables file readahead entirely. These changes affect the entire file, not just the specified region (but other open file handles to the same file are unaffected).

### C library/kernel differences
The name of the wrapper function in the C library is posix_fadvise(). The underlying system call is called fadvise64() (or, on some architectures, fadvise64_64()); the difference between the two is that the former system call assumes that the type of the len argument is size_t, while the latter expects loff_t there.

### Architecture-specific variants
Some architectures require 64-bit arguments to be aligned in a suitable pair of registers (see syscall(2) for further detail). On such architectures, the call signature of posix_fadvise() shown in the SYNOPSIS would force a register to be wasted as padding between the fd and offset arguments. Therefore, these architectures define a version of the system call that orders the arguments suitably, but is otherwise exactly the same as posix_fadvise().

For example, since Linux 2.6.14, ARM has the following system call:

```
long arm_fadvise64_64(int fd, int advice,
                      loff_t offset, loff_t len);
```

These architecture-specific details are generally hidden from applications by the glibc posix_fadvise() wrapper function, which invokes the appropriate architecture-specific system call.

## STANDARDS
POSIX.1-2008.

## HISTORY
POSIX.1-2001.

Kernel support first appeared in Linux 2.5.60; the underlying system call is called fadvise64(). Library support has been provided since glibc 2.2, via the wrapper function posix_fadvise().

Since Linux 3.18, support for the underlying system call is optional, depending on the setting of the CONFIG_ADVISE_SYSCALLS configuration option.

The type of the len argument was changed from size_t to off_t in POSIX.1-2001 TC1.

## NOTES
The contents of the kernel buffer cache can be cleared via the /proc/sys/vm/drop_caches interface described in proc(5).

One can obtain a snapshot of which pages of a file are resident in the buffer cache by opening a file, mapping it with mmap(2), and then applying mincore(2) to the mapping.

## BUGS
Before Linux 2.6.6, if len was specified as 0, then this was interpreted literally as "zero bytes", rather than as meaning "all bytes through to the end of the file".

## SEE ALSO
fincore(1), mincore(2), readahead(2), sync_file_range(2), posix_fallocate(3), posix_madvise(3)