--- pth_high.c 2000/08/18 08:35:29 1.74
+++ pth_high.c 2000/10/03 09:26:47 1.75
@@ -141,6 +141,98 @@
return 0;
}
+/* Pth variant of waitpid(2) */
+pid_t pth_waitpid(pid_t wpid, int *status, int options)
+{
+ pth_event_t ev;
+ static pth_key_t ev_key = PTH_KEY_INIT;
+ pid_t pid;
+
+ pth_debug2("pth_waitpid: called from thread \"%s\"", pth_current->name);
+
+ for (;;) {
+ /* do a non-blocking poll for the pid */
+ while ( (pid = pth_sc(waitpid)(wpid, status, options|WNOHANG)) < 0
+ && errno == EINTR) ;
+
+ /* if pid was found or caller requested a polling return immediately */
+ if (pid == -1 || pid > 0 || (pid == 0 && (options & WNOHANG)))
+ break;
+
+ /* else wait a little bit */
+ ev = pth_event(PTH_EVENT_TIME|PTH_MODE_STATIC, &ev_key, pth_timeout(0,250000));
+ pth_wait(ev);
+ }
+
+ pth_debug2("pth_waitpid: leave to thread \"%s\"", pth_current->name);
+ return pid;
+}
+
+/* Pth variant of system(3) */
+int pth_system(const char *cmd)
+{
+ struct sigaction sa_ign, sa_int, sa_quit;
+ sigset_t ss_block, ss_old;
+ struct stat sb;
+ pid_t pid;
+ int pstat;
+
+ /* POSIX calling convention: determine whether the
+ Bourne Shell ("sh") is available on this platform */
+ if (cmd == NULL) {
+ if (stat(PTH_PATH_BINSH, &sb) == -1)
+ return 0;
+ return 1;
+ }
+
+ /* temporarily ignore SIGINT and SIGQUIT actions */
+ sa_ign.sa_handler = SIG_IGN;
+ sigemptyset(&sa_ign.sa_mask);
+ sa_ign.sa_flags = 0;
+ sigaction(SIGINT, &sa_ign, &sa_int);
+ sigaction(SIGQUIT, &sa_ign, &sa_quit);
+
+ /* block SIGCHLD signal */
+ sigemptyset(&ss_block);
+ sigaddset(&ss_block, SIGCHLD);
+ sigprocmask(SIG_BLOCK, &ss_block, &ss_old);
+
+ /* fork the current process */
+ pstat = -1;
+ switch (pid = pth_fork()) {
+ case -1: /* error */
+ break;
+
+ case 0: /* child */
+ /* restore original signal dispositions and execute the command */
+ sigaction(SIGINT, &sa_int, NULL);
+ sigaction(SIGQUIT, &sa_quit, NULL);
+ sigprocmask(SIG_SETMASK, &ss_old, NULL);
+
+ /* stop the Pth scheduling */
+ pth_scheduler_kill();
+
+ /* execute the command through Bourne Shell */
+ execl(PTH_PATH_BINSH, "sh", "-c", cmd, NULL);
+
+ /* POSIX compliant return in case execution failed */
+ exit(127);
+
+ default: /* parent */
+ /* wait until child process terminates */
+ pid = pth_waitpid(pid, &pstat, 0);
+ break;
+ }
+
+ /* restore original signal dispositions and execute the command */
+ sigaction(SIGINT, &sa_int, NULL);
+ sigaction(SIGQUIT, &sa_quit, NULL);
+ sigprocmask(SIG_SETMASK, &ss_old, NULL);
+
+ /* return error or child process result code */
+ return (pid == -1 ? -1 : pstat);
+}
+
/* Pth variant of select(2) */
int pth_select(int nfds, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout)
@@ -637,33 +729,6 @@
return rv;
}
-/* Pth variant of waitpid(2) */
-pid_t pth_waitpid(pid_t wpid, int *status, int options)
-{
- pth_event_t ev;
- static pth_key_t ev_key = PTH_KEY_INIT;
- pid_t pid;
-
- pth_debug2("pth_waitpid: called from thread \"%s\"", pth_current->name);
-
- for (;;) {
- /* do a non-blocking poll for the pid */
- while ( (pid = pth_sc(waitpid)(wpid, status, options|WNOHANG)) < 0
- && errno == EINTR) ;
-
- /* if pid was found or caller requested a polling return immediately */
- if (pid == -1 || pid > 0 || (pid == 0 && (options & WNOHANG)))
- break;
-
- /* else wait a little bit */
- ev = pth_event(PTH_EVENT_TIME|PTH_MODE_STATIC, &ev_key, pth_timeout(0,250000));
- pth_wait(ev);
- }
-
- pth_debug2("pth_waitpid: leave to thread \"%s\"", pth_current->name);
- return pid;
-}
-
/* Pth variant of readv(2) */
ssize_t pth_readv(int fd, const struct iovec *iov, int iovcnt)
{
|