aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Drake <cygwin@jdrake.com>2025-06-27 17:16:51 -0700
committerJeremy Drake <cygwin@jdrake.com>2025-09-20 12:55:33 -0700
commit0802d9184bc8c7edef463cefc3f0c81523f049fd (patch)
treee1986fb8f0b1a821eff8b6193ada98ec2a979107
parent9a62bd63e7816e8f0a4b3b74fc4d3c01f38bc308 (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 pathtopic/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,