[PATCH 4/5] Cygwin: add fast-path for posix_spawn(p)

Jeremy Drake cygwin@jdrake.com
Thu Jul 3 05:51:32 GMT 2025


On Wed, 2 Jul 2025, Corinna Vinschen wrote:

> One problem is that you dup and open files in the parent, which are
> supposed to be dup'ed and opened in the child.  That's ok for a native
> child, because we can't just hook into the native child process as Linux'
> clone3 call does.
>
> But generally it's not ok for Cygwin parent and child.  We have methods
> in place to communicate to the child what its supposed to do at startup,
> so we can do this right with a bit of tweaking, no?
>
> > It kind of sounds like what you are envisioning is pushing this to a lower
> > level, potentially even re-architecting child_info_spawn and related
> > startup code (I don't know if handle_spawn would necessarily encapsulate
> > everything) in terms of posix_spawn's parameters.  I was not looking to
> > get that deep into things.
>
> I don't see this as a deeper level.  It's just the child side of the same
> mechanism.  You're adding lots of code to make this work, but for Cygwin
> processes it's just in the wrong spot.


I was thinking about this further this evening, and I think I found a flaw
that couldn't be readily solved *without* processing the file actions in
the parent.  We already know and agree that the parent must process the
chdir and fchdir actions, in order to properly resolve relative path_args
(and relative #!s for that matter).  However, fchdir takes a file
descriptor, and the state of the file descriptors depends on the file
actions before the fchdir.  Therefore, all file actions prior to an fchdir
must be processed (or at least considered, probably through multiple
passes of the singly-linked actions queue) in the parent.

addopen (42, "dir", O_SEARCH|O_DIRECTORY)
addfchdir (42)
addclose (42)
(therefore addopen needs to be considered)

fd = open ("dir", O_SEARCH|O_DIRECTORY)
addclose (fd)
addfchdir (fd)
needs to fail with EBADF (therefore addclose needs to be considered.)

fd = open ("dir", O_SEARCH|O_DIRECTORY)
fd2 = open ("dir2", O_SEARCH|O_DIRECTORY)
adddup2 (fd2, fd)
addfchdir (fd)
needs to chdir to dir2, not dir (therefore dup2 needs to be considered)

addchdir ("dir")
addopen (42, "subdir", O_SEARCH|O_DIRECTORY)
addfchdir (42)
addclose (42)
needs to chdir to dir/subdir (so chdir needs to be considered before open).

What scenario would not work properly if the file actions were not done in
the child?  The main thing I can think of is opening things under
/proc/self, but that would do the wrong thing anyway even if done in the
child startup (vs the "proper" behavior in a real fork/exec), if you open
/proc/self/exe.  There is the RESETIDS flag that could implicate that the
operations need to happen as a different user, but I was definitely not
planning to handle that flag and letting fork/exec take care of it.
setuid binary (if those are even supported in Cygwin) would mean the child
would be running as the new id, while a fork running the actions would
still be running as the old id before execing the suid binary, so point
for processing in the parent for that I guess.




More information about the Cygwin-patches mailing list