diff --git a/qa/lib/newlib/030-pause.c b/qa/lib/newlib/030-pause.c new file mode 100644 index 0000000..ca8d247 --- /dev/null +++ b/qa/lib/newlib/030-pause.c @@ -0,0 +1,67 @@ +#include +#include +#include +#include +#include +#include + + +void sighup() { + signal(SIGHUP,sighup); /* reset signal */ + printf("CHILD: SIGHUP received\n"); +} + +int +main(int argc, char *argv[]) +{ + pid_t cpid, w; + int ret, status; + + + cpid = fork(); + if(cpid == -1){ + perror("fork"); + exit(EXIT_FAILURE); + } + + if (cpid == 0) { /* Code executed by child */ + signal(SIGHUP, sighup); /* set function calls */ + + printf("Child PID is %ld, calling pause()...\n", (long) getpid()); + ret = pause(); + + if(ret == -1 && errno == EINTR){ + printf("Pause returned %d with errno = EINTR\n", ret); + _exit(0); + } + if(ret != -1) + printf("Pause returned %d\n", ret); + if(errno != EINTR) + printf("Pause returned but errno != EINTR\n"); + _exit(1); + } + + /* Code executed by parent */ + sleep(5); + kill(cpid, SIGHUP); + + do { + w = waitpid(cpid, &status, WUNTRACED); + if (w == -1) { + perror("waitpid"); + exit(EXIT_FAILURE); + } + + if (WIFEXITED(status)) { + printf("exited, status=%d\n", WEXITSTATUS(status)); + } else if (WIFSIGNALED(status)) { + printf("killed by signal %d\n", WTERMSIG(status)); + exit(EXIT_FAILURE); + } else if (WIFSTOPPED(status)) { + printf("stopped by signal %d\n", WSTOPSIG(status)); + exit(EXIT_FAILURE); + } + } while (!WIFEXITED(status) && !WIFSIGNALED(status)); + exit(EXIT_SUCCESS); + +} diff --git a/qa/lib/newlib/build.json b/qa/lib/newlib/build.json index 3abf70d..13c2ddb 100644 --- a/qa/lib/newlib/build.json +++ b/qa/lib/newlib/build.json @@ -34,6 +34,7 @@ "000-hello.c", "010-fork.c", "020-waitpid.c", + "030-pause.c", "100-files.c", "101-files.c", "200-signals.c", diff --git a/sys/src/lib/posix/others.c b/sys/src/lib/posix/others.c index c5ffc55..68b73c7 100644 --- a/sys/src/lib/posix/others.c +++ b/sys/src/lib/posix/others.c @@ -60,6 +60,13 @@ POSIX_usleep(int *errnop, unsigned int usec) return 0; } +int +POSIX_pause(int *errnop) +{ + rendezvous((void*)~0, 1); + *errnop = __libposix_get_errno(PosixEINTR); + return -1; +} clock_t POSIX_times(int *errnop, void *buf)