Repository: SerenityOS/serenity
File: Userland/Libraries/LibC/spawn.cpp (C++)

Code before:
    posix_spawn_params.environment.strings = envp_string_args.is_empty() ? nullptr : envp_string_args.data();
    posix_spawn_params.environment.length = envp_string_args.size();

    posix_spawn_params.attr_data = nullptr;
    posix_spawn_params.attr_data_size = 0;

    posix_spawn_params.serialized_file_actions_data = nullptr;
    posix_spawn_params.serialized_file_actions_data_size = 0;

    pid_t child_pid = syscall(SC_posix_spawn, &posix_spawn_params);

    if (child_pid < 0) {
        // syscall will set errno
        return errno;
    }

    if (out_pid)
        *out_pid = child_pid;
    return 0;
}

// https://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_spawn.html
int posix_spawn(pid_t* out_pid, char const* path, posix_spawn_file_actions_t const* file_actions, posix_spawnattr_t const* attr, char* const argv[], char* const envp[])
{
    // If we file_actions and spawnattr are nulled, call efficient posix_spawn syscall; otherwise, default to fork() + exec() libc wrapper
    if (!file_actions and !attr) {
        posix_spawn_syscall(out_pid, path, argv, envp);
        return 0;
    }

    pid_t child_pid = fork();
    if (child_pid < 0)
        return errno;

    if (child_pid != 0) {
        *out_pid = child_pid;
        return 0;
    }

    posix_spawn_child(path, file_actions, attr, argv, envp, execve);
}

// https://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_spawnp.html
int posix_spawnp(pid_t* out_pid, char const* file, posix_spawn_file_actions_t const* file_actions, posix_spawnattr_t const* attr, char* const argv[], char* const envp[])
{
    pid_t child_pid = fork();
    if (child_pid < 0)
        return errno;

    if (child_pid != 0) {
        *out_pid = child_pid;

Review comment (suggestion):
Please don't use [alternative operator representations](https://en.cppreference.com/w/cpp/language/operator_alternative.html).

Code after:
int posix_spawn(pid_t* out_pid, char const* path, posix_spawn_file_actions_t const* file_actions, posix_spawnattr_t const* attr, char* const argv[], char* const envp[])
{
    // FIXME: Support file_actions and spawnattr in the posix_spawn syscall.
    if (!file_actions && !attr) {
        auto child_pid_or_error = posix_spawn_syscall(path, argv, envp);
        if (child_pid_or_error.is_error())
            return child_pid_or_error.error().code();

        if (out_pid)
            *out_pid = child_pid_or_error.value();
        return 0;
    }

    pid_t child_pid = fork();
    if (child_pid < 0)
        return errno;

    if (child_pid != 0) {
        *out_pid = child_pid;
        return 0;
    }

    posix_spawn_child(path, file_actions, attr, argv, envp, execve);
}

// https://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_spawnp.html
int posix_spawnp(pid_t* out_pid, char const* file, posix_spawn_file_actions_t const* file_actions, posix_spawnattr_t const* attr, char* const argv[], char* const envp[])
{
    // FIXME: Use the posix_spawn syscall here.

    pid_t child_pid = fork();
    if (child_pid < 0)
        return errno;

    if (child_pid != 0) {
        *out_pid = child_pid;
        return 0;
    }

    posix_spawn_child(file, file_actions, attr, argv, envp, execvpe);
}

// https://pubs.opengroup.org/onlinepubs/9699919799/functions/posix_spawn_file_actions_addchdir.html
int posix_spawn_file_actions_addchdir(posix_spawn_file_actions_t* actions, char const* path)
{
    actions->state->actions.append([path]() { return chdir(path); });
    return 0;
}

int posix_spawn_file_actions_addfchdir(posix_spawn_file_actions_t* actions, int fd)
{