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
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2006-04-12 19:53:22 +0400
committerChristopher Faylor <me@cgf.cx>2006-04-12 19:53:22 +0400
commit329a39ebeaeb5da4006fece1e3a46d975e76e800 (patch)
treea683f5d36768b2c9dcadd30c891853363e401dec /winsup/cygwin/winf.cc
parentbe5542f7168f9cdc40cc20c6a9831143ddfdbdc4 (diff)
* 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/winf.cc')
-rw-r--r--winsup/cygwin/winf.cc148
1 files changed, 148 insertions, 0 deletions
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;
+}