* Makefile.in (DLL_OFILES): Add winf.o.
* spawn.cc: Move command line handling stuff into winf.cc. * winf.h: New file. * winf.cc: New file.
This commit is contained in:
		| @@ -1,3 +1,10 @@ | ||||
| 2006-04-11  Christopher Faylor  <cgf@timesys.com> | ||||
|  | ||||
| 	* Makefile.in (DLL_OFILES): Add winf.o. | ||||
| 	* spawn.cc: Move command line handling stuff into winf.cc. | ||||
| 	* winf.h: New file. | ||||
| 	* winf.cc: New file. | ||||
|  | ||||
| 2006-04-05  Christopher Faylor  <cgf@timesys.com> | ||||
|  | ||||
| 	* fhandler_socket.cc: Move iptypes.h include after winsock2 since it | ||||
|   | ||||
| @@ -141,7 +141,7 @@ DLL_OFILES:=assert.o autoload.o bsdlib.o ctype.o cxx.o cygheap.o cygthread.o \ | ||||
| 	sigfe.o signal.o sigproc.o smallprint.o spawn.o strace.o strptime.o \ | ||||
| 	strsep.o strsig.o sync.o syscalls.o sysconf.o syslog.o termios.o thread.o \ | ||||
| 	timelocal.o timer.o times.o tty.o uinfo.o uname.o v8_regexp.o \ | ||||
| 	v8_regerror.o v8_regsub.o wait.o wincap.o window.o \ | ||||
| 	v8_regerror.o v8_regsub.o wait.o wincap.o window.o winf.o \ | ||||
| 	$(EXTRA_DLL_OFILES) $(EXTRA_OFILES) $(MALLOC_OFILES) $(MT_SAFE_OBJECTS) | ||||
|  | ||||
| GMON_OFILES:=gmon.o mcount.o profil.o | ||||
|   | ||||
| @@ -13,7 +13,7 @@ details. */ | ||||
|  | ||||
| #define SP " \t\n" | ||||
|  | ||||
| /* Allow apps which don't have a main work, as long as they define WinMain */ | ||||
| /* Allow apps which don't have a main to work, as long as they define WinMain */ | ||||
| int | ||||
| main () | ||||
| { | ||||
|   | ||||
| @@ -33,9 +33,7 @@ details. */ | ||||
| #include "registry.h" | ||||
| #include "environ.h" | ||||
| #include "cygtls.h" | ||||
|  | ||||
| #define LINE_BUF_CHUNK (CYG_MAX_PATH * 2) | ||||
| #define MAXWINCMDLEN 32767 | ||||
| #include "winf.h" | ||||
|  | ||||
| static suffix_info exe_suffixes[] = | ||||
| { | ||||
| @@ -239,138 +237,6 @@ iscmd (const char *argv0, const char *what) | ||||
| 	 (n == 0 || isdirsep (argv0[n - 1])); | ||||
| } | ||||
|  | ||||
| class linebuf | ||||
| { | ||||
|  public: | ||||
|   size_t ix; | ||||
|   char *buf; | ||||
|   size_t alloced; | ||||
|   linebuf () : ix (0), buf (NULL), alloced (0) {} | ||||
|   ~linebuf () {if (buf) free (buf);} | ||||
|   void add (const char *what, int len) __attribute__ ((regparm (3))); | ||||
|   void add (const char *what) {add (what, strlen (what));} | ||||
|   void prepend (const char *what, int len); | ||||
|   void finish () __attribute__ ((regparm (1))); | ||||
| }; | ||||
|  | ||||
| void | ||||
| linebuf::finish () | ||||
| { | ||||
|   if (!ix) | ||||
|     add ("", 1); | ||||
|   else | ||||
|     buf[--ix] = '\0'; | ||||
| } | ||||
|  | ||||
| void | ||||
| linebuf::add (const char *what, int len) | ||||
| { | ||||
|   size_t newix = ix + len; | ||||
|   if (newix >= alloced || !buf) | ||||
|     { | ||||
|       alloced += LINE_BUF_CHUNK + newix; | ||||
|       buf = (char *) realloc (buf, alloced + 1); | ||||
|     } | ||||
|   memcpy (buf + ix, what, len); | ||||
|   ix = newix; | ||||
|   buf[ix] = '\0'; | ||||
| } | ||||
|  | ||||
| void | ||||
| linebuf::prepend (const char *what, int len) | ||||
| { | ||||
|   int buflen; | ||||
|   size_t newix; | ||||
|   if ((newix = ix + len) >= alloced) | ||||
|     { | ||||
|       alloced += LINE_BUF_CHUNK + newix; | ||||
|       buf = (char *) realloc (buf, alloced + 1); | ||||
|       buf[ix] = '\0'; | ||||
|     } | ||||
|   if ((buflen = strlen (buf))) | ||||
|       memmove (buf + len, buf, buflen + 1); | ||||
|   else | ||||
|       buf[newix] = '\0'; | ||||
|   memcpy (buf, what, len); | ||||
|   ix = newix; | ||||
| } | ||||
|  | ||||
| class av | ||||
| { | ||||
|   char **argv; | ||||
|   int calloced; | ||||
|  public: | ||||
|   int argc; | ||||
|   bool win16_exe; | ||||
|   bool iscui; | ||||
|   av (): argv (NULL), iscui (false) {} | ||||
|   av (int ac_in, const char * const *av_in) : calloced (0), argc (ac_in), win16_exe (false), iscui (false) | ||||
|   { | ||||
|     argv = (char **) cmalloc (HEAP_1_ARGV, (argc + 5) * sizeof (char *)); | ||||
|     memcpy (argv, av_in, (argc + 1) * sizeof (char *)); | ||||
|   } | ||||
|   void *operator new (size_t, void *p) __attribute__ ((nothrow)) {return p;} | ||||
|   void set (int ac_in, const char * const *av_in) {new (this) av (ac_in, av_in);} | ||||
|   ~av () | ||||
|   { | ||||
|     if (argv) | ||||
|       { | ||||
| 	for (int i = 0; i < calloced; i++) | ||||
| 	  if (argv[i]) | ||||
| 	    cfree (argv[i]); | ||||
| 	cfree (argv); | ||||
|       } | ||||
|   } | ||||
|   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] = cstrdup1 (arg0); | ||||
| 	calloced = true; | ||||
|       } | ||||
|   } | ||||
|   void dup_maybe (int i) | ||||
|   { | ||||
|     if (i >= calloced) | ||||
|       argv[i] = cstrdup1 (argv[i]); | ||||
|   } | ||||
|   void dup_all () | ||||
|   { | ||||
|     for (int i = calloced; i < argc; i++) | ||||
|       argv[i] = cstrdup1 (argv[i]); | ||||
|   } | ||||
|   int fixup (const char *, path_conv&, const char *); | ||||
| }; | ||||
|  | ||||
| int | ||||
| av::unshift (const char *what, int conv) | ||||
| { | ||||
|   char **av; | ||||
|   av = (char **) crealloc (argv, (argc + 2) * sizeof (char *)); | ||||
|   if (!av) | ||||
|     return 0; | ||||
|  | ||||
|   argv = av; | ||||
|   memmove (argv + 1, argv, (argc + 1) * sizeof (char *)); | ||||
|   char buf[CYG_MAX_PATH]; | ||||
|   if (conv) | ||||
|     { | ||||
|       cygwin_conv_to_posix_path (what, buf); | ||||
|       char *p = strchr (buf, '\0') - 4; | ||||
|       if (p > buf && strcasematch (p, ".exe")) | ||||
| 	*p = '\0'; | ||||
|       what = buf; | ||||
|     } | ||||
|   *argv = cstrdup1 (what); | ||||
|   calloced++; | ||||
|   argc++; | ||||
|   return 1; | ||||
| } | ||||
|  | ||||
| struct pthread_cleanup | ||||
| { | ||||
|   _sig_func_ptr oldint; | ||||
| @@ -507,65 +373,13 @@ spawn_guts (const char * prog_arg, const char *const *argv, | ||||
|     { | ||||
|       if (real_path.iscygexec ()) | ||||
| 	newargv.dup_all (); | ||||
|       else | ||||
|       else if (!one_line.fromargv (newargv, real_path)) | ||||
| 	{ | ||||
| 	  for (int i = 0; i < newargv.argc; i++) | ||||
| 	    { | ||||
| 	      char *p = NULL; | ||||
| 	      const char *a; | ||||
|  | ||||
| 	      newargv.dup_maybe (i); | ||||
| 	      a = i ? newargv[i] : (char *) real_path; | ||||
| 	      int len = strlen (a); | ||||
| 	      if (len != 0 && !strpbrk (a, " \t\n\r\"")) | ||||
| 		one_line.add (a, len); | ||||
| 	      else | ||||
| 		{ | ||||
| 		  one_line.add ("\"", 1); | ||||
| 		  /* Handle embedded special characters " and \. | ||||
| 		     A " is always preceded by a \. | ||||
| 		     A \ is not special unless it precedes a ".  If it does, | ||||
| 		     then all preceding \'s must be doubled to avoid having | ||||
| 		     the Windows command line parser interpret the \ as quoting | ||||
| 		     the ".  This rule applies to a string of \'s before the end | ||||
| 		     of the string, since cygwin/windows uses a " to delimit the | ||||
| 		     argument. */ | ||||
| 		  for (; (p = strpbrk (a, "\"\\")); a = ++p) | ||||
| 		    { | ||||
| 		      one_line.add (a, p - a); | ||||
| 		      /* Find length of string of backslashes */ | ||||
| 		      int n = strspn (p, "\\"); | ||||
| 		      if (!n) | ||||
| 			one_line.add ("\\\"", 2);	/* No backslashes, so it must be a ". | ||||
| 						       The " has to be protected with a backslash. */ | ||||
| 		      else | ||||
| 			{ | ||||
| 			  one_line.add (p, n);	/* Add the run of backslashes */ | ||||
| 			  /* Need to double up all of the preceding | ||||
| 			     backslashes if they precede a quote or EOS. */ | ||||
| 			  if (!p[n] || p[n] == '"') | ||||
| 			    one_line.add (p, n); | ||||
| 			  p += n - 1;		/* Point to last backslash */ | ||||
| 			} | ||||
| 		    } | ||||
| 		  if (*a) | ||||
| 		    one_line.add (a); | ||||
| 		  one_line.add ("\"", 1); | ||||
| 		} | ||||
| 	      one_line.add (" ", 1); | ||||
| 	    } | ||||
|  | ||||
| 	  one_line.finish (); | ||||
|  | ||||
| 	  if (one_line.ix >= MAXWINCMDLEN) | ||||
| 	    { | ||||
| 	      debug_printf ("command line too long (>32K), return E2BIG"); | ||||
| 	      set_errno (E2BIG); | ||||
| 	      res = -1; | ||||
| 	      goto out; | ||||
| 	    } | ||||
| 	  res = -1; | ||||
| 	  goto out; | ||||
| 	} | ||||
|  | ||||
|  | ||||
|       newargv.all_calloced (); | ||||
|       moreinfo->argc = newargv.argc; | ||||
|       moreinfo->argv = newargv; | ||||
|   | ||||
							
								
								
									
										148
									
								
								winsup/cygwin/winf.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										148
									
								
								winsup/cygwin/winf.cc
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,148 @@ | ||||
| /* winf.cc | ||||
|  | ||||
|    Copyright 2003, 2004, 2005, 2006 Red Hat, Inc. | ||||
|  | ||||
| This software is a copyrighted work licensed under the terms of the | ||||
| Cygwin license.  Please consult the file "CYGWIN_LICENSE" for | ||||
| details. */ | ||||
|  | ||||
| #include "winsup.h" | ||||
| #include <stdlib.h> | ||||
| #include "cygerrno.h" | ||||
| #include "security.h" | ||||
| #include "sync.h" | ||||
| #include "path.h" | ||||
| #include "fhandler.h" | ||||
| #include "dtable.h" | ||||
| #include "cygheap.h" | ||||
| #include "winf.h" | ||||
| #include "sys/cygwin.h" | ||||
|  | ||||
| void | ||||
| linebuf::finish () | ||||
| { | ||||
|   if (!ix) | ||||
|     add ("", 1); | ||||
|   else | ||||
|     buf[--ix] = '\0'; | ||||
| } | ||||
|  | ||||
| void | ||||
| linebuf::add (const char *what, int len) | ||||
| { | ||||
|   size_t newix = ix + len; | ||||
|   if (newix >= alloced || !buf) | ||||
|     { | ||||
|       alloced += LINE_BUF_CHUNK + newix; | ||||
|       buf = (char *) realloc (buf, alloced + 1); | ||||
|     } | ||||
|   memcpy (buf + ix, what, len); | ||||
|   ix = newix; | ||||
|   buf[ix] = '\0'; | ||||
| } | ||||
|  | ||||
| void | ||||
| linebuf::prepend (const char *what, int len) | ||||
| { | ||||
|   int buflen; | ||||
|   size_t newix; | ||||
|   if ((newix = ix + len) >= alloced) | ||||
|     { | ||||
|       alloced += LINE_BUF_CHUNK + newix; | ||||
|       buf = (char *) realloc (buf, alloced + 1); | ||||
|       buf[ix] = '\0'; | ||||
|     } | ||||
|   if ((buflen = strlen (buf))) | ||||
|       memmove (buf + len, buf, buflen + 1); | ||||
|   else | ||||
|       buf[newix] = '\0'; | ||||
|   memcpy (buf, what, len); | ||||
|   ix = newix; | ||||
| } | ||||
|  | ||||
| bool | ||||
| linebuf::fromargv (av& newargv, char *real_path) | ||||
| { | ||||
|   bool success = true; | ||||
|   for (int i = 0; i < newargv.argc; i++) | ||||
|     { | ||||
|       char *p = NULL; | ||||
|       const char *a; | ||||
|  | ||||
|       newargv.dup_maybe (i); | ||||
|       a = i ? newargv[i] : (char *) real_path; | ||||
|       int len = strlen (a); | ||||
|       if (len != 0 && !strpbrk (a, " \t\n\r\"")) | ||||
| 	add (a, len); | ||||
|       else | ||||
| 	{ | ||||
| 	  add ("\"", 1); | ||||
| 	  /* Handle embedded special characters " and \. | ||||
| 	     A " is always preceded by a \. | ||||
| 	     A \ is not special unless it precedes a ".  If it does, | ||||
| 	     then all preceding \'s must be doubled to avoid having | ||||
| 	     the Windows command line parser interpret the \ as quoting | ||||
| 	     the ".  This rule applies to a string of \'s before the end | ||||
| 	     of the string, since cygwin/windows uses a " to delimit the | ||||
| 	     argument. */ | ||||
| 	  for (; (p = strpbrk (a, "\"\\")); a = ++p) | ||||
| 	    { | ||||
| 	      add (a, p - a); | ||||
| 	      /* Find length of string of backslashes */ | ||||
| 	      int n = strspn (p, "\\"); | ||||
| 	      if (!n) | ||||
| 		add ("\\\"", 2);	/* No backslashes, so it must be a ". | ||||
| 					       The " has to be protected with a backslash. */ | ||||
| 	      else | ||||
| 		{ | ||||
| 		  add (p, n);	/* Add the run of backslashes */ | ||||
| 		  /* Need to double up all of the preceding | ||||
| 		     backslashes if they precede a quote or EOS. */ | ||||
| 		  if (!p[n] || p[n] == '"') | ||||
| 		    add (p, n); | ||||
| 		  p += n - 1;		/* Point to last backslash */ | ||||
| 		} | ||||
| 	    } | ||||
| 	  if (*a) | ||||
| 	    add (a); | ||||
| 	  add ("\"", 1); | ||||
| 	} | ||||
|       add (" ", 1); | ||||
|     } | ||||
|  | ||||
|   finish (); | ||||
|  | ||||
|   if (ix >= MAXWINCMDLEN) | ||||
|     { | ||||
|       debug_printf ("command line too long (>32K), return E2BIG"); | ||||
|       set_errno (E2BIG); | ||||
|       success = false; | ||||
|     } | ||||
|  | ||||
|   return success; | ||||
| } | ||||
|  | ||||
| int | ||||
| av::unshift (const char *what, int conv) | ||||
| { | ||||
|   char **av; | ||||
|   av = (char **) crealloc (argv, (argc + 2) * sizeof (char *)); | ||||
|   if (!av) | ||||
|     return 0; | ||||
|  | ||||
|   argv = av; | ||||
|   memmove (argv + 1, argv, (argc + 1) * sizeof (char *)); | ||||
|   char buf[CYG_MAX_PATH]; | ||||
|   if (conv) | ||||
|     { | ||||
|       cygwin_conv_to_posix_path (what, buf); | ||||
|       char *p = strchr (buf, '\0') - 4; | ||||
|       if (p > buf && strcasematch (p, ".exe")) | ||||
| 	*p = '\0'; | ||||
|       what = buf; | ||||
|     } | ||||
|   *argv = cstrdup1 (what); | ||||
|   calloced++; | ||||
|   argc++; | ||||
|   return 1; | ||||
| } | ||||
							
								
								
									
										82
									
								
								winsup/cygwin/winf.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								winsup/cygwin/winf.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,82 @@ | ||||
| /* winf.h | ||||
|  | ||||
|    Copyright 2003, 2004, 2005 Red Hat, Inc. | ||||
|  | ||||
| This software is a copyrighted work licensed under the terms of the | ||||
| Cygwin license.  Please consult the file "CYGWIN_LICENSE" for | ||||
| details. */ | ||||
|  | ||||
| #ifndef _WINF_H | ||||
| #define _WINF_H | ||||
|  | ||||
| #define MAXWINCMDLEN 32767 | ||||
| #define LINE_BUF_CHUNK (CYG_MAX_PATH * 2) | ||||
|  | ||||
| class av | ||||
| { | ||||
|   char **argv; | ||||
|   int calloced; | ||||
|  public: | ||||
|   int argc; | ||||
|   bool win16_exe; | ||||
|   bool iscui; | ||||
|   av (): argv (NULL), iscui (false) {} | ||||
|   av (int ac_in, const char * const *av_in) : calloced (0), argc (ac_in), win16_exe (false), iscui (false) | ||||
|   { | ||||
|     argv = (char **) cmalloc (HEAP_1_ARGV, (argc + 5) * sizeof (char *)); | ||||
|     memcpy (argv, av_in, (argc + 1) * sizeof (char *)); | ||||
|   } | ||||
|   void *operator new (size_t, void *p) __attribute__ ((nothrow)) {return p;} | ||||
|   void set (int ac_in, const char * const *av_in) {new (this) av (ac_in, av_in);} | ||||
|   ~av () | ||||
|   { | ||||
|     if (argv) | ||||
|       { | ||||
| 	for (int i = 0; i < calloced; i++) | ||||
| 	  if (argv[i]) | ||||
| 	    cfree (argv[i]); | ||||
| 	cfree (argv); | ||||
|       } | ||||
|   } | ||||
|   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] = cstrdup1 (arg0); | ||||
| 	calloced = true; | ||||
|       } | ||||
|   } | ||||
|   void dup_maybe (int i) | ||||
|   { | ||||
|     if (i >= calloced) | ||||
|       argv[i] = cstrdup1 (argv[i]); | ||||
|   } | ||||
|   void dup_all () | ||||
|   { | ||||
|     for (int i = calloced; i < argc; i++) | ||||
|       argv[i] = cstrdup1 (argv[i]); | ||||
|   } | ||||
|   int fixup (const char *, path_conv&, const char *); | ||||
| }; | ||||
|  | ||||
| class linebuf | ||||
| { | ||||
|  public: | ||||
|   size_t ix; | ||||
|   char *buf; | ||||
|   size_t alloced; | ||||
|   linebuf () : ix (0), buf (NULL), alloced (0) {} | ||||
|   ~linebuf () {if (buf) free (buf);} | ||||
|   void add (const char *what, int len) __attribute__ ((regparm (3))); | ||||
|   void add (const char *what) {add (what, strlen (what));} | ||||
|   void prepend (const char *what, int len); | ||||
|   void finish () __attribute__ ((regparm (1))); | ||||
|   bool fromargv(av&, char *); | ||||
|   operator char *() {return buf;} | ||||
| }; | ||||
|  | ||||
| #endif /*_WINF_H*/ | ||||
		Reference in New Issue
	
	Block a user