interim update for pio
- improved qse_pio_wait but not finished it yet
This commit is contained in:
@ -27,8 +27,11 @@
|
||||
# include "syscall.h"
|
||||
# include <fcntl.h>
|
||||
# include <errno.h>
|
||||
# include <sys/wait.h>
|
||||
#endif
|
||||
|
||||
#define CHILD_EXIT_CODE 128
|
||||
|
||||
qse_pio_t* qse_pio_open (
|
||||
qse_mmgr_t* mmgr, qse_size_t ext,
|
||||
const qse_char_t* path, int flags)
|
||||
@ -86,7 +89,9 @@ qse_pio_t* qse_pio_init (
|
||||
|
||||
#ifdef _WIN32
|
||||
/* TODO: XXXXXXXXXXXXXXXXX */
|
||||
http://msdn.microsoft.com/en-us/library/ms682499(VS.85).aspx
|
||||
#else
|
||||
|
||||
if (flags & QSE_PIO_WRITEIN)
|
||||
{
|
||||
if (QSE_PIPE(&handle[0]) == -1) goto oops;
|
||||
@ -298,7 +303,7 @@ qse_pio_t* qse_pio_init (
|
||||
}
|
||||
|
||||
child_oops:
|
||||
QSE_EXIT(127);
|
||||
QSE_EXIT (CHILD_EXIT_CODE);
|
||||
}
|
||||
|
||||
/* parent */
|
||||
@ -352,44 +357,10 @@ oops:
|
||||
|
||||
void qse_pio_fini (qse_pio_t* pio)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
CloseHandle (pio->handle);
|
||||
#else
|
||||
int i, status;
|
||||
|
||||
qse_pio_end (pio, QSE_PIO_IN);
|
||||
qse_pio_end (pio, QSE_PIO_OUT);
|
||||
qse_pio_end (pio, QSE_PIO_ERR);
|
||||
|
||||
while (QSE_WAITPID (pio->child, &status, 0) == -1)
|
||||
{
|
||||
if (errno != EINTR) break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int qse_pio_wait (qse_pio_t* pio)
|
||||
{
|
||||
int status;
|
||||
|
||||
#if 0
|
||||
if (opt & QSE_PIO_NOWAIT)
|
||||
{
|
||||
opt |= WNOHANG;
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
n = QSE_WAITPID (pio->child, &status, opt);
|
||||
if (n == 0) break;
|
||||
/* TODO: .... */
|
||||
}
|
||||
|
||||
|
||||
output => return code...
|
||||
output => termination cause...
|
||||
#endif
|
||||
return -1;
|
||||
qse_pio_wait (pio, QSE_PIO_IGNINTR);
|
||||
}
|
||||
|
||||
qse_pio_hnd_t qse_pio_gethandle (qse_pio_t* pio, qse_pio_hid_t hid)
|
||||
@ -397,6 +368,11 @@ qse_pio_hnd_t qse_pio_gethandle (qse_pio_t* pio, qse_pio_hid_t hid)
|
||||
return pio->handle[hid];
|
||||
}
|
||||
|
||||
qse_pio_pid_t qse_pio_getchild (qse_pio_t* pio)
|
||||
{
|
||||
return pio->child;
|
||||
}
|
||||
|
||||
qse_ssize_t qse_pio_read (
|
||||
qse_pio_t* pio, void* buf, qse_size_t size, qse_pio_hid_t hid)
|
||||
{
|
||||
@ -445,3 +421,87 @@ void qse_pio_end (qse_pio_t* pio, qse_pio_hid_t hid)
|
||||
pio->handle[hid] = QSE_PIO_HND_NIL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
return -1 on error
|
||||
return -2 on no change
|
||||
return retcode on normal exit
|
||||
return 255+signal on kill.
|
||||
*/
|
||||
|
||||
int qse_pio_wait (qse_pio_t* pio, int flags)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
DWORD ec;
|
||||
|
||||
if (pio->child == QSE_PIO_PID_NIL) return -1;
|
||||
|
||||
WaitForSingleObject (pio->child, -1);
|
||||
if (GetExitCodeProcess (pio->child, &ec) == -1)
|
||||
/* close handle here to emulate waitpid() as much as possible. */
|
||||
CloseHandle (pio->child);
|
||||
pio->child = QSE_PIO_PID_NIL;
|
||||
|
||||
#else
|
||||
int status;
|
||||
int opt = 0;
|
||||
int ret = -1;
|
||||
|
||||
if (pio->child == QSE_PIO_PID_NIL) return -1;
|
||||
|
||||
if (flags & QSE_PIO_NOWAIT) opt |= WNOHANG;
|
||||
|
||||
while (1)
|
||||
{
|
||||
int n = QSE_WAITPID (pio->child, &status, opt);
|
||||
|
||||
qse_printf (QSE_T("n=%d,pio->child=%d,errno=%d,ECHILD=%d\n"), n, pio->child, errno, ECHILD);
|
||||
if (n == -1)
|
||||
{
|
||||
if (errno == ECHILD)
|
||||
{
|
||||
/* most likely, the process has already been waitpid()ed on. */
|
||||
/* TODO: what should we do... ? */
|
||||
/* ??? TREAT AS NORMAL??? => cannot know exit code => TREAT AS ERROR but reset pio->child */
|
||||
|
||||
pio->child = QSE_PIO_PID_NIL;
|
||||
ret = -1; /* OR ECHILD / QSE_PIO_ECHILD */
|
||||
break;
|
||||
}
|
||||
|
||||
if (errno != EINTR || !(flags & QSE_PIO_IGNINTR)) break;
|
||||
}
|
||||
|
||||
if (n == 0)
|
||||
{
|
||||
/* when WNOHANG is not specified, 0 can't be returned */
|
||||
QSE_ASSERT (flags & QSE_PIO_NOWAIT);
|
||||
|
||||
ret = -2;
|
||||
/* the child process is still alive */
|
||||
break;
|
||||
}
|
||||
|
||||
if (n == pio->child)
|
||||
{
|
||||
if (WIFEXITED(status))
|
||||
{
|
||||
/* the child process ended normally */
|
||||
ret = WEXITSTATUS(status);
|
||||
}
|
||||
else if (WIFSIGNALED(status))
|
||||
{
|
||||
/* the child process was killed by a signal */
|
||||
ret = 255 + WTERMSIG (status);
|
||||
}
|
||||
|
||||
/* not interested in WIFSTOPPED & WIFCONTINUED */
|
||||
|
||||
pio->child = QSE_PIO_PID_NIL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
|
Reference in New Issue
Block a user