On Sat, Jun 14, 2025 at 12:29:57PM -0600, Brian Inglis via Cygwin wrote: > 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.
Yes. And to clarify for pedantic correctness, the envp pointer should be stable during the fork, so it is best to avoid using the stack. One solution, as Brian said, is to pass a pointer to the NULL at the end of environ (which is still not guaranteed static), or one could use static char *empty_envp[] = { NULL }; and pass empty_envp, which is persistent and stable. Cheers, Glenn -- Problem reports: https://cygwin.com/problems.html FAQ: https://cygwin.com/faq/ Documentation: https://cygwin.com/docs.html Unsubscribe info: https://cygwin.com/ml/#unsubscribe-simple