]> Savannah Git Hosting - gnulib.git/commitdiff
pipe_filter_ii_execute: port to OS/2 kLIBC
authorKO Myung-Hun <komh78@gmail.com>
Thu, 14 Jan 2016 02:23:46 +0000 (11:23 +0900)
committerPaul Eggert <eggert@cs.ucla.edu>
Fri, 15 Jan 2016 00:45:38 +0000 (16:45 -0800)
Pipes on kLIBC do not support O_NONBLOCK like Win32.

* lib/pipe-filter-ii.c (start_wrapper, _beginthreadex, CloseHandle,
WaiForSingleObject, WaitForMultipleObjects): New on OS/2 kLIBC.
Reuse Win32 code on OS/2 kLIBC.
* lib/spawn-pipe.c: Reuse Win32 code on OS/2 kLIBC.
* lib/w32spawn.h: Do not include windows.h on OS/2 kLIBC.

lib/pipe-filter-ii.c
lib/spawn-pipe.c
lib/w32spawn.h

index d05d2012f9d93aa6ac44155f34480e45dc9923a9..28feb466fedd60f62d556c6e00308fa8e18a6090 100644 (file)
 #include <unistd.h>
 #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
 # include <windows.h>
+#elif defined __KLIBC__
+# define INCL_DOS
+# include <os2.h>
+
+/* Simple implementation of Win32 APIs */
+
+# define WINAPI
+
+typedef struct _HANDLE
+{
+  TID tid;
+  HEV hevDone;
+  unsigned int WINAPI (*start) (void *);
+  void *arg;
+} *HANDLE;
+
+typedef ULONG DWORD;
+
+static void
+start_wrapper (void *arg)
+{
+  HANDLE h = (HANDLE) arg;
+
+  h->start (h->arg);
+
+  DosPostEventSem (h->hevDone);
+  _endthread ();
+}
+
+static HANDLE
+_beginthreadex (void *s, unsigned n, unsigned int WINAPI (*start) (void *),
+                void *arg, unsigned fl, unsigned *th)
+{
+  HANDLE h;
+
+  h = malloc (sizeof (*h));
+  if (!h)
+    return NULL;
+
+  if (DosCreateEventSem (NULL, &h->hevDone, 0, FALSE))
+    goto exit_free;
+
+  h->start = start;
+  h->arg = arg;
+
+  h->tid = _beginthread (start_wrapper, NULL, n, (void *) h);
+  if (h->tid == -1)
+    goto exit_close_event_sem;
+
+  return h;
+
+ exit_close_event_sem:
+  DosCloseEventSem (h->hevDone);
+
+ exit_free:
+  free (h);
+
+  return NULL;
+}
+
+static BOOL
+CloseHandle (HANDLE h)
+{
+  DosCloseEventSem (h->hevDone);
+  free (h);
+}
+
+# define _endthreadex(x) return (x)
+# define TerminateThread(h, e) DosKillThread (h->tid)
+
+# define GetLastError()  -1
+
+# ifndef ERROR_NO_DATA
+#  define ERROR_NO_DATA 232
+# endif
+
+# define INFINITE SEM_INDEFINITE_WAIT
+# define WAIT_OBJECT_0  0
+
+static DWORD
+WaitForSingleObject (HANDLE h, DWORD ms)
+{
+  return DosWaitEventSem (h->hevDone, ms) == 0 ? WAIT_OBJECT_0 : (DWORD) -1;
+}
+
+static DWORD
+WaitForMultipleObjects (DWORD nCount, const HANDLE *pHandles, BOOL bWaitAll,
+                        DWORD ms)
+{
+  HMUX hmux;
+  PSEMRECORD psr;
+  ULONG ulUser;
+  ULONG rc = (ULONG) -1;
+  DWORD i;
+
+  psr = malloc (sizeof (*psr) * nCount);
+  if (!psr)
+    goto exit_return;
+
+  for (i = 0; i < nCount; ++i)
+    {
+      psr[i].hsemCur = (HSEM) pHandles[i]->hevDone;
+      psr[i].ulUser  = WAIT_OBJECT_0 + i;
+    }
+
+  if (DosCreateMuxWaitSem (NULL, &hmux, nCount, psr,
+                           bWaitAll ? DCMW_WAIT_ALL : DCMW_WAIT_ANY))
+    goto exit_free;
+
+  rc = DosWaitMuxWaitSem (hmux, ms, &ulUser);
+  DosCloseMuxWaitSem (hmux);
+
+ exit_free:
+  free (psr);
+
+ exit_return:
+  if (rc)
+    return (DWORD) -1;
+
+  return ulUser;
+}
 #else
 # include <signal.h>
 # include <sys/select.h>
 
 #include "pipe-filter-aux.h"
 
-#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+#if (((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__) \
+     || defined __KLIBC__)
 
 struct locals
 {
@@ -143,7 +265,8 @@ pipe_filter_ii_execute (const char *progname,
 {
   pid_t child;
   int fd[2];
-#if !((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__)
+#if !(((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__) \
+      || defined __KLIBC__)
   struct sigaction orig_sigpipe_action;
 #endif
 
@@ -154,7 +277,8 @@ pipe_filter_ii_execute (const char *progname,
   if (child == -1)
     return -1;
 
-#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+#if (((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__) \
+     || defined __KLIBC__)
   /* Native Windows API.  */
   /* Pipes have a non-blocking mode, see function SetNamedPipeHandleState and
      the article "Named Pipe Type, Read, and Wait Modes", but Microsoft's
@@ -462,7 +586,8 @@ pipe_filter_ii_execute (const char *progname,
   {
     int saved_errno = errno;
     close (fd[1]);
-#if !((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__)
+#if !(((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__) \
+      || defined __KLIBC__)
     if (sigaction (SIGPIPE, &orig_sigpipe_action, NULL) < 0)
       abort ();
 #endif
index 0f47fe665b096aa0ad8fdfc15f1262cdf071802a..87cebf7f5cc260eb309e7df01b31b76291f18495 100644 (file)
@@ -35,7 +35,8 @@
 
 #define _(str) gettext (str)
 
-#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+#if (((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__) \
+     || defined __KLIBC__)
 
 /* Native Windows API.  */
 # include <process.h>
@@ -109,7 +110,8 @@ create_pipe (const char *progname,
              bool slave_process, bool exit_on_error,
              int fd[2])
 {
-#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+#if (((defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__) \
+     || defined __KLIBC__)
 
   /* Native Windows API.
      This uses _pipe(), dup2(), and spawnv().  It could also be implemented
index e0608fb6e159dda96a7ca264933e9a0162385f0b..389054aa6d50c5bbf5dd1c8ca82a1e58fb94d08f 100644 (file)
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
+#ifndef __KLIBC__
 /* Get declarations of the native Windows API functions.  */
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+#endif
 
 /* Get _open_osfhandle().  */
 #include <io.h>