interim commit for qse_pio_t
- added QSE_KILL() - added qse_pio_kill() - enhanced qse_pio_wait()
This commit is contained in:
		| @ -275,7 +275,7 @@ qse_fio_off_t qse_fio_seek ( | ||||
|  | ||||
| 	return (qse_fio_off_t)tmp; | ||||
|  | ||||
| #elif defined(HAVE_LSEEK64) | ||||
| #elif defined(QSE_LSEEK64) | ||||
| 	return QSE_LSEEK64 (fio->handle, offset, seek_map[origin]); | ||||
| #else | ||||
| 	return QSE_LSEEK (fio->handle, offset, seek_map[origin]); | ||||
|  | ||||
| @ -378,18 +378,31 @@ qse_ssize_t qse_pio_read ( | ||||
| { | ||||
| #ifdef _WIN32 | ||||
| 	DWORD count; | ||||
| #else | ||||
| 	qse_ssize_t n; | ||||
| #endif | ||||
|  | ||||
| 	if (pio->handle[hid] == QSE_PIO_HND_NIL)  | ||||
| 	{ | ||||
| 		/* the stream is already closed */ | ||||
| 		pio->errnum = QSE_PIO_ENOHND; | ||||
| 		return (qse_ssize_t)-1; | ||||
| 	} | ||||
|  | ||||
| #ifdef _WIN32 | ||||
| 	if (size > QSE_TYPE_MAX(DWORD)) size = QSE_TYPE_MAX(DWORD); | ||||
| 	if (ReadFile(pio->handle, buf, size, &count, QSE_NULL) == FALSE) return -1; | ||||
| 	return (qse_ssize_t)count; | ||||
| #else | ||||
| 	if (pio->handle[hid] == QSE_PIO_HND_NIL)  | ||||
| 	{ | ||||
| 		/* the stream is already closed */ | ||||
| 		return (qse_ssize_t)-1; | ||||
| 	} | ||||
|  | ||||
| 	if (size > QSE_TYPE_MAX(size_t)) size = QSE_TYPE_MAX(size_t); | ||||
| 	return QSE_READ (pio->handle[hid], buf, size); | ||||
| 	n = QSE_READ (pio->handle[hid], buf, size); | ||||
| 	if (n == -1)  | ||||
| 	{ | ||||
| 		pio->errnum = (errno == EINTR)?  | ||||
| 			QSE_PIO_EINTR: QSE_PIO_ESYSCALL; | ||||
| 	} | ||||
| 	return n; | ||||
| #endif | ||||
| } | ||||
|  | ||||
| @ -398,6 +411,18 @@ qse_ssize_t qse_pio_write ( | ||||
| { | ||||
| #ifdef _WIN32 | ||||
| 	DWORD count; | ||||
| #else | ||||
| 	qse_ssize_t n; | ||||
| #endif | ||||
|  | ||||
| 	if (pio->handle[hid] == QSE_PIO_HND_NIL)  | ||||
| 	{ | ||||
| 		/* the stream is already closed */ | ||||
| 		pio->errnum = QSE_PIO_ENOHND; | ||||
| 		return (qse_ssize_t)-1; | ||||
| 	} | ||||
|  | ||||
| #ifdef _WIN32 | ||||
| 	if (size > QSE_TYPE_MAX(DWORD)) size = QSE_TYPE_MAX(DWORD); | ||||
| 	if (WriteFile(pio->handle, data, size, &count, QSE_NULL) == FALSE) return -1; | ||||
| 	return (qse_ssize_t)count; | ||||
| @ -409,7 +434,13 @@ qse_ssize_t qse_pio_write ( | ||||
| 	} | ||||
|  | ||||
| 	if (size > QSE_TYPE_MAX(size_t)) size = QSE_TYPE_MAX(size_t); | ||||
| 	return QSE_WRITE (pio->handle[hid], data, size); | ||||
| 	n = QSE_WRITE (pio->handle[hid], data, size); | ||||
| 	if (n == -1)  | ||||
| 	{ | ||||
| 		pio->errnum = (errno == EINTR)?  | ||||
| 			QSE_PIO_EINTR: QSE_PIO_ESYSCALL; | ||||
| 	} | ||||
| 	return n; | ||||
| #endif | ||||
| } | ||||
|  | ||||
| @ -422,19 +453,17 @@ void qse_pio_end (qse_pio_t* pio, qse_pio_hid_t hid) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| /* | ||||
| 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; | ||||
| 	if (pio->child == QSE_PIO_PID_NIL)  | ||||
| 	{ | ||||
| 		 | ||||
| 		pio->errnum = QSE_PIO_ECHILD; | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	WaitForSingleObject (pio->child, -1); | ||||
| 	if (GetExitCodeProcess (pio->child, &ec) == -1) | ||||
| @ -443,17 +472,22 @@ int qse_pio_wait (qse_pio_t* pio, int flags) | ||||
| 	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 (pio->child == QSE_PIO_PID_NIL)  | ||||
| 	{ | ||||
| 		pio->errnum = QSE_PIO_ECHILD; | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	if (flags & QSE_PIO_NOHANG) opt |= WNOHANG; | ||||
|  | ||||
| 	while (1) | ||||
| 	{ | ||||
| 		int n = QSE_WAITPID (pio->child, &status, opt); | ||||
| 		int status, n; | ||||
|  | ||||
| 		n = QSE_WAITPID (pio->child, &status, opt); | ||||
|  | ||||
| 		if (n == -1) | ||||
| 		{ | ||||
| @ -461,17 +495,17 @@ int qse_pio_wait (qse_pio_t* pio, int flags) | ||||
| 			{ | ||||
| 				/* 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; | ||||
| 				pio->errnum = QSE_PIO_ECHILD; | ||||
| 				ret = -1;  | ||||
| 				break; | ||||
| 			} | ||||
| 			else if (errno == EINTR) | ||||
| 			{ | ||||
| 				if (flags & QSE_PIO_IGNINTR) continue; | ||||
| 				pio->errnum = QSE_PIO_EINTR; | ||||
| 			} | ||||
| 			else pio->errnum = QSE_PIO_ESYSCALL; | ||||
|  | ||||
| 			if (errno != EINTR || !(flags & QSE_PIO_IGNINTR)) break; | ||||
| 			break; | ||||
| 		} | ||||
|  | ||||
| 		if (n == 0)  | ||||
| @ -479,7 +513,7 @@ int qse_pio_wait (qse_pio_t* pio, int flags) | ||||
| 			/* when WNOHANG is not specified, 0 can't be returned */ | ||||
| 			QSE_ASSERT (flags & QSE_PIO_NOHANG); | ||||
|  | ||||
| 			ret = -2; | ||||
| 			ret = 255 + 1; | ||||
| 			/* the child process is still alive */ | ||||
| 			break; | ||||
| 		} | ||||
| @ -494,10 +528,16 @@ int qse_pio_wait (qse_pio_t* pio, int flags) | ||||
| 			else if (WIFSIGNALED(status)) | ||||
| 			{ | ||||
| 				/* the child process was killed by a signal */ | ||||
| 				ret = 255 + WTERMSIG (status); | ||||
| 				ret = 255 + 1 + WTERMSIG (status); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				/* not interested in WIFSTOPPED & WIFCONTINUED. | ||||
| 				 * in fact, this else block should not be reached | ||||
| 				 * as WIFEXITED or WIFSIGNALED must be true. | ||||
| 				 * anyhow, just set the return value to 0. */ | ||||
| 				ret = 0; | ||||
| 			} | ||||
|  | ||||
| 			/* not interested in WIFSTOPPED & WIFCONTINUED  */ | ||||
|  | ||||
| 			pio->child = QSE_PIO_PID_NIL; | ||||
| 			break; | ||||
| @ -507,3 +547,33 @@ int qse_pio_wait (qse_pio_t* pio, int flags) | ||||
| 	return ret; | ||||
| #endif | ||||
| } | ||||
|  | ||||
| int qse_pio_kill (qse_pio_t* pio) | ||||
| { | ||||
| #ifdef _WIN32 | ||||
| 	DWORD n; | ||||
| #else | ||||
| 	int n; | ||||
| #endif | ||||
|  | ||||
| 	if (pio->child == QSE_PIO_PID_NIL)  | ||||
| 	{ | ||||
| 		pio->errnum = QSE_PIO_ECHILD; | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| #ifdef _WIN32 | ||||
| 	/* 9 was chosen below to treat TerminateProcess as kill -KILL. */ | ||||
| 	n = TerminateProcess (pio->child, 255 + 1 + 9); | ||||
| 	if (n == FALSE)  | ||||
| 	{ | ||||
| 		pio->errnum = QSE_PIO_SYSCALL; | ||||
| 		return -1; | ||||
| 	} | ||||
| 	return 0; | ||||
| #else | ||||
| 	n = QSE_KILL (pio->child, SIGKILL); | ||||
| 	if (n == -1) pio->errnum = QSE_PIO_ESYSCALL; | ||||
| 	return n; | ||||
| #endif | ||||
| } | ||||
|  | ||||
| @ -12,6 +12,9 @@ | ||||
| #ifdef HAVE_SYS_WAIT_H | ||||
| #include <sys/wait.h> | ||||
| #endif | ||||
| #ifdef HAVE_SIGNAL_H | ||||
| #include <signal.h> | ||||
| #endif | ||||
|  | ||||
| #if defined(QSE_USE_SYSCALL) && defined(HAVE_SYS_SYSCALL_H) | ||||
| #include <sys/syscall.h> | ||||
| @ -117,6 +120,12 @@ | ||||
| 	#define QSE_WAITPID(pid,status,options) waitpid(pid,status,options) | ||||
| #endif | ||||
|  | ||||
| #ifdef SYS_kill | ||||
| 	#define QSE_KILL(pid,sig) syscall(SYS_kill,pid,sig) | ||||
| #else | ||||
| 	#define QSE_KILL(pid,sig) kill(pid,sig) | ||||
| #endif | ||||
|  | ||||
| #ifdef SYS_getpid | ||||
| 	#define QSE_GETPID() syscall(SYS_getpid) | ||||
| #else | ||||
|  | ||||
		Reference in New Issue
	
	Block a user