diff options
author | Jeremy Drake <cygwin@jdrake.com> | 2025-06-27 17:16:51 -0700 |
---|---|---|
committer | Jeremy Drake <cygwin@jdrake.com> | 2025-07-24 15:49:56 -0700 |
commit | c1eec60d6035d497a9a9c99a5b2911b79cd8919b (patch) | |
tree | a4af9f45c3ad7657f3f62d62e7b2c22ac261b988 | |
parent | 6e5d4ecfbfb817e9104aa6b81c6b973640227554 (diff) | |
download | newlib-github/topic/posix_spawn.zip newlib-github/topic/posix_spawn.tar.gz newlib-github/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 bce5ca7..91d5433 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 3618879..7020071 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 4c17ee6..e17ef10 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, |