posix_spawn difference from Linux
Brian Inglis
Brian.Inglis@SystematicSW.ab.ca
Sat Jun 14 18:29:57 GMT 2025
On 2025-06-13 21:39, Glenn Strauss via Cygwin wrote:
> On Fri, Jun 13, 2025 at 02:25:17PM -0700, Jeremy Drake via Cygwin wrote:
>> On Fri, 13 Jun 2025, Jeremy Drake wrote:
>>
>>> I am working on some posix_spawn tests for the new stc repository [1], and
>>> making sure they behave the same between Cygwin and Linux. I found one
>>> case (so far) which does not: passing NULL for argument "envp" to
>>> posix_spawn.
>>>
>>> In Cygwin, this results in the child inheriting the environment from the
>>> caller (same as passing "environ"), but on Linux this results in the child
>>> getting an empty environment (same as passing a char *envp[] = {NULL}).
>>>
>>> The Open Group doc on posix_spawn[2] doesn't seem to say anything about
>>> the potential for envp being NULL, but does mention
>>>
>>>> For the Ada language binding for Start_Process to be implemented with
>>>> posix_spawn(), that binding would need to explicitly pass an empty
>>>> signal mask and the parent's environment to posix_spawn() whenever the
>>>> caller of Start_Process allowed these arguments to default, since
>>>> posix_spawn() does not provide such defaults.
>>>
>>> That at least implies that passing NULL does not default to using the
>>> parent's environment.
>>>
>>> Thoughts? Is this a bug in Cygwin, or "undefined behavior" that it's
>>> perfectly within its rights to do whatever it feels like in response
>>> (empty environment or inherited environment, or crash every second
>>> Tuesday)?
>>
>> Oops, I forgot my footnote links:
>>
>> [1]: https://cygwin.com/cgit/cygwin-apps/stc/
>> [2]: https://pubs.opengroup.org/onlinepubs/007904975/functions/posix_spawn.html
Latest Issue 8 2024 SUSV5:
https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawn.html
says envp is pointer to char * array.
> The man pages from different OS contain something like (from Linux):
>
> The argument envp is an array of character pointers to null-terminated strings. These strings constitute the environment for the new
> process image. The environment array is terminated by a null pointer.
>
> I have never interpreted NULL as a valid value for envp.
> I think the behavior is unspecified, and could segfault.
> If caller intends an empty environment, then caller should pass:
> char *e[] = { NULL };
Could also pass a pointer to the final NULL pointer in environ to avoid defining
your own.
> Therefore, in lighttpd's portability wrapper for fork-execve,
> passing NULL for envp (to my wrapper) is used to inherit default env
> from current process (char **environ), whether lighttpd uses
> posix_spawn() or execve(). This is the same behavior you described
> for Cygwin, though lighttpd passes `environ` to posix_spawn(), not NULL.
--
Take care. Thanks, Brian Inglis Calgary, Alberta, Canada
La perfection est atteinte Perfection is achieved
non pas lorsqu'il n'y a plus rien à ajouter not when there is no more to add
mais lorsqu'il n'y a plus rien à retrancher but when there is no more to cut
-- Antoine de Saint-Exupéry
More information about the Cygwin
mailing list