From 4b52ca1faf383ec124745ad9782b6fb0735320b0 Mon Sep 17 00:00:00 2001 From: KO Myung-Hun Date: Sat, 4 May 2013 14:04:14 +0900 Subject: [PATCH] pipe_filter_ii_execute: port to OS/2 kLIBC Pipes on kLIBC does not support O_NONBLOCK like Win32. * lib/pipe-filter-ii.c (start_wrapper, _beginthreadex, CloseHandle, WaiForSingleObject, WaitForMultipleObjects): New on OS/2 kLIBC. Reuse Win32 codes on OS/2 kLIBC. * lib/spawn-pipe.c: Reuse Win32 codes on OS/2 kLIBC. * lib/w32spawn.h: Do not include windows.h on OS/2 kLIBC. --- lib/pipe-filter-ii.c | 133 +++++++++++++++++++++++++++++++++++++++++++++++++-- lib/spawn-pipe.c | 6 ++- lib/w32spawn.h | 6 ++- 3 files changed, 137 insertions(+), 8 deletions(-) diff --git a/lib/pipe-filter-ii.c b/lib/pipe-filter-ii.c index db398d2..27037e5 100644 --- a/lib/pipe-filter-ii.c +++ b/lib/pipe-filter-ii.c @@ -27,6 +27,127 @@ #include #if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ # include +#elif defined __KLIBC__ +# define INCL_DOS +# include + +/* 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 # include @@ -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 diff --git a/lib/spawn-pipe.c b/lib/spawn-pipe.c index 656980d..ab7cc18 100644 --- a/lib/spawn-pipe.c +++ b/lib/spawn-pipe.c @@ -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 @@ -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 diff --git a/lib/w32spawn.h b/lib/w32spawn.h index 16f1251..1346773 100644 --- a/lib/w32spawn.h +++ b/lib/w32spawn.h @@ -15,9 +15,11 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ +#ifndef __KLIBC__ /* Get declarations of the native Windows API functions. */ -#define WIN32_LEAN_AND_MEAN -#include +# define WIN32_LEAN_AND_MEAN +# include +#endif /* Get _open_osfhandle(). */ #include -- 1.8.5.2