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:
parent
7fd70a9706
commit
578bbc3a29
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue