>From 093ce865871947a28e20fd3802fd828d229d09c0 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Sun, 29 Nov 2020 18:37:33 +0100 Subject: [PATCH] spawn-pipe: Fix build on OS/2 kLIBC (regression 2020-11-28). * lib/os2-spawn.h: New file, based on lib/windows-spawn.h. * lib/os2-spawn.c: New file, based on lib/windows-spawn.c. * lib/spawn-pipe.c: On OS/2 kLIBC, include "os2-spawn.h". * lib/windows-spawn.c: Remove modifications for kLIBC. * modules/spawn-pipe (Files): Add the new files. (configure.ac): Arrange to compile os2-spawn.c on OS/2. --- ChangeLog | 10 ++++ lib/os2-spawn.c | 128 ++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/os2-spawn.h | 32 +++++++++++++ lib/spawn-pipe.c | 8 +++- lib/windows-spawn.c | 15 ++---- modules/spawn-pipe | 8 ++++ 6 files changed, 189 insertions(+), 12 deletions(-) create mode 100644 lib/os2-spawn.c create mode 100644 lib/os2-spawn.h diff --git a/ChangeLog b/ChangeLog index fa21e9c..d6fd4ac 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2020-11-29 Bruno Haible + + spawn-pipe: Fix build on OS/2 kLIBC (regression 2020-11-28). + * lib/os2-spawn.h: New file, based on lib/windows-spawn.h. + * lib/os2-spawn.c: New file, based on lib/windows-spawn.c. + * lib/spawn-pipe.c: On OS/2 kLIBC, include "os2-spawn.h". + * lib/windows-spawn.c: Remove modifications for kLIBC. + * modules/spawn-pipe (Files): Add the new files. + (configure.ac): Arrange to compile os2-spawn.c on OS/2. + 2020-11-28 Bruno Haible asyncsafe-spin: Fix compilation error with GCC on 32-bit SPARC. diff --git a/lib/os2-spawn.c b/lib/os2-spawn.c new file mode 100644 index 0000000..c15e200 --- /dev/null +++ b/lib/os2-spawn.c @@ -0,0 +1,128 @@ +/* Auxiliary functions for the creation of subprocesses. OS/2 kLIBC API. + Copyright (C) 2001, 2003-2020 Free Software Foundation, Inc. + Written by Bruno Haible , 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 3 of the License, 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, see . */ + +#include + +/* Specification. */ +#include "os2-spawn.h" + +/* Get _open_osfhandle(). */ +#include + +#include +#include +#include +#include +#include + +#include "cloexec.h" +#include "error.h" +#include "xalloc.h" +#include "gettext.h" + +#define _(str) gettext (str) + + +/* Duplicates a file handle, making the copy uninheritable. + Returns -1 for a file handle that is equivalent to closed. */ +static int +dup_noinherit (int fd) +{ + fd = dup_cloexec (fd); + if (fd < 0 && errno == EMFILE) + error (EXIT_FAILURE, errno, _("_open_osfhandle failed")); + + return fd; +} + +/* Returns a file descriptor equivalent to FD, except that the resulting file + descriptor is none of STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO. + FD must be open and non-inheritable. The result will be non-inheritable as + well. + If FD < 0, FD itself is returned. */ +static int +fd_safer_noinherit (int fd) +{ + if (STDIN_FILENO <= fd && fd <= STDERR_FILENO) + { + /* The recursion depth is at most 3. */ + int nfd = fd_safer_noinherit (dup_noinherit (fd)); + int saved_errno = errno; + close (fd); + errno = saved_errno; + return nfd; + } + return fd; +} + +int +dup_safer_noinherit (int fd) +{ + return fd_safer_noinherit (dup_noinherit (fd)); +} + +void +undup_safer_noinherit (int tempfd, int origfd) +{ + if (tempfd >= 0) + { + if (dup2 (tempfd, origfd) < 0) + error (EXIT_FAILURE, errno, _("cannot restore fd %d: dup2 failed"), + origfd); + close (tempfd); + } + else + { + /* origfd was closed or open to no handle at all. Set it to a closed + state. This is (nearly) equivalent to the original state. */ + close (origfd); + } +} + +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 (1 + argc + 1, char *); + + /* Add an element upfront that can be used when argv[0] turns out to be a + script, not a program. + On Unix, this would be "/bin/sh". */ + *new_argv++ = "sh.exe"; + + /* 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 + new_argv[i] = (char *) string; + } + new_argv[argc] = NULL; + + return new_argv; +} diff --git a/lib/os2-spawn.h b/lib/os2-spawn.h new file mode 100644 index 0000000..701cc10 --- /dev/null +++ b/lib/os2-spawn.h @@ -0,0 +1,32 @@ +/* Auxiliary functions for the creation of subprocesses. OS/2 kLIBC API. + Copyright (C) 2001, 2003-2020 Free Software Foundation, Inc. + Written by Bruno Haible , 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 3 of the License, 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, see . */ + +#ifndef _OS2_SPAWN_H +#define _OS2_SPAWN_H + +/* Duplicates a file handle, making the copy uninheritable and ensuring the + result is none of STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO. + Returns -1 for a file handle that is equivalent to closed. */ +extern int dup_safer_noinherit (int fd); + +/* Undoes the effect of TEMPFD = dup_safer_noinherit (ORIGFD); */ +extern void undup_safer_noinherit (int tempfd, int origfd); + +/* Prepares an argument vector before calling spawn(). */ +extern char ** prepare_spawn (char **argv); + +#endif /* _OS2_SPAWN_H */ diff --git a/lib/spawn-pipe.c b/lib/spawn-pipe.c index 1a7a1e1..b0f5314 100644 --- a/lib/spawn-pipe.c +++ b/lib/spawn-pipe.c @@ -40,12 +40,18 @@ #define _(str) gettext (str) -#if (defined _WIN32 && ! defined __CYGWIN__) || defined __KLIBC__ +#if defined _WIN32 && ! defined __CYGWIN__ /* Native Windows API. */ # include # include "windows-spawn.h" +#elif defined __KLIBC__ + +/* OS/2 kLIBC API. */ +# include +# include "os2-spawn.h" + #else /* Unix API. */ diff --git a/lib/windows-spawn.c b/lib/windows-spawn.c index eedb7e4..776303a 100644 --- a/lib/windows-spawn.c +++ b/lib/windows-spawn.c @@ -20,11 +20,9 @@ /* Specification. */ #include "windows-spawn.h" -#ifndef __KLIBC__ /* Get declarations of the native Windows API functions. */ -# define WIN32_LEAN_AND_MEAN -# include -#endif +#define WIN32_LEAN_AND_MEAN +#include /* Get _open_osfhandle(). */ #include @@ -106,13 +104,8 @@ undup_safer_noinherit (int tempfd, int origfd) } } -#ifndef __KLIBC__ -# 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" -#else -# define SHELL_SPECIAL_CHARS "" -# define SHELL_SPACE_CHARS "" -#endif +#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" char ** prepare_spawn (char **argv) { diff --git a/modules/spawn-pipe b/modules/spawn-pipe index 2c62586..7845afa 100644 --- a/modules/spawn-pipe +++ b/modules/spawn-pipe @@ -4,6 +4,8 @@ Creation of subprocesses, communicating via pipes. Files: lib/spawn-pipe.h lib/spawn-pipe.c +lib/os2-spawn.h +lib/os2-spawn.c m4/spawn-pipe.m4 Depends-on: @@ -35,6 +37,12 @@ windows-spawn configure.ac: gl_SPAWN_PIPE +AC_REQUIRE([AC_CANONICAL_HOST]) +case "$host_os" in + os2) + AC_LIBOBJ([os2-spawn]) + ;; +esac Makefile.am: lib_SOURCES += spawn-pipe.h spawn-pipe.c -- 2.7.4