summaryrefslogtreecommitdiffstats
path: root/winsup/cygwin
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2006-04-12 15:53:22 +0000
committerChristopher Faylor <me@cgf.cx>2006-04-12 15:53:22 +0000
commit329a39ebeaeb5da4006fece1e3a46d975e76e800 (patch)
treea683f5d36768b2c9dcadd30c891853363e401dec /winsup/cygwin
parentbe5542f7168f9cdc40cc20c6a9831143ddfdbdc4 (diff)
downloadcygnal-329a39ebeaeb5da4006fece1e3a46d975e76e800.tar.gz
cygnal-329a39ebeaeb5da4006fece1e3a46d975e76e800.tar.bz2
cygnal-329a39ebeaeb5da4006fece1e3a46d975e76e800.zip
* 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.
Diffstat (limited to 'winsup/cygwin')
-rw-r--r--winsup/cygwin/ChangeLog7
-rw-r--r--winsup/cygwin/Makefile.in2
-rw-r--r--winsup/cygwin/lib/libcmain.c2
-rw-r--r--winsup/cygwin/spawn.cc196
-rw-r--r--winsup/cygwin/winf.cc148
-rw-r--r--winsup/cygwin/winf.h82
6 files changed, 244 insertions, 193 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index eaf3135e5..0352479fb 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -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
diff --git a/winsup/cygwin/Makefile.in b/winsup/cygwin/Makefile.in
index 665257c63..6d7857017 100644
--- a/winsup/cygwin/Makefile.in
+++ b/winsup/cygwin/Makefile.in
@@ -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
diff --git a/winsup/cygwin/lib/libcmain.c b/winsup/cygwin/lib/libcmain.c
index b0c011999..da2a69839 100644
--- a/winsup/cygwin/lib/libcmain.c
+++ b/winsup/cygwin/lib/libcmain.c
@@ -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 ()
{
diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc
index 8ac3ae039..9d358da0c 100644
--- a/winsup/cygwin/spawn.cc
+++ b/winsup/cygwin/spawn.cc
@@ -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;
diff --git a/winsup/cygwin/winf.cc b/winsup/cygwin/winf.cc
new file mode 100644
index 000000000..01c5cfb65
--- /dev/null
+++ b/winsup/cygwin/winf.cc
@@ -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;
+}
diff --git a/winsup/cygwin/winf.h b/winsup/cygwin/winf.h
new file mode 100644
index 000000000..3b7fec23b
--- /dev/null
+++ b/winsup/cygwin/winf.h
@@ -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*/