diff options
author | Jeremy Drake <cygwin@jdrake.com> | 2025-06-27 17:16:51 -0700 |
---|---|---|
committer | Jeremy Drake <cygwin@jdrake.com> | 2025-08-19 11:06:59 -0700 |
commit | 2589cbaf7d699bdb63eb244e035f3f5a244f4453 (patch) | |
tree | 8ec45deea31cdd11436d744086391508b2728218 | |
parent | 5e5e505242f368d9bb8a2b618420fc1c77c77927 (diff) | |
download | newlib-topic/posix_spawn.zip newlib-topic/posix_spawn.tar.gz newlib-topic/posix_spawn.tar.bz2 |
Cygwin: add pgroup support to posix_spawn fast pathgithub/topic/posix_spawntopic/posix_spawn
Tweak proc_subproc PROC_ADD_CHILD to only initialize vchild->pgid if
it's not already set.
The error checking of setpgid is lacking with respect to the POSIX
standard, but this code replicates what setpgid does.
This attribute is used by ninja, so is worth adding to the fast path.
Signed-off-by: Jeremy Drake <cygwin@jdrake.com>
-rw-r--r-- | winsup/cygwin/local_includes/child_info.h | 3 | ||||
-rw-r--r-- | winsup/cygwin/sigproc.cc | 2 | ||||
-rw-r--r-- | winsup/cygwin/spawn.cc | 19 |
3 files changed, 19 insertions, 5 deletions
diff --git a/winsup/cygwin/local_includes/child_info.h b/winsup/cygwin/local_includes/child_info.h index 9d2563e..6e8504d 100644 --- a/winsup/cygwin/local_includes/child_info.h +++ b/winsup/cygwin/local_includes/child_info.h @@ -142,11 +142,12 @@ struct spawn_worker_args const char *const *envp; int stdfds[3]; int cwdfd; + pid_t pgid; sigset_t *sigmask; spawn_worker_args (const char *const *argv, const char *const envp[]) : argv (argv), envp (envp), stdfds {-1, -1, -1}, cwdfd (AT_FDCWD), - sigmask (NULL) + pgid (-1), sigmask (NULL) { } }; diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index 30779cf..9bf6d26 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -257,7 +257,7 @@ proc_subproc (DWORD what, uintptr_t val) { vchild->uid = myself->uid; vchild->gid = myself->gid; - vchild->pgid = myself->pgid; + InterlockedCompareExchange ((LONG*) &vchild->pgid, myself->pgid, 0); vchild->sid = myself->sid; vchild->ctty = myself->ctty; vchild->cygstarted = true; diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc index 1b9aea3..59ac5b2 100644 --- a/winsup/cygwin/spawn.cc +++ b/winsup/cygwin/spawn.cc @@ -613,7 +613,8 @@ child_info_spawn::worker (int mode, const char *prog_arg, they ignore it explicitely. CREATE_NEW_PROCESS_GROUP does that for us. */ pid_t ctty_pgid = ::cygheap->ctty ? ::cygheap->ctty->tc_getpgid () : 0; - if (!iscygwin () && ctty_pgid && ctty_pgid != myself->pgid) + if (!iscygwin () && ctty_pgid && + ctty_pgid != (args.pgid == -1 ? myself->pgid : args.pgid)) c_flags |= CREATE_NEW_PROCESS_GROUP; if (mode == _P_DETACH) @@ -859,6 +860,8 @@ child_info_spawn::worker (int mode, const char *prog_arg, } child->dwProcessId = pi.dwProcessId; child.hProcess = pi.hProcess; + if (args.pgid != -1) + child->pgid = args.pgid ?: cygpid; real_path.get_wide_win32_path (child->progname); /* This introduces an unreferenced, open handle into the child. @@ -1470,17 +1473,27 @@ do_posix_spawn (pid_t *pid, const char *path, /* TODO: possibly implement spawnattr flags: POSIX_SPAWN_RESETIDS - POSIX_SPAWN_SETPGROUP POSIX_SPAWN_SETSCHEDPARAM POSIX_SPAWN_SETSCHEDULER */ if (sa) { - if ((*sa)->sa_flags & ~(POSIX_SPAWN_SETSIGMASK|POSIX_SPAWN_SETSIGDEF)) + static const short FASTPATH_FLAGS = + POSIX_SPAWN_SETSIGMASK|POSIX_SPAWN_SETSIGDEF|POSIX_SPAWN_SETPGROUP; + if ((*sa)->sa_flags & ~FASTPATH_FLAGS) goto fallback; if ((*sa)->sa_flags & POSIX_SPAWN_SETSIGMASK) args.sigmask = &(*sa)->sa_sigmask; + if ((*sa)->sa_flags & POSIX_SPAWN_SETPGROUP) + { + args.pgid = (*sa)->sa_pgroup; + if (args.pgid < 0) + return EINVAL; + /* According to POSIX there should be more error cases, but setpgid + does not implement them, so replicate its behavior. */ + } + if ((*sa)->sa_flags & POSIX_SPAWN_SETSIGDEF) { sigs = (struct sigaction *) cmalloc (HEAP_SIGS, |