1
0
mirror of https://https.git.savannah.gnu.org/git/gnulib.git synced 2026-06-15 23:35:50 +00:00
Files
Paul Eggert 1e4ece4ab9 * doc/gnulib-tool.texi (Initial import): Update to match current
behavior with strdup module.
* lib/.cppi-disable: Remove strcase.h, strdup.h, strndup.h, strnlen.h.
* lib/memmem.h: Remove; all uses removed.  This is now done
by <string.h>.
* lib/mempcpy.h: Likewise.
* lib/memrchr.h: Likewise.
* lib/stpcpy.h: Likewise.
* lib/stpncpy.h: Likewise.
* lib/strcase.h: Likewise.
* lib/strchrnul.h: Likewise.
* lib/strdup.h: Likewise.
* lib/strndup.h: Likewise.
* lib/strnlen.h: Likewise.
* lib/strpbrk.h: Likewise.
* lib/strsep.h: Likewise.
* lib/strstr.h: Likewise.
* lib/strtok_r.h: Likewise.
* lib/string_.h: New file.
* lib/argp-namefrob.h: Don't include no-longer-existent include files.
Rely on <string.h> instead.
* lib/canon-host.c: Likewise.
* lib/chdir-long.c: Likewise.
* lib/concatpath.c: Likewise.
* lib/exclude.c: Likewise.
* lib/fchdir.c: Likewise.
* lib/getaddrinfo.c: Likewise.
* lib/getcwd.c: Likewise.
* lib/getsubopt.c: Likewise.
* lib/glob.c: Likewise.
* lib/hard-locale.c: Likewise.
* lib/iconvme.c: Likewise.
* lib/javacomp.c: Likewise.
* lib/mempcpy.c: Likewise.
* lib/memrchr.c: Likewise.
* lib/regex_internal.h: Likewise.
* lib/stpncpy.c: Likewise.
* lib/strcasecmp.c: Likewise.
* lib/strchrnul.c: Likewise.
* lib/strdup.c: Likewise.
* lib/striconv.c: Likewise.
* lib/striconveh.c: Likewise.
* lib/striconveha.c: Likewise.
* lib/strncasecmp.c: Likewise.
* lib/strndup.c: Likewise.
* lib/strnlen.c: Likewise.
* lib/strsep.c: Likewise.
* lib/strstr.c: Likewise.
* lib/strtok_r.c: Likewise.
* lib/userspec.c: Likewise.
* lib/w32spawn.h: Likewise.
* lib/xstrndup.c: Likewise.
* lib/mountlist.c (strstr): Remove decl.
* m4/string_h.m4: New file.
* m4/memmem.m4 (gl_FUNC_MEMMEM): Set HAVE_DECL_MEMMEM if necessary.
* m4/mempcpy.m4 (gl_FUNC_MEMPCPY): Set HAVE_MEMPCPY if necessary.
* m4/memrchr.m4 (gl_FUNC_MEMRCHR): Set HAVE_MEMRCHR
* m4/stpcpy.m4 (gl_FUNC_STPCPY): Set HAVE_STPCPY if necessary.
* m4/stpncpy.m4 (gl_PREREQ_STPNCPY): Set HAVE_STPNCPY if necessary.
* m4/strcase.m4 (gl_FUNC_STRCASECMP):
Set REPLACE_STRCASECMP if necessary.
(gl_FUNC_STRNCASECMP): Set HAVE_DECL_STRNCASECMP if necessary.
* m4/strchrnul.m4 (gl_FUNC_STRCHRNUL): Set HAVE_STRCHRNUL if necessary.
* m4/strdup.m4 (gl_FUNC_STRDUP): Set HAVE_DECL_STRDUP if necessary.
* m4/strndup.m4 (gl_FUNC_STRNDUP): Set HAVE_DECL_STRNLEN and
HAVE_DECL_STRDUP if necessary.
(gl_PREREQ_STRNLEN): Don't bother to check for strnlen decl,
since gl_FUNC_STRNDUP does that now.
* m4/strnlen.m4 (gl_FUNC_STRNLEN): Set HAVE_DECL_STRNLEN if necessary.
Check for decl here...
(gl_PREREQ_STRNLEN): ... not here.
* m4/strpbrk.m4 (gl_FUNC_STRPBRK): Set HAVE_STRPBRK if necessary.
* m4/strsep.m4 (gl_FUNC_STRSEP): Set HAVE_STRSEP if necessary.
* m4/strstr.m4 (gl_FUNC_STRSTR): Set REPLACE_STRSTR if necessary.
* m4/strtok_r.m4 (gl_FUNC_STRTOK_R): Set HAVE_DECL_STRTOK_R if
necessary.
* modules/string: New file.
* modules/memmem (Files): Remove special-purpose include file.
(Depends-on): Add string.
(Include): Include <string.h>, not the removed file.
* modules/mempcpy: Likewise.
* modules/memrchr: Likewise.
* modules/stpcpy: Likewise.
* modules/stpncpy: Likewise.
* modules/strcase: Likewise.
* modules/strchrnul: Likewise.
* modules/strdup: Likewise.
* modules/strndup: Likewise.
* modules/strnlen: Likewise.
* modules/strpbrk: Likewise.
* modules/strsep: Likewise.
* modules/strstr: Likewise.
* modules/strtok_r: Likewise.
* tests/test-dirname.c: Don't include "stdup.h", since
<string.h> now suffices.
* tests/test-memmem.c: Don't include "memmem.h", since
<string.h> now suffices.
2007-01-26 22:16:55 +00:00

170 lines
5.0 KiB
C

/* Auxiliary functions for the creation of subprocesses. Native Woe32 API.
Copyright (C) 2003, 2006, 2007 Free Software Foundation, Inc.
Written by Bruno Haible <bruno@clisp.org>, 2003.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software Foundation,
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
/* Get declarations of the Win32 API functions. */
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
/* Get _get_osfhandle() and _open_osfhandle(). */
#include <io.h>
#include <stdbool.h>
#include <string.h>
#include <errno.h>
#include "xalloc.h"
/* Duplicates a file handle, making the copy uninheritable. */
static int
dup_noinherit (int fd)
{
HANDLE curr_process = GetCurrentProcess ();
HANDLE old_handle = (HANDLE) _get_osfhandle (fd);
HANDLE new_handle;
int nfd;
if (!DuplicateHandle (curr_process, /* SourceProcessHandle */
old_handle, /* SourceHandle */
curr_process, /* TargetProcessHandle */
(PHANDLE) &new_handle, /* TargetHandle */
(DWORD) 0, /* DesiredAccess */
FALSE, /* InheritHandle */
DUPLICATE_SAME_ACCESS)) /* Options */
error (EXIT_FAILURE, 0, _("DuplicateHandle failed with error code 0x%08x"),
GetLastError ());
nfd = _open_osfhandle ((long) new_handle, O_BINARY);
if (nfd < 0)
error (EXIT_FAILURE, errno, _("_open_osfhandle failed"));
return nfd;
}
/* Prepares an argument vector before calling spawn().
Note that spawn() does not by itself call the command interpreter
(getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") :
({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&v);
v.dwPlatformId == VER_PLATFORM_WIN32_NT;
}) ? "cmd.exe" : "command.com").
Instead it simply concatenates the arguments, separated by ' ', and calls
CreateProcess(). We must quote the arguments since Win32 CreateProcess()
interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a
special way:
- Space and tab are interpreted as delimiters. They are not treated as
delimiters if they are surrounded by double quotes: "...".
- Unescaped double quotes are removed from the input. Their only effect is
that within double quotes, space and tab are treated like normal
characters.
- Backslashes not followed by double quotes are not special.
- But 2*n+1 backslashes followed by a double quote become
n backslashes followed by a double quote (n >= 0):
\" -> "
\\\" -> \"
\\\\\" -> \\"
*/
#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
static char **
prepare_spawn (char **argv)
{
size_t argc;
char **new_argv;
size_t i;
/* Count number of arguments. */
for (argc = 0; argv[argc] != NULL; argc++)
;
/* Allocate new argument vector. */
new_argv = XNMALLOC (argc + 1, char *);
/* Put quoted arguments into the new argument vector. */
for (i = 0; i < argc; i++)
{
const char *string = argv[i];
if (string[0] == '\0')
new_argv[i] = xstrdup ("\"\"");
else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL)
{
bool quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL);
size_t length;
unsigned int backslashes;
const char *s;
char *quoted_string;
char *p;
length = 0;
backslashes = 0;
if (quote_around)
length++;
for (s = string; *s != '\0'; s++)
{
char c = *s;
if (c == '"')
length += backslashes + 1;
length++;
if (c == '\\')
backslashes++;
else
backslashes = 0;
}
if (quote_around)
length += backslashes + 1;
quoted_string = (char *) xmalloc (length + 1);
p = quoted_string;
backslashes = 0;
if (quote_around)
*p++ = '"';
for (s = string; *s != '\0'; s++)
{
char c = *s;
if (c == '"')
{
unsigned int j;
for (j = backslashes + 1; j > 0; j--)
*p++ = '\\';
}
*p++ = c;
if (c == '\\')
backslashes++;
else
backslashes = 0;
}
if (quote_around)
{
unsigned int j;
for (j = backslashes; j > 0; j--)
*p++ = '\\';
*p++ = '"';
}
*p = '\0';
new_argv[i] = quoted_string;
}
else
new_argv[i] = (char *) string;
}
new_argv[argc] = NULL;
return new_argv;
}