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.
This commit is contained in:
Erik M. Bray 2017-01-10 16:03:09 +01:00 committed by Corinna Vinschen
parent 7fd70a9706
commit 578bbc3a29
2 changed files with 84 additions and 3 deletions

View File

@ -653,8 +653,26 @@ commune_process (void *arg)
else if (!WritePipeOverlapped (tothem, path, n, &nr, 1000L)) else if (!WritePipeOverlapped (tothem, path, n, &nr, 1000L))
sigproc_printf ("WritePipeOverlapped fd failed, %E"); sigproc_printf ("WritePipeOverlapped fd failed, %E");
break; 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) if (process_sync)
{ {
DWORD res = WaitForSingleObject (process_sync, 5000); DWORD res = WaitForSingleObject (process_sync, 5000);
@ -730,6 +748,7 @@ _pinfo::commune_request (__uint32_t code, ...)
{ {
case PICOM_CMDLINE: case PICOM_CMDLINE:
case PICOM_CWD: case PICOM_CWD:
case PICOM_ENVIRON:
case PICOM_ROOT: case PICOM_ROOT:
case PICOM_FDS: case PICOM_FDS:
case PICOM_FD: case PICOM_FD:
@ -993,6 +1012,66 @@ _pinfo::cmdline (size_t& n)
return s; 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 /* 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 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. is received on the pipe, it is assumed that the cygwin pid has exited.

View File

@ -26,7 +26,8 @@ enum picom
PICOM_ROOT = 3, PICOM_ROOT = 3,
PICOM_FDS = 4, PICOM_FDS = 4,
PICOM_FD = 5, PICOM_FD = 5,
PICOM_PIPE_FHANDLER = 6 PICOM_PIPE_FHANDLER = 6,
PICOM_ENVIRON = 7
}; };
#define EXITCODE_SET 0x8000000 #define EXITCODE_SET 0x8000000
@ -106,6 +107,7 @@ public:
char *root (size_t &); char *root (size_t &);
char *cwd (size_t &); char *cwd (size_t &);
char *cmdline (size_t &); char *cmdline (size_t &);
char *environ (size_t &);
char *win_heap_info (size_t &); char *win_heap_info (size_t &);
bool set_ctty (class fhandler_termios *, int); bool set_ctty (class fhandler_termios *, int);
bool alert_parent (char); bool alert_parent (char);