From 99d7d12af0bd6e08312a3c9c41b507d68d9c9662 Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Wed, 13 Sep 2000 19:57:00 +0000 Subject: [PATCH] * spawn.cc (av): Hide 'calloced' field and limit cstrduping to class methods only. (spawn_guts): Use methods for manipulating most newargv stuff. * child_info.h (child_info_spawn::~child_info_spawn): Avoid memory leaks in cygheap. * spawn.cc (spawn_guts): Ditto. * dcrt0.cc (quoted): Return next character after a quoted string when not doing special quote processing. Also ensure that non-NULL is returned in all circumstances. * spawn.cc (spawn_guts): Ensure that argv[0] is correctly set to the full path when a script is detected. Suggested by Kazuhiro Fujieda . --- winsup/cygwin/ChangeLog | 24 +++++++++++++++++++ winsup/cygwin/child_info.h | 4 ++++ winsup/cygwin/dcrt0.cc | 2 +- winsup/cygwin/spawn.cc | 49 +++++++++++++++++++++++++++----------- 4 files changed, 64 insertions(+), 15 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 479fb7263..dc73370d3 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,27 @@ +Wed Sep 13 14:56:47 2000 Christopher Faylor + + * spawn.cc (av): Hide 'calloced' field and limit cstrduping to class + methods only. + (spawn_guts): Use methods for manipulating most newargv stuff. + +2000-09-13 Egor Duda + + * child_info.h (child_info_spawn::~child_info_spawn): Avoid + memory leaks in cygheap. + * spawn.cc (spawn_guts): Ditto. + +Wed Sep 13 14:28:03 2000 Christopher Faylor + + * dcrt0.cc (quoted): Return next character after a quoted string when + not doing special quote processing. Also ensure that non-NULL is + returned in all circumstances. + +Wed Sep 13 10:26:16 2000 Christopher Faylor + + * spawn.cc (spawn_guts): Ensure that argv[0] is correctly set to the + full path when a script is detected. Suggested by Kazuhiro Fujieda + . + Tue Sep 12 22:33:30 2000 Christopher Faylor * external.cc (fillout_pinfo): Handle explicit pids correctly. diff --git a/winsup/cygwin/child_info.h b/winsup/cygwin/child_info.h index 8e76ca399..afea34b02 100644 --- a/winsup/cygwin/child_info.h +++ b/winsup/cygwin/child_info.h @@ -87,6 +87,10 @@ public: { if (moreinfo->old_title) cfree (moreinfo->old_title); + if (moreinfo->cwd_posix) + cfree (moreinfo->cwd_posix); + if (moreinfo->cwd_win32) + cfree (moreinfo->cwd_win32); if (moreinfo->environ) { for (char **e = moreinfo->environ; *e; e++) diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc index ac67eb807..9d3db236e 100644 --- a/winsup/cygwin/dcrt0.cc +++ b/winsup/cygwin/dcrt0.cc @@ -307,7 +307,7 @@ quoted (char *cmd, int winshell) strcpy (cmd, cmd + 1); if ((p = strchr (cmd, quote)) != NULL) strcpy (p, p + 1); - return p + 1; + return p; } /* This must have been run from a Windows shell, so preserve diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc index c7813a3c3..f396311ea 100644 --- a/winsup/cygwin/spawn.cc +++ b/winsup/cygwin/spawn.cc @@ -244,14 +244,13 @@ exec_fixup_after_fork () hexec_proc = NULL; } -struct av +class av { - int argc; - int calloced; -private: char **argv; + int calloced; public: - av (int ac, const char * const *av) : argc (ac), calloced (0) + int argc; + av (int ac, const char * const *av) : calloced (0), argc (ac) { argv = (char **) cmalloc (HEAP_ARGV, (argc + 1) * sizeof (char *)); memcpy (argv, av, (argc + 1) * sizeof (char *)); @@ -264,6 +263,26 @@ public: } int unshift (const char *what, int conv = 0); operator char **() {return argv;} + void all_calloced () {calloced = argc;} + void replace0_maybe (const char *arg0) + { + /* Note: Assumes that argv array has not yet been "unshifted" */ + if (!calloced) + { + argv[0] = cstrdup (arg0); + calloced = 1; + } + } + void *dup_maybe (int i) + { + if (i >= calloced) + argv[i] = cstrdup (argv[i]); + } + void dup_all () + { + for (int i = calloced; i < argc; i++) + argv[i] = cstrdup (argv[i]); + } }; int @@ -303,7 +322,6 @@ spawn_guts (HANDLE hToken, const char * prog_arg, const char *const *argv, MALLOC_CHECK; -// if (strstr (prog_arg, "dopath")) try_to_debug (); if (prog_arg == NULL) { syscall_printf ("prog_arg is NULL"); @@ -417,18 +435,18 @@ spawn_guts (HANDLE hToken, const char * prog_arg, const char *const *argv, if (buf[0] == 'M' && buf[1] == 'Z') break; - debug_printf ("%s is a script", prog_arg); + debug_printf ("%s is a script", (char *) real_path); - char *ptr, *pgm, *arg1; + char *pgm, *arg1; if (buf[0] != '#' || buf[1] != '!') { pgm = (char *) "/bin/sh"; - ptr = buf + 2; arg1 = NULL; } else { + char *ptr; pgm = buf + 2; pgm += strspn (pgm, " \t"); for (ptr = pgm, arg1 = NULL; @@ -453,10 +471,13 @@ spawn_guts (HANDLE hToken, const char * prog_arg, const char *const *argv, *ptr = '\0'; } + /* Replace argv[0] with the full path to the script if this is the + first time through the loop. */ + newargv.replace0_maybe (real_path); + /* pointers: * pgm interpreter name * arg1 optional string - * ptr end of string */ if (arg1) newargv.unshift (arg1); @@ -466,8 +487,7 @@ spawn_guts (HANDLE hToken, const char * prog_arg, const char *const *argv, } if (real_path.iscygexec ()) - for (int i = newargv.calloced; i < newargv.argc; i++) - newargv[i] = cstrdup (newargv[i]); + newargv.dup_all (); else { for (int i = 0; i < newargv.argc; i++) @@ -475,8 +495,7 @@ spawn_guts (HANDLE hToken, const char * prog_arg, const char *const *argv, char *p = NULL; const char *a; - if (i >= newargv.calloced) - newargv[i] = cstrdup (newargv[i]); + newargv.dup_maybe (i); a = newargv[i]; int len = strlen (a); if (len != 0 && !strpbrk (a, " \t\n\r\"")) @@ -507,6 +526,8 @@ spawn_guts (HANDLE hToken, const char * prog_arg, const char *const *argv, one_line.add ("", 1); MALLOC_CHECK; } + + newargv.all_calloced (); ciresrv.moreinfo->argc = newargv.argc; ciresrv.moreinfo->argv = newargv;