This is the mail archive of the cygwin-patches mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH v2 2/6] Cygwin: Allow the environment pointer to be NULL


Following glibc, interpret this as meaning the environment is empty.
---
 winsup/cygwin/environ.cc | 40 ++++++++++++++++++++++++++--------------
 winsup/cygwin/pinfo.cc   |  7 ++++---
 2 files changed, 30 insertions(+), 17 deletions(-)

diff --git a/winsup/cygwin/environ.cc b/winsup/cygwin/environ.cc
index b452d21a5..06e1ced01 100644
--- a/winsup/cygwin/environ.cc
+++ b/winsup/cygwin/environ.cc
@@ -30,6 +30,7 @@ details. */
 #include "shared_info.h"
 #include "ntdll.h"
 
+/* If this is not NULL, it points to memory allocated by us. */
 static char **lastenviron;
 
 /* Parse CYGWIN options */
@@ -483,6 +484,9 @@ my_findenv (const char *name, int *offset)
   register char **p;
   const char *c;
 
+  if (cur_environ () == NULL)
+    return NULL;
+
   c = name;
   len = 0;
   while (*c && *c != '=')
@@ -545,14 +549,18 @@ _getenv_r (struct _reent *, const char *name)
   return findenv_func (name, &offset);
 }
 
-/* Return size of environment block, including terminating NULL. */
+/* Return number of environment entries, including terminating NULL. */
 static int __stdcall
 envsize (const char * const *in_envp)
 {
   const char * const *envp;
+
+  if (in_envp == NULL)
+    return 0;
+
   for (envp = in_envp; *envp; envp++)
     continue;
-  return (1 + envp - in_envp) * sizeof (const char *);
+  return 1 + envp - in_envp;
 }
 
 /* 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. */
       int sz = envsize (cur_environ ());
 
-      /* Allocate space for two new slots even though only one is needed.
-	 According to the commit message for commit ebd645e
-	 (2001-10-03), this is done to "work around problems with some
-	 buggy applications." */
-      int allocsz = sz + (2 * sizeof (char *));
+      /* If sz == 0, we need two new slots, one for the terminating NULL.
+	 But we add two slots in all cases, as has been done since
+	 2001-10-03 (commit ebd645e) to "work around problems with
+	 some buggy applications." */
+      int allocsz = (sz + 2) * sizeof (char *);
 
-      offset = (sz - 1) / sizeof (char *);
+      offset = sz == 0 ? 0 : sz - 1;
 
       /* Allocate space for additional element. */
       if (cur_environ () == lastenviron)
-	lastenviron = __cygwin_environ = (char **) realloc (cur_environ (),
+	lastenviron = __cygwin_environ = (char **) realloc (lastenviron,
 							    allocsz);
-      else if ((lastenviron = (char **) malloc (allocsz)) != NULL)
-	__cygwin_environ = (char **) memcpy ((char **) lastenviron,
-					     __cygwin_environ, sz);
-
-      if (!__cygwin_environ)
+      else if ((lastenviron = (char **) realloc (lastenviron, allocsz)) != NULL)
+	__cygwin_environ = (char **) memcpy (lastenviron, __cygwin_environ,
+					     sz * sizeof (char *));
+      if (!lastenviron)
 	{
 #ifdef DEBUGGING
 	  try_to_debug ();
@@ -1029,8 +1036,13 @@ build_env (const char * const *envp, PWCHAR &envblock, int &envc,
   char **dstp;
   bool saw_spenv[SPENVS_SIZE] = {0};
 
+  static char *const empty_env[] = { NULL };
+
   debug_printf ("envp %p", envp);
 
+  if (!envp)
+    envp = empty_env;
+
   /* How many elements? */
   for (n = 0; envp[n]; n++)
     continue;
diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc
index e4eef8b3c..6b6986c9e 100644
--- a/winsup/cygwin/pinfo.cc
+++ b/winsup/cygwin/pinfo.cc
@@ -677,11 +677,12 @@ commune_process (void *arg)
 	sigproc_printf ("processing PICOM_ENVIRON");
 	unsigned n = 0;
 	char **env = cur_environ ();
-	for (char **e = env; *e; e++)
-	  n += strlen (*e) + 1;
+	if (env)
+	  for (char **e = env; *e; e++)
+	    n += strlen (*e) + 1;
 	if (!WritePipeOverlapped (tothem, &n, sizeof n, &nr, 1000L))
 	  sigproc_printf ("WritePipeOverlapped sizeof argv failed, %E");
-	else
+	else if (env)
 	  for (char **e = env; *e; e++)
 	    if (!WritePipeOverlapped (tothem, *e, strlen (*e) + 1, &nr, 1000L))
 	      {
-- 
2.17.0


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]