setpgid non-compliance with POSIX?

Jeremy Drake cygwin@jdrake.com
Sat Jun 28 19:32:55 GMT 2025


I was looking at setpgid yesterday, and it seems deficient with respect to
the errors required to be returned by the POSIX docs in
https://pubs.opengroup.org/onlinepubs/9799919799/functions/setpgid.html

Basically, it seems that setpgid allows any arbitrary positive integer to
be set as pgid, rather than restricting to setting it to either the
process's pid or to an existing pgid in the same session (sid).

> The setpgid() function shall fail if:
>
> [EACCES]
> The value of the pid argument matches the process ID of a child process
> of the calling process and the child process has successfully executed
> one of the exec functions.

Not handled.  In Cygwin context, I imagine the intent here is that you can
only call setpgid on a forked child, not a spawned or execed one?  I don't
know how that might cause issues for things already using spawn* functions
and expecting to setpgid (if there are any).  It seems like the only
POSIX-compliant way to spawn with a different pgid then is to use
posix_spawn with POSIX_SPAWN_SETPGROUP.

> [EINVAL]
> The value of the pgid argument is less than 0, or is not a value
> supported by the implementation.

This seems to be handled correctly.

> [EPERM]
> The process indicated by the pid argument is a session leader.

Not handled

> [EPERM]
> The value of the pid argument matches the process ID of a child process
> of the calling process and the child process is not in the same session
> as the calling process.

Not handled

> [EPERM]
> The value of the pgid argument is valid but does not match the process
> ID of the process indicated by the pid argument and there is no process
> with a process group ID that matches the value of the pgid argument in
> the same session as the calling process.

Not handled

> [ESRCH]
> The value of the pid argument does not match the process ID of the
> calling process or of a child process of the calling process.

Partially handled - fails with ESRCH if no process with that ID exists,
but fails with EPERM if the process does exist but is not the calling
process or a child of the calling process.



More information about the Cygwin mailing list