View Issue Details

IDProjectCategoryView StatusLast Update
00019351003.1(2024)/Issue8System Interfacespublic2025-08-07 10:27
Reportercorinna_vinschen Assigned Togeoffclare  
PrioritynormalSeverityEditorialTypeClarification Requested
Status AppliedResolutionAccepted As Marked 
NameCorinna Vinschen
OrganizationCygwin Project
User Reference
Sectionposix_spawn_file_actions_addchdir, posix_spawn_file_actions_addclose
Page Number1590 - 1592
Line Number53472 - 53473, 53480 - 53481, 53516 - 53518
Interp Status---
Final Accepted Text0001935:0007229
Summary0001935: posix_spawn file actions: in the context of the child or "as if" in the context of the child?
DescriptionRight now, Cygwin uses fork/execve to implement posix_spawn(). This is
wasteful, because fork() on Windows OS requires to create a copy of a
process using a spawn-like OS call CreateProcess() and then overriding
process memory until the child resembles a forked parent.

So we're currently trying to implement posix_spawn() with just a single
CreateProcess() call to make posix_spawn() perform better than fork()/
execve().

Our problem: We do NOT have any OS call which creates a shallow child
process like Linux' clone3 call or BSD vfork(). We either have to run
file actions for the child in the parent, or in the fully created child
process before calling main().

The documentation of posix_spawn_file_actions_addchdir() has this to say:

  [...] all file actions are processed in sequence *** in the context of
  the child *** at a point where the child process is still
  single-threaded.
  [...]
  File actions are performed *** in a new process *** created by
  posix_spawn() or posix_spawnp() in the same order that they were added
  to the file actions object.

So, there's a clear message that the file actions are to be performed in
the child.

However, if we *have* to run the file actions in the child process, we
have a few problems, at least:

- O_CLOEXEC descriptors are never seen by the child process. So, for
  instance, handling O_CLOEXEC descriptors duplicated by
  posix_spawn_file_actions_adddup2() has to be done in the parent
  process to create an inheritable descriptor. If this dup2 relies on a
  preceeding posix_spawn_file_actions_addopen(), this open call has to
  be performed in the parent as well.

- If the executable path given to posix_spawn() is a relative path, it's
  relative to the CWD after having performed the last
  posix_spawn_file_actions_add{f}chdir(). Given we start the process
  from within the parent, we would have to run the file action calls to
  evaluate the CWD in the parent, before we exec the child.

- Along the same lines, if we have to run the file actions in the child,
  given the OS restriction, we would have to execve *before* running the
  file actions, which leads to a chicken-egg problem.

The documentation of posix_spawn_file_actions_addclose() contains this
section:

  A spawn file actions object, when passed to posix_spawn() or
  posix_spawnp(), shall specify how the set of open file descriptors in
  the calling process is transformed into a set of potentially open file
  descriptors for the spawned process. This transformation shall be
  *** as if *** the specified sequence of actions was performed exactly
  once, in the context of the spawned process (prior to execution of the
  new process image), in the order in which the actions were added to
  the object; additionally, when the new process image is executed, any
  file descriptor (from this new set) which has its FD_CLOEXEC flag set
  shall be closed (see posix_spawn()).

Note the "as if". This "as if" looks like a way out for us, but it
depends on the interpretation. What does that "as if" include? Does it
include only the "performed exactly once" requirement? Or does it
include all three requirements, as in "*as if* performed exactly once,
*as if* in the context of the spawned process, *as if* in order...
Desired ActionPlease clarify if the requirement to perform the file actions in the
child process is a hard one, meaning we have to continue using
fork()/execve().

Or if a POSIX emulation is allowed to workaround this requirement, if
the underlying OS is not capable to provide a shallow child context
along the lines of clone3()/vfork().
Tagstc1-2024

Activities

geoffclare

2025-07-24 15:53

manager   bugnote:0007229

On page 1590 line 53471 section posix_spawn_file_actions_addchdir(), change:
[...] all file actions are processed in sequence in the context of the child at a point where the child process is still single-threaded. [...]

to:
[...] all file actions are processed in sequence as if in the context of the child at a point where the child process is still single-threaded. [...]


On page 1591 line 53480 section posix_spawn_file_actions_addchdir(), change:
File actions are performed in a new process created by posix_spawn() or posix_spawnp() in the same order that they were added to the file actions object.

to:
File actions are performed as if in a new process created by posix_spawn() or posix_spawnp() in the same order that they were added to the file actions object.


On page 1592 line 53516 section posix_spawn_file_actions_addclose(), change:
This transformation shall be as if the specified sequence of actions was performed exactly once, in the context of the spawned process (prior to execution of the new process image), in the order in which the actions were added to the object; additionally, when the new process image is executed, any file descriptor (from this new set) which has its FD_CLOEXEC flag set shall be closed (see [xref to posix_spawn( )]).

to:
This transformation shall be as if the specified sequence of actions was:

  • performed exactly once

  • performed in the context of the spawned process (prior to execution of the new process image)

  • performed in the order in which the actions were added to the object


Additionally, when the new process image is executed, any file descriptor (from this new set) which has its FD_CLOEXEC flag set shall be closed (see [xref to posix_spawn( )]).

Issue History

Date Modified Username Field Change
2025-07-07 10:32 corinna_vinschen New Issue
2025-07-24 15:53 geoffclare Note Added: 0007229
2025-07-24 15:54 geoffclare Status New => Resolved
2025-07-24 15:54 geoffclare Resolution Open => Accepted As Marked
2025-07-24 15:54 geoffclare Interp Status => ---
2025-07-24 15:54 geoffclare Final Accepted Text => 0001935:0007229
2025-07-24 15:55 geoffclare Tag Attached: tc1-2024
2025-08-05 15:51 geoffclare Assigned To => geoffclare
2025-08-07 10:27 geoffclare Status Resolved => Applied