> 2020-11-28  Bruno Haible  <br...@clisp.org>
> 
>       windows-spawn: New module.

This patch probably introduced a compilation error on OS/2 kLIBC.

Here's a (probable) fix. It copies windows-spawn.[hc] to os2-spawn.[hc].
I will soon modify windows-spawn.[hc], basing it on 'CreateProcess'
instead of '_spawnvpe'. Such modifications are not possible on OS/2,
because there 'spawnvpe' relies on a system call '__spawnve', not
on 'CreateProcess'.


2020-11-29  Bruno Haible  <br...@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.

>From 093ce865871947a28e20fd3802fd828d229d09c0 Mon Sep 17 00:00:00 2001
From: Bruno Haible <br...@clisp.org>
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  <br...@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  <br...@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
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 <br...@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
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 <br...@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 */
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 <process.h>
 # include "windows-spawn.h"
 
+#elif defined __KLIBC__
+
+/* OS/2 kLIBC API.  */
+# include <process.h>
+# 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 <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)
 {
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

Reply via email to