aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Drake <cygwin@jdrake.com>2025-06-27 17:16:51 -0700
committerJeremy Drake <cygwin@jdrake.com>2025-07-24 15:49:56 -0700
commitc1eec60d6035d497a9a9c99a5b2911b79cd8919b (patch)
treea4af9f45c3ad7657f3f62d62e7b2c22ac261b988
parent6e5d4ecfbfb817e9104aa6b81c6b973640227554 (diff)
downloadnewlib-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.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 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,