aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Drake <cygwin@jdrake.com>2025-06-27 17:16:51 -0700
committerJeremy Drake <cygwin@jdrake.com>2025-08-19 11:06:59 -0700
commit2589cbaf7d699bdb63eb244e035f3f5a244f4453 (patch)
tree8ec45deea31cdd11436d744086391508b2728218
parent5e5e505242f368d9bb8a2b618420fc1c77c77927 (diff)
downloadnewlib-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.h3
-rw-r--r--winsup/cygwin/sigproc.cc2
-rw-r--r--winsup/cygwin/spawn.cc19
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,