I have some code that's using posix_spawnp(3) to create a new process. I want to set the child's stdin to read from a certain file descriptor so before the posix_spawnp() call I'm setting up a dup2 file action:
ret = posix_spawn_file_actions_adddup2(&file_actions, fd_for_stdin, 0);
Then I have no more use for fd_for_stdin in the child process so I believe I should close it. To achieve that is there a difference between adding a call to posix_spawn_file_actions_addclose(3) versus adding a call to fcntl(2) to set FD_CLOEXEC? My understanding is that these two code snippets (error checking omitted) should have the same result - is that right, or am I missing something?
posix_spawn_file_actions_adddup2(&file_actions, fd_for_stdin, STDIN_FILENO);
posix_spawn_file_actions_addclose(&file_actions, fd_for_stdin);
posix_spawnp(..., &file_actions, ...);
Versus:
posix_spawn_file_actions_adddup2(&file_actions, fd_for_stdin, STDIN_FILENO);
fcntl(fd_for_stdin, F_SETFD, FD_CLOEXEC);
posix_spawnp(..., &file_actions, ...);
The spec of
posix_spawnp()says:There's nothing in the description of the close action that suggests that it does anything different from the
FD_CLOEXECflag. In both cases they just close the descriptor when spawning.However, using
posix_spawn_file_actions_addclose()gives you control over precisely when the descriptor is closed, since the file actions are performed in the order that they're added, whileFD_CLEXECis always processed last.