Cygwin: Allow the environment pointer to be NULL

Following glibc, interpret this as meaning the environment is empty.
This commit is contained in:
Ken Brown 2018-06-06 11:45:55 -04:00 committed by Corinna Vinschen
parent 1ecbb8d7b7
commit 9234545e3d
2 changed files with 30 additions and 17 deletions

View File

@ -30,6 +30,7 @@ details. */
#include "shared_info.h" #include "shared_info.h"
#include "ntdll.h" #include "ntdll.h"
/* If this is not NULL, it points to memory allocated by us. */
static char **lastenviron; static char **lastenviron;
/* Parse CYGWIN options */ /* Parse CYGWIN options */
@ -483,6 +484,9 @@ my_findenv (const char *name, int *offset)
register char **p; register char **p;
const char *c; const char *c;
if (cur_environ () == NULL)
return NULL;
c = name; c = name;
len = 0; len = 0;
while (*c && *c != '=') while (*c && *c != '=')
@ -545,14 +549,18 @@ _getenv_r (struct _reent *, const char *name)
return findenv_func (name, &offset); return findenv_func (name, &offset);
} }
/* Return size of environment block, including terminating NULL. */ /* Return number of environment entries, including terminating NULL. */
static int __stdcall static int __stdcall
envsize (const char * const *in_envp) envsize (const char * const *in_envp)
{ {
const char * const *envp; const char * const *envp;
if (in_envp == NULL)
return 0;
for (envp = in_envp; *envp; envp++) for (envp = in_envp; *envp; envp++)
continue; continue;
return (1 + envp - in_envp) * sizeof (const char *); return 1 + envp - in_envp;
} }
/* Takes similar arguments to setenv except that overwrite is /* Takes similar arguments to setenv except that overwrite is
@ -584,23 +592,22 @@ _addenv (const char *name, const char *value, int overwrite)
{ /* Create new slot. */ { /* Create new slot. */
int sz = envsize (cur_environ ()); int sz = envsize (cur_environ ());
/* Allocate space for two new slots even though only one is needed. /* If sz == 0, we need two new slots, one for the terminating NULL.
According to the commit message for commit ebd645e But we add two slots in all cases, as has been done since
(2001-10-03), this is done to "work around problems with some 2001-10-03 (commit ebd645e) to "work around problems with
buggy applications." */ some buggy applications." */
int allocsz = sz + (2 * sizeof (char *)); int allocsz = (sz + 2) * sizeof (char *);
offset = (sz - 1) / sizeof (char *); offset = sz == 0 ? 0 : sz - 1;
/* Allocate space for additional element. */ /* Allocate space for additional element. */
if (cur_environ () == lastenviron) if (cur_environ () == lastenviron)
lastenviron = __cygwin_environ = (char **) realloc (cur_environ (), lastenviron = __cygwin_environ = (char **) realloc (lastenviron,
allocsz); allocsz);
else if ((lastenviron = (char **) malloc (allocsz)) != NULL) else if ((lastenviron = (char **) realloc (lastenviron, allocsz)) != NULL)
__cygwin_environ = (char **) memcpy ((char **) lastenviron, __cygwin_environ = (char **) memcpy (lastenviron, __cygwin_environ,
__cygwin_environ, sz); sz * sizeof (char *));
if (!lastenviron)
if (!__cygwin_environ)
{ {
#ifdef DEBUGGING #ifdef DEBUGGING
try_to_debug (); try_to_debug ();
@ -1029,8 +1036,13 @@ build_env (const char * const *envp, PWCHAR &envblock, int &envc,
char **dstp; char **dstp;
bool saw_spenv[SPENVS_SIZE] = {0}; bool saw_spenv[SPENVS_SIZE] = {0};
static char *const empty_env[] = { NULL };
debug_printf ("envp %p", envp); debug_printf ("envp %p", envp);
if (!envp)
envp = empty_env;
/* How many elements? */ /* How many elements? */
for (n = 0; envp[n]; n++) for (n = 0; envp[n]; n++)
continue; continue;

View File

@ -677,11 +677,12 @@ commune_process (void *arg)
sigproc_printf ("processing PICOM_ENVIRON"); sigproc_printf ("processing PICOM_ENVIRON");
unsigned n = 0; unsigned n = 0;
char **env = cur_environ (); char **env = cur_environ ();
for (char **e = env; *e; e++) if (env)
n += strlen (*e) + 1; for (char **e = env; *e; e++)
n += strlen (*e) + 1;
if (!WritePipeOverlapped (tothem, &n, sizeof n, &nr, 1000L)) if (!WritePipeOverlapped (tothem, &n, sizeof n, &nr, 1000L))
sigproc_printf ("WritePipeOverlapped sizeof argv failed, %E"); sigproc_printf ("WritePipeOverlapped sizeof argv failed, %E");
else else if (env)
for (char **e = env; *e; e++) for (char **e = env; *e; e++)
if (!WritePipeOverlapped (tothem, *e, strlen (*e) + 1, &nr, 1000L)) if (!WritePipeOverlapped (tothem, *e, strlen (*e) + 1, &nr, 1000L))
{ {