]> Savannah Git Hosting - gnulib.git/commitdiff
spawn-pipe: Fix build on OS/2 kLIBC (regression 2020-11-28).
authorBruno Haible <bruno@clisp.org>
Sun, 29 Nov 2020 17:37:33 +0000 (18:37 +0100)
committerBruno Haible <bruno@clisp.org>
Sun, 29 Nov 2020 17:49:19 +0000 (18:49 +0100)
* 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
lib/os2-spawn.c [new file with mode: 0644]
lib/os2-spawn.h [new file with mode: 0644]
lib/spawn-pipe.c
lib/windows-spawn.c
modules/spawn-pipe

index fa21e9cd28abf4acb062ad1d879fd20a723dd7f5..d6fd4aca6782c2e67dd6fe0fb65e15e8d4b7ac06 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2020-11-29  Bruno Haible  <bruno@clisp.org>
+
+       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  <bruno@clisp.org>
 
        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 (file)
index 0000000..c15e200
--- /dev/null
@@ -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 <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 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 <https://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+
+/* Specification.  */
+#include "os2-spawn.h"
+
+/* Get _open_osfhandle().  */
+#include <io.h>
+
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+
+#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 (file)
index 0000000..701cc10
--- /dev/null
@@ -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 <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 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 <https://www.gnu.org/licenses/>.  */
+
+#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 */
index 1a7a1e1662b6ed319fe92d07b3419edac8306f90..b0f53146552fcd06c14cfb3af181b40aebfa88f8 100644 (file)
 
 #define _(str) gettext (str)
 
-#if (defined _WIN32 && ! defined __CYGWIN__) || defined __KLIBC__
+#if defined _WIN32 && ! defined __CYGWIN__
 
 /* Native Windows API.  */
 # include <process.h>
 # include "windows-spawn.h"
 
+#elif defined __KLIBC__
+
+/* OS/2 kLIBC API.  */
+# include <process.h>
+# include "os2-spawn.h"
+
 #else
 
 /* Unix API.  */
index eedb7e4c309db4f16e6ae8a40806da8fc6b8a115..776303abf1174c3bc72cc21f2e001b9b5020e972 100644 (file)
 /* Specification.  */
 #include "windows-spawn.h"
 
-#ifndef __KLIBC__
 /* Get declarations of the native Windows API functions.  */
-# define WIN32_LEAN_AND_MEAN
-# include <windows.h>
-#endif
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
 
 /* Get _open_osfhandle().  */
 #include <io.h>
@@ -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)
 {
index 2c62586e272ae3f43ece27306beecccaba72df6c..7845afa5b3262077ef283b328e33e4fa9c478644 100644 (file)
@@ -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