Cygwin: pinfo: use stpcpy where appropriate
[newlib-cygwin.git] / winsup / cygwin / winf.cc
blobd0c5c440fbe0c972fc97f69b7c174b4936757be3
1 /* winf.cc
3 This software is a copyrighted work licensed under the terms of the
4 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
5 details. */
7 #include "winsup.h"
8 #include <stdlib.h>
9 #include "cygerrno.h"
10 #include "security.h"
11 #include "path.h"
12 #include "fhandler.h"
13 #include "dtable.h"
14 #include "cygheap.h"
15 #include "tls_pbuf.h"
16 #include "winf.h"
17 #include "sys/cygwin.h"
19 void
20 linebuf::finish (bool cmdlenoverflow_ok)
22 if (!ix)
23 add ("", 1);
24 else
26 if (ix-- > MAXCYGWINCMDLEN && cmdlenoverflow_ok)
27 ix = MAXCYGWINCMDLEN - 1;
28 buf[ix] = '\0';
32 void
33 linebuf::add (const char *what, int len)
35 size_t newix = ix + len;
36 if (newix >= alloced || !buf)
38 alloced += LINE_BUF_CHUNK + newix;
39 buf = (char *) realloc (buf, alloced + 1);
41 memcpy (buf + ix, what, len);
42 ix = newix;
43 buf[ix] = '\0';
46 void
47 linebuf::prepend (const char *what, int len)
49 int buflen;
50 size_t newix;
51 if ((newix = ix + len) >= alloced)
53 alloced += LINE_BUF_CHUNK + newix;
54 buf = (char *) realloc (buf, alloced + 1);
55 buf[ix] = '\0';
57 if ((buflen = strlen (buf)))
58 memmove (buf + len, buf, buflen + 1);
59 else
60 buf[newix] = '\0';
61 memcpy (buf, what, len);
62 ix = newix;
65 bool
66 linebuf::fromargv (av& newargv, const char *real_path, bool cmdlenoverflow_ok)
68 bool success = true;
69 for (int i = 0; i < newargv.argc; i++)
71 char *p = NULL;
72 const char *a;
74 a = i ? newargv[i] : (char *) real_path;
75 int len = strlen (a);
76 if (len != 0 && !strpbrk (a, " \t\n\r\""))
77 add (a, len);
78 else
80 add ("\"", 1);
81 /* Handle embedded special characters " and \.
82 A " is always preceded by a \.
83 A \ is not special unless it precedes a ". If it does,
84 then all preceding \'s must be doubled to avoid having
85 the Windows command line parser interpret the \ as quoting
86 the ". This rule applies to a string of \'s before the end
87 of the string, since cygwin/windows uses a " to delimit the
88 argument. */
89 for (; (p = strpbrk (a, "\"\\")); a = ++p)
91 add (a, p - a);
92 /* Find length of string of backslashes */
93 int n = strspn (p, "\\");
94 if (!n)
95 add ("\\\"", 2); /* No backslashes, so it must be a ".
96 The " has to be protected with a backslash. */
97 else
99 add (p, n); /* Add the run of backslashes */
100 /* Need to double up all of the preceding
101 backslashes if they precede a quote or EOS. */
102 if (!p[n] || p[n] == '"')
103 add (p, n);
104 p += n - 1; /* Point to last backslash */
107 if (*a)
108 add (a);
109 add ("\"", 1);
111 add (" ", 1);
114 finish (cmdlenoverflow_ok);
116 if (ix >= MAXWINCMDLEN)
118 debug_printf ("command line too long (>32K), return E2BIG");
119 set_errno (E2BIG);
120 success = false;
123 return success;
127 av::unshift (const char *what)
129 char **av;
130 av = (char **) crealloc (argv, (argc + 2) * sizeof (char *));
131 if (!av)
132 return 0;
134 argv = av;
135 memmove (argv + 1, argv, (argc + 1) * sizeof (char *));
136 *argv = cstrdup1 (what);
137 calloced++;
138 argc++;
139 return 1;