* dcrt0.cc (get_cygwin_startup_info): New function pulled from dll_crt0_0.

(dll_crt0_0): Use get_cygwin_startup_info to retrieve cygwin-specific startup
pointer.
* external.cc (cygwin_internal): Implement CW_ARGV and CW_ENVP.
* include/sys/cygwin.h: Implement CW_ARGV and CW_ENVP.
This commit is contained in:
Christopher Faylor 2005-05-09 01:19:38 +00:00
parent 61931ed5dc
commit 1cd8ccec87
4 changed files with 77 additions and 48 deletions

View File

@ -1,3 +1,12 @@
2005-05-08 Christopher Faylor <cgf@timesys.com>
* dcrt0.cc (get_cygwin_startup_info): New function pulled from
dll_crt0_0.
(dll_crt0_0): Use get_cygwin_startup_info to retrieve cygwin-specific
startup pointer.
* external.cc (cygwin_internal): Implement CW_ARGV and CW_ENVP.
* include/sys/cygwin.h: Implement CW_ARGV and CW_ENVP.
2005-05-07 Christopher Faylor <cgf@timesys.com> 2005-05-07 Christopher Faylor <cgf@timesys.com>
* path.cc (normalize_posix_path): Don't treat '//' specially since * path.cc (normalize_posix_path): Don't treat '//' specially since

View File

@ -578,14 +578,63 @@ initial_env ()
} }
child_info *
get_cygwin_startup_info ()
{
STARTUPINFO si;
char zeros[sizeof (child_proc_info->zero)] = {0};
GetStartupInfo (&si);
child_info *res = (child_info *) si.lpReserved2;
if (si.cbReserved2 < EXEC_MAGIC_SIZE || !res
|| memcmp (res->zero, zeros, sizeof (res->zero)) != 0)
res = NULL;
else
{
if ((res->intro & OPROC_MAGIC_MASK) == OPROC_MAGIC_GENERIC)
multiple_cygwin_problem ("proc intro", res->intro, 0);
else if (res->intro == PROC_MAGIC_GENERIC
&& res->magic != CHILD_INFO_MAGIC)
multiple_cygwin_problem ("proc magic", res->magic,
CHILD_INFO_MAGIC);
else if (res->cygheap != (void *) &_cygheap_start)
multiple_cygwin_problem ("cygheap base", (DWORD) res->cygheap,
(DWORD) &_cygheap_start);
unsigned should_be_cb = 0;
switch (res->type)
{
case _PROC_FORK:
user_data->forkee = true;
should_be_cb = sizeof (child_info_fork);
/* fall through */;
case _PROC_SPAWN:
case _PROC_EXEC:
if (!should_be_cb)
should_be_cb = sizeof (child_info_spawn);
if (should_be_cb != res->cb)
multiple_cygwin_problem ("proc size", res->cb, should_be_cb);
else if (sizeof (fhandler_union) != res->fhandler_union_cb)
multiple_cygwin_problem ("fhandler size", res->fhandler_union_cb, sizeof (fhandler_union));
break;
default:
system_printf ("unknown exec type %d", res->type);
/* intentionally fall through */
case _PROC_WHOOPS:
res = NULL;
break;
}
}
return res;
}
void __stdcall void __stdcall
dll_crt0_0 () dll_crt0_0 ()
{ {
wincap.init (); wincap.init ();
initial_env (); initial_env ();
char zeros[sizeof (child_proc_info->zero)] = {0};
init_console_handler (); init_console_handler ();
init_global_security (); init_global_security ();
if (!DuplicateHandle (GetCurrentProcess (), GetCurrentProcess (), if (!DuplicateHandle (GetCurrentProcess (), GetCurrentProcess (),
@ -600,60 +649,17 @@ dll_crt0_0 ()
(void) SetErrorMode (SEM_FAILCRITICALERRORS); (void) SetErrorMode (SEM_FAILCRITICALERRORS);
STARTUPINFO si;
GetStartupInfo (&si);
child_proc_info = (child_info *) si.lpReserved2;
if (si.cbReserved2 < EXEC_MAGIC_SIZE || !child_proc_info
|| memcmp (child_proc_info->zero, zeros,
sizeof (child_proc_info->zero)) != 0)
child_proc_info = NULL;
else
{
if ((child_proc_info->intro & OPROC_MAGIC_MASK) == OPROC_MAGIC_GENERIC)
multiple_cygwin_problem ("proc intro", child_proc_info->intro, 0);
else if (child_proc_info->intro == PROC_MAGIC_GENERIC
&& child_proc_info->magic != CHILD_INFO_MAGIC)
multiple_cygwin_problem ("proc magic", child_proc_info->magic,
CHILD_INFO_MAGIC);
else if (child_proc_info->cygheap != (void *) &_cygheap_start)
multiple_cygwin_problem ("cygheap base", (DWORD) child_proc_info->cygheap,
(DWORD) &_cygheap_start);
unsigned should_be_cb = 0;
switch (child_proc_info->type)
{
case _PROC_FORK:
user_data->forkee = true;
should_be_cb = sizeof (child_info_fork);
/* fall through */;
case _PROC_SPAWN:
case _PROC_EXEC:
if (!should_be_cb)
should_be_cb = sizeof (child_info_spawn);
if (should_be_cb != child_proc_info->cb)
multiple_cygwin_problem ("proc size", child_proc_info->cb, should_be_cb);
else if (sizeof (fhandler_union) != child_proc_info->fhandler_union_cb)
multiple_cygwin_problem ("fhandler size", child_proc_info->fhandler_union_cb, sizeof (fhandler_union));
else
cygwin_user_h = child_proc_info->user_h;
break;
default:
system_printf ("unknown exec type %d", child_proc_info->type);
/* intentionally fall through */
case _PROC_WHOOPS:
child_proc_info = NULL;
break;
}
}
device::init (); device::init ();
do_global_ctors (&__CTOR_LIST__, 1); do_global_ctors (&__CTOR_LIST__, 1);
cygthread::init (); cygthread::init ();
child_proc_info = get_cygwin_startup_info ();
if (!child_proc_info) if (!child_proc_info)
memory_init (); memory_init ();
else else
{ {
cygwin_user_h = child_proc_info->user_h;
switch (child_proc_info->type) switch (child_proc_info->type)
{ {
case _PROC_FORK: case _PROC_FORK:

View File

@ -27,8 +27,10 @@ details. */
#include "heap.h" #include "heap.h"
#include "pwdgrp.h" #include "pwdgrp.h"
#include "cygtls.h" #include "cygtls.h"
#include "child_info.h"
void *hook_cygwin (const char *, const void *); void *hook_cygwin (const char *, const void *);
child_info *get_cygwin_startup_info ();
static external_pinfo * static external_pinfo *
fillout_pinfo (pid_t pid, int winpid) fillout_pinfo (pid_t pid, int winpid)
@ -306,6 +308,16 @@ cygwin_internal (cygwin_getinfo_types t, ...)
const void *hookfn = va_arg (arg, const void *); const void *hookfn = va_arg (arg, const void *);
return (unsigned long) hook_cygwin (name, hookfn); return (unsigned long) hook_cygwin (name, hookfn);
} }
case CW_ARGV:
{
child_info_spawn *ci = (child_info_spawn *) get_cygwin_startup_info ();
return (DWORD) (ci ? ci->moreinfo->argv : NULL);
}
case CW_ENVP:
{
child_info_spawn *ci = (child_info_spawn *) get_cygwin_startup_info ();
return (DWORD) (ci ? ci->moreinfo->envp : NULL);
}
default: default:
return (DWORD) -1; return (DWORD) -1;
} }

View File

@ -80,7 +80,9 @@ typedef enum
CW_GET_UID_FROM_SID, CW_GET_UID_FROM_SID,
CW_GET_GID_FROM_SID, CW_GET_GID_FROM_SID,
CW_GET_BINMODE, CW_GET_BINMODE,
CW_HOOK CW_HOOK,
CW_ARGV,
CW_ENVP
} cygwin_getinfo_types; } cygwin_getinfo_types;
#define CW_NEXTPID 0x80000000 /* or with pid to get next one */ #define CW_NEXTPID 0x80000000 /* or with pid to get next one */