POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR(3)

πŸ“¦ version 15.1, in freebsd 15.1

πŸ’… POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR(3) β€” Library Functions Manual, but make it make sense

okay bestie, so this is a libc page (yes, from the Standard C Library, -lc), and it's actually a whole squad of functions that all do the same kind of thing: they queue up little file actions for a future posix_spawn()-y child process. The heading up top says addchdir because that's the star of the show, but ngl the whole friend group shows up here. Let's go. πŸŽ€


✨ NAME ✨

posix_spawn_file_actions_addopen, posix_spawn_file_actions_adddup2, posix_spawn_file_actions_addclose, posix_spawn_file_actions_addclosefrom_np, posix_spawn_file_actions_addchdir, posix_spawn_file_actions_addfchdir β€” they add open, dup2, close, closefrom, or chdir/fchdir actions to a spawn file actions object, which is a whole mood. πŸ’…

πŸ“š LIBRARY πŸ“š

Standard C Library (libc, -lc) β€” the classic, the icon, the one you're already linking against.

🧾 SYNOPSIS 🧾

#include <spawn.h>

int
posix_spawn_file_actions_addopen(posix_spawn_file_actions_t * file_actions,
    int fildes, const char *restrict path, int oflag, mode_t mode);

int
posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t * file_actions,
    int fildes, int newfildes);

int
posix_spawn_file_actions_addclose(posix_spawn_file_actions_t * file_actions,
    int fildes);

int
posix_spawn_file_actions_addclosefrom_np(posix_spawn_file_actions_t * file_actions,
    int from);

int
posix_spawn_file_actions_addchdir(posix_spawn_file_actions_t *restrict file_actions,
    const char *restrict path);

int
posix_spawn_file_actions_addfchdir(posix_spawn_file_actions_t * file_actions,
    int fildes);

🌸 DESCRIPTION 🌸

So here's the vibe: these functions add an open, dup2 or close action to a spawn file actions object. That's a posix_spawn_file_actions_t, defined in <spawn.h>, and it's basically a little to-do list you hand to posix_spawn() or posix_spawnp() so it knows how to get from your open file descriptors to the set of open file descriptors the child process should end up with. Slay. πŸ”₯

When you pass that object to posix_spawn() or posix_spawnp(), it specifies how the calling process's set of open file descriptors gets transformed into a set of potentially open file descriptors for the spawned process. The transformation is as if the specified sequence of actions was performed exactly once, in the context of the spawned process (before the new process image is executed, okurrr), in the order you added them to the object. And on top of that β€” when the new process image is executed, any file descriptor from this new set that has its FD_CLOEXEC flag set gets closed (see posix_spawn()). Periodt. πŸ’€


🫢 the addopen one

posix_spawn_file_actions_addopen() adds an open action to the object referenced by file_actions that causes the file named by path to be opened (as if

open(path, oflag, mode)

had been called, and the returned file descriptor, if not fildes, had been changed to fildes) when a new process is spawned using this file actions object. And if fildes was already an open file descriptor? It gets closed before the new file is opened. Clean slate energy. ✨

The string described by path is copied by posix_spawn_file_actions_addopen() β€” so yes, it's safely duplicated for you. πŸ’œ

πŸ¦‹ the adddup2 one

posix_spawn_file_actions_adddup2() adds a dup2 action to the object referenced by file_actions that causes the file descriptor fildes to be duplicated as newfildes (as if

dup2(fildes, newfildes)

had been called) when a new process is spawned using this file actions object β€” except that the FD_CLOEXEC flag for newfildes is cleared even if fildes is equal to newfildes. That difference from plain dup2() is genuinely useful for passing a particular file descriptor to a particular child process. iykyk. πŸ‘‘

πŸ“ the addclose one

posix_spawn_file_actions_addclose() adds a close action to the object referenced by file_actions that causes the file descriptor fildes to be closed (as if

close(fildes)

had been called) when a new process is spawned using this file actions object.

🧚 the addclosefrom_np one (the mass-close, non-standard girlie)

posix_spawn_file_actions_addclosefrom_np() adds a close action to close all file descriptors numerically equal or greater then the argument from. (Yes, that's "then" β€” I'm keeping it exactly as the page says, no cap.) For each open file descriptor, logically the close action is performed, and any possible errors encountered are ignored. We simply do not perceive them. πŸ™ˆ

🌈 the chdir / fchdir ones (the reason we're all here)

posix_spawn_file_actions_addchdir() and posix_spawn_file_actions_addfchdir() add a change current directory action to the object referenced by file_actions that affects actions (opens with a relative path) performed after the operation, in the order of insertion into the file_actions object. It also sets the working directory for the spawned program. πŸ“‚

posix_spawn_file_actions_addchdir() takes the path to set as the working directory, while posix_spawn_file_actions_addfchdir() takes the directory file descriptor (fildes). Main character energy, both of them. πŸŽ€


πŸ’– RETURN VALUES πŸ’–

Upon successful completion, these functions return zero. Otherwise, an error number is returned to indicate the error. That's it, that's the whole contract, bestie.

😭 ERRORS 😭

These functions fail if:

  • [EBADF] β€” The value specified by fildes or newfildes is negative. (Negative fds are not a slay, they're a no.)
  • [ENOMEM] β€” Insufficient memory exists to add to the spawn file actions object. The object said "I'm full, babe."

πŸ‘€ SEE ALSO πŸ‘€

close(2), dup2(2), open(2), posix_spawn(3), posix_spawn_file_actions_destroy(3), posix_spawn_file_actions_init(3), posix_spawnp(3) β€” go read the whole friend group, fr fr.

πŸ›οΈ STANDARDS πŸ›οΈ

posix_spawn_file_actions_addopen(), posix_spawn_file_actions_adddup2() and posix_spawn_file_actions_addclose() conform to IEEE Std 1003.1-2001 (β€œPOSIX.1”), with the exception of the behavior of posix_spawn_file_actions_adddup2() if fildes is equal to newfildes (that's the clearing FD_CLOEXEC thing). A future update of the Standard is expected to require this behavior β€” so like, we're early. Trendsetters. ⭐

posix_spawn_file_actions_addclosefrom_np() is non-standard and implemented after the similar functionality provided by glibc. The _np is right there in the name, bestie β€” don't @ me.

πŸ“œ HISTORY πŸ“œ

  • posix_spawn_file_actions_addopen(), posix_spawn_file_actions_adddup2() and posix_spawn_file_actions_addclose() first appeared in FreeBSD 8.0.
  • posix_spawn_file_actions_addchdir_np(), posix_spawn_file_actions_addfchdir_np(), and posix_spawn_file_actions_addclosefrom_np() first appeared in FreeBSD 13.1.
  • In FreeBSD 16.0, the posix_spawn_file_actions_addchdir(), posix_spawn_file_actions_addfchdir() aliases where added to the corresponding functions with the β€˜_np’ suffix.
That "where" in the last line is the manpage's own typo, not mine β€” I refuse to gaslight the historical record. πŸ’€

✍️ AUTHORS ✍️

Ed Schouten <ed@FreeBSD.org> β€” thank you for your service, king. πŸ‘‘


and that's the page!! 🫢 Debian shipped this one, dated May 9, 201 (that's literally what the footer says, the year got cut off mid-slide, iconic honestly), and the footer page name is POSIX_SPAWN_FILE_ACTIONS_ADDOPEN(3) β€” yes, the header and footer disagree about which function the page is named after, and we love that for them. bye bestie, go spawn something responsibly πŸ’–βœ¨

πŸ“¦ where this page comes from
  • freebsd 15.1: base 15.1
  • πŸ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms