Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/winsup
diff options
context:
space:
mode:
Diffstat (limited to 'winsup')
-rw-r--r--winsup/cygwin/dcrt0.cc18
-rw-r--r--winsup/cygwin/kernel32.cc7
-rw-r--r--winsup/cygwin/local_includes/winf.h13
-rw-r--r--winsup/cygwin/local_includes/winsup.h4
-rw-r--r--winsup/cygwin/spawn.cc18
-rw-r--r--winsup/cygwin/sysconf.cc2
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 */