diff options
Diffstat (limited to 'gettext-tools/gnulib-lib/pipe-filter-ii.c')
-rw-r--r-- | gettext-tools/gnulib-lib/pipe-filter-ii.c | 135 |
1 files changed, 130 insertions, 5 deletions
diff --git a/gettext-tools/gnulib-lib/pipe-filter-ii.c b/gettext-tools/gnulib-lib/pipe-filter-ii.c index 88b0d0d..28feb46 100644 --- a/gettext-tools/gnulib-lib/pipe-filter-ii.c +++ b/gettext-tools/gnulib-lib/pipe-filter-ii.c @@ -1,5 +1,5 @@ /* Filtering of data through a subprocess. - Copyright (C) 2001-2003, 2008-2015 Free Software Foundation, Inc. + Copyright (C) 2001-2003, 2008-2016 Free Software Foundation, Inc. Written by Bruno Haible <bruno@clisp.org>, 2009. This program is free software: you can redistribute it and/or modify @@ -27,6 +27,127 @@ #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> @@ -41,7 +162,8 @@ #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 |