diff options
Diffstat (limited to 'winsup')
-rw-r--r-- | winsup/cygwin/dcrt0.cc | 18 | ||||
-rw-r--r-- | winsup/cygwin/kernel32.cc | 7 | ||||
-rw-r--r-- | winsup/cygwin/local_includes/winf.h | 13 | ||||
-rw-r--r-- | winsup/cygwin/local_includes/winsup.h | 4 | ||||
-rw-r--r-- | winsup/cygwin/spawn.cc | 18 | ||||
-rw-r--r-- | winsup/cygwin/sysconf.cc | 2 |
6 files changed, 38 insertions, 24 deletions
diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc index 1d8810546..130d652aa 100644 --- a/winsup/cygwin/dcrt0.cc +++ b/winsup/cygwin/dcrt0.cc @@ -976,10 +976,22 @@ dll_crt0_1 (void *) { /* Create a copy of Cygwin's version of __argv so that, if the user makes a change to an element of argv[] it does not affect Cygwin's argv. - Changing the the contents of what argv[n] points to will still - affect Cygwin. This is similar (but not exactly like) Linux. */ + Changing the contents of what argv[n] points to will still affect + Cygwin. This is similar (but not exactly like) Linux. + + We used to allocate newargv on the stack, but all the rest of the + argument and environment handling does not depend on the stack, + as it does on Linux. In fact, everything is stored by the parent + in the cygheap, so the only reason this may fail is if we're out + of resources in a big way. If this malloc fails, we could either + fail the entire process execution, or we could proceed with the + original argv and potentially affect output of /proc/self/cmdline. + We opt for the latter here because it's the lesser evil. */ char **newargv = (char **) malloc ((__argc + 1) * sizeof (char *)); - memcpy (newargv, __argv, (__argc + 1) * sizeof (char *)); + if (newargv) + memcpy (newargv, __argv, (__argc + 1) * sizeof (char *)); + else + newargv = __argv; /* Handle any signals which may have arrived */ sig_dispatch_pending (false); _my_tls.call_signal_handler (); diff --git a/winsup/cygwin/kernel32.cc b/winsup/cygwin/kernel32.cc index 6248aefd5..36951f6a8 100644 --- a/winsup/cygwin/kernel32.cc +++ b/winsup/cygwin/kernel32.cc @@ -424,8 +424,11 @@ ucmd () linebuf cmd; path_conv real_path (__argv[0]); av newargv (__argc, __argv); - cmd.fromargv (newargv, real_path.get_win32 (), true); - RtlInitUnicodeString (&wcmd, cmd); + if (newargv.argc) + { + cmd.fromargv (newargv, real_path.get_win32 (), true); + RtlInitUnicodeString (&wcmd, cmd); + } } return &wcmd; } diff --git a/winsup/cygwin/local_includes/winf.h b/winsup/cygwin/local_includes/winf.h index 651f78ba2..b58693441 100644 --- a/winsup/cygwin/local_includes/winf.h +++ b/winsup/cygwin/local_includes/winf.h @@ -23,11 +23,16 @@ class av public: int argc; bool win16_exe; - av (): argv (NULL) {} - av (int ac_in, const char * const *av_in) : calloced (0), argc (ac_in), win16_exe (false) + av () : argv (NULL), argc (0) {} + av (int ac_in, const char * const *av_in) + : calloced (0), win16_exe (false) { - argv = (char **) cmalloc_abort (HEAP_1_ARGV, (argc + 5) * sizeof (char *)); - memcpy (argv, av_in, (argc + 1) * sizeof (char *)); + argv = (char **) cmalloc (HEAP_1_ARGV, (ac_in + 5) * sizeof (char *)); + if (argv) + { + argc = ac_in; + memcpy (argv, av_in, (argc + 1) * sizeof (char *)); + } } void *operator new (size_t, void *p) __attribute__ ((nothrow)) {return p;} ~av () diff --git a/winsup/cygwin/local_includes/winsup.h b/winsup/cygwin/local_includes/winsup.h index 57bd38c9f..c9788de8f 100644 --- a/winsup/cygwin/local_includes/winsup.h +++ b/winsup/cygwin/local_includes/winsup.h @@ -73,10 +73,6 @@ uint32_t cygwin_inet_addr (const char *cp); application provided path strings we handle. */ #define NT_MAX_PATH 32768 -/* CYG_ARG_MAX is the maximum total length of command line args. - The value 2097152 is the default ARG_MAX value in Linux. */ -#define CYG_ARG_MAX 2097152 - /* This definition allows to define wide char strings using macros as parameters. See the definition of __CONCAT in newlib's sys/cdefs.h and accompanying comment. */ diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc index c4f116728..dc1c4ac17 100644 --- a/winsup/cygwin/spawn.cc +++ b/winsup/cygwin/spawn.cc @@ -351,9 +351,8 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv, We need to quote any argument that has whitespace or embedded "'s. */ int ac; - size_t arg_len = 0; for (ac = 0; argv[ac]; ac++) - arg_len += strlen (argv[ac]) + 1; + ; int err; const char *ext; @@ -522,12 +521,6 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv, __leave; } set (chtype, real_path.iscygexec ()); - if (iscygwin () && arg_len > (size_t) sysconf (_SC_ARG_MAX)) - { - set_errno (E2BIG); - res = -1; - __leave; - } __stdin = in__stdin; __stdout = in__stdout; record_children (); @@ -1130,11 +1123,16 @@ spawnvpe (int mode, const char *file, const char * const *argv, int av::setup (const char *prog_arg, path_conv& real_path, const char *ext, - int argc, const char *const *argv, bool p_type_exec) + int ac_in, const char *const *av_in, bool p_type_exec) { const char *p; bool exeext = ascii_strcasematch (ext, ".exe"); - new (this) av (argc, argv); + new (this) av (ac_in, av_in); + if (!argc) + { + set_errno (E2BIG); + return -1; + } if ((exeext && real_path.iscygexec ()) || ascii_strcasematch (ext, ".bat") || (!*ext && ((p = ext - 4) > real_path.get_win32 ()) && (ascii_strcasematch (p, ".bat") || ascii_strcasematch (p, ".cmd") diff --git a/winsup/cygwin/sysconf.cc b/winsup/cygwin/sysconf.cc index 7cdfbdb9d..6529731a5 100644 --- a/winsup/cygwin/sysconf.cc +++ b/winsup/cygwin/sysconf.cc @@ -485,7 +485,7 @@ static struct }; } sca[] = { - {cons, {c:CYG_ARG_MAX}}, /* 0, _SC_ARG_MAX */ + {cons, {c:-1L}}, /* 0, _SC_ARG_MAX */ {cons, {c:CHILD_MAX}}, /* 1, _SC_CHILD_MAX */ {cons, {c:CLOCKS_PER_SEC}}, /* 2, _SC_CLK_TCK */ {cons, {c:NGROUPS_MAX}}, /* 3, _SC_NGROUPS_MAX */ |