This is the mail archive of the cygwin-cvs@cygwin.com 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]

[newlib-cygwin] Add a _pinfo.environ() method analogous to _pinfo.cmdline(), and others.


https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=578bbc3a2907aed549da6fcfc4713f3a2358cc86

commit 578bbc3a2907aed549da6fcfc4713f3a2358cc86
Author: Erik M. Bray <erik.bray@lri.fr>
Date:   Tue Jan 10 16:03:09 2017 +0100

    Add a _pinfo.environ() method analogous to _pinfo.cmdline(), and others.
    
    Returns the process's environment concatenated into a single block of
    null-terminated strings, along with the length of the environment block.
    
    Adds an associated PICOM_ENVIRON commune_process handler.

Diff:
---
 winsup/cygwin/pinfo.cc | 83 ++++++++++++++++++++++++++++++++++++++++++++++++--
 winsup/cygwin/pinfo.h  |  4 ++-
 2 files changed, 84 insertions(+), 3 deletions(-)

diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc
index 9b74442..a88b6d0 100644
--- a/winsup/cygwin/pinfo.cc
+++ b/winsup/cygwin/pinfo.cc
@@ -653,8 +653,26 @@ commune_process (void *arg)
 	else if (!WritePipeOverlapped (tothem, path, n, &nr, 1000L))
 	  sigproc_printf ("WritePipeOverlapped fd failed, %E");
 	break;
-      }
-    }
+	  }
+	case PICOM_ENVIRON:
+	  {
+	sigproc_printf ("processing PICOM_ENVIRON");
+	unsigned n = 0;
+	char **env = cur_environ ();
+	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
+	  for (char **e = env; *e; e++)
+	    if (!WritePipeOverlapped (tothem, *e, strlen (*e) + 1, &nr, 1000L))
+	      {
+	        sigproc_printf ("WritePipeOverlapped arg %d failed, %E", e - env);
+	        break;
+	      }
+	break;
+	  }
+	}
   if (process_sync)
     {
       DWORD res = WaitForSingleObject (process_sync, 5000);
@@ -730,6 +748,7 @@ _pinfo::commune_request (__uint32_t code, ...)
     {
     case PICOM_CMDLINE:
     case PICOM_CWD:
+    case PICOM_ENVIRON:
     case PICOM_ROOT:
     case PICOM_FDS:
     case PICOM_FD:
@@ -993,6 +1012,66 @@ _pinfo::cmdline (size_t& n)
   return s;
 }
 
+
+char *
+_pinfo::environ (size_t& n)
+{
+  char **env = NULL;
+  if (!this || !pid)
+    return NULL;
+  if (ISSTATE (this, PID_NOTCYGWIN))
+    {
+      RTL_USER_PROCESS_PARAMETERS rupp;
+      HANDLE proc = open_commune_proc_parms (dwProcessId, &rupp);
+
+      if (!proc)
+        return NULL;
+
+      MEMORY_BASIC_INFORMATION mbi;
+      SIZE_T envsize;
+      PWCHAR envblock;
+      if (!VirtualQueryEx (proc, rupp.Environment, &mbi, sizeof(mbi)))
+        {
+          NtClose (proc);
+          return NULL;
+        }
+
+      SIZE_T read;
+      envsize = (ptrdiff_t) mbi.RegionSize
+                - ((ptrdiff_t) rupp.Environment - (ptrdiff_t) mbi.BaseAddress);
+      envblock = (PWCHAR) cmalloc_abort (HEAP_COMMUNE, envsize);
+
+      if (ReadProcessMemory (proc, rupp.Environment, envblock, envsize, &read))
+        env = win32env_to_cygenv (envblock, false);
+
+      NtClose (proc);
+    }
+  else if (pid != myself->pid)
+    {
+      commune_result cr = commune_request (PICOM_ENVIRON);
+      n = cr.n;
+      return cr.s;
+    }
+  else
+    env = cur_environ ();
+
+  if (env == NULL)
+      return NULL;
+
+  n = 0;
+  for (char **e = env; *e; e++)
+    n += strlen (*e) + 1;
+
+  char *p, *s;
+  p = s = (char *) cmalloc_abort (HEAP_COMMUNE, n);
+  for (char **e = env; *e; e++)
+    {
+      strcpy (p, *e);
+      p = strchr (p, '\0') + 1;
+    }
+  return s;
+}
+
 /* This is the workhorse which waits for the write end of the pipe
    created during new process creation.  If the pipe is closed or a zero
    is received on the pipe, it is assumed that the cygwin pid has exited.
diff --git a/winsup/cygwin/pinfo.h b/winsup/cygwin/pinfo.h
index fd76c8d..7ad1294 100644
--- a/winsup/cygwin/pinfo.h
+++ b/winsup/cygwin/pinfo.h
@@ -26,7 +26,8 @@ enum picom
   PICOM_ROOT = 3,
   PICOM_FDS = 4,
   PICOM_FD = 5,
-  PICOM_PIPE_FHANDLER = 6
+  PICOM_PIPE_FHANDLER = 6,
+  PICOM_ENVIRON = 7
 };
 
 #define EXITCODE_SET		0x8000000
@@ -106,6 +107,7 @@ public:
   char *root (size_t &);
   char *cwd (size_t &);
   char *cmdline (size_t &);
+  char *environ (size_t &);
   char *win_heap_info (size_t &);
   bool set_ctty (class fhandler_termios *, int);
   bool alert_parent (char);


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