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