aboutsummaryrefslogtreecommitdiff
path: root/posix
diff options
context:
space:
mode:
Diffstat (limited to 'posix')
-rw-r--r--posix/sys/wait.h7
-rw-r--r--posix/tst-waitid.c71
2 files changed, 76 insertions, 2 deletions
diff --git a/posix/sys/wait.h b/posix/sys/wait.h
index e758f9e3ff..372d46c79a 100644
--- a/posix/sys/wait.h
+++ b/posix/sys/wait.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-1994,1996-2001,2003 Free Software Foundation, Inc.
+/* Copyright (C) 1991-1994,1996-2001,2003,2004 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -30,7 +30,7 @@ __BEGIN_DECLS
#include <signal.h>
#include <sys/resource.h>
-/* These macros could also be defined int <stdlib.h>. */
+/* These macros could also be defined in <stdlib.h>. */
#if !defined _STDLIB_H || !defined __USE_XOPEN
/* This will define the `W*' macros for the flag
bits to `waitpid', `wait3', and `wait4'. */
@@ -84,6 +84,9 @@ typedef union
# define WIFEXITED(status) __WIFEXITED(__WAIT_INT(status))
# define WIFSIGNALED(status) __WIFSIGNALED(__WAIT_INT(status))
# define WIFSTOPPED(status) __WIFSTOPPED(__WAIT_INT(status))
+# ifdef __WIFCONTINUED
+# define WIFCONTINUED(status) __WIFCONTINUED(__WAIT_INT(status))
+# endif
#endif /* <stdlib.h> not included. */
#ifdef __USE_BSD
diff --git a/posix/tst-waitid.c b/posix/tst-waitid.c
index 3e81d7a0ac..642d529a9a 100644
--- a/posix/tst-waitid.c
+++ b/posix/tst-waitid.c
@@ -335,6 +335,77 @@ do_test (int argc, char *argv[])
info.si_signo);
RETURN (EXIT_FAILURE);
}
+
+ /* Now stop him again and test waitpid with WCONTINUED. */
+ expecting_sigchld = 1;
+ if (kill (pid, SIGSTOP) != 0)
+ {
+ error (0, errno, "kill (%d, SIGSTOP)", pid);
+ RETURN (EXIT_FAILURE);
+ }
+ pid_t wpid = waitpid (pid, &fail, WUNTRACED);
+ if (wpid < 0)
+ {
+ error (0, errno, "waitpid WUNTRACED on stopped");
+ RETURN (EXIT_FAILURE);
+ }
+ else if (wpid != pid)
+ {
+ error (0, 0,
+ "waitpid WUNTRACED on stopped returned %d != %d (status %x)",
+ wpid, pid, fail);
+ RETURN (EXIT_FAILURE);
+ }
+ else if (!WIFSTOPPED (fail) || WIFSIGNALED (fail) || WIFEXITED (fail)
+ || WIFCONTINUED (fail) || WSTOPSIG (fail) != SIGSTOP)
+ {
+ error (0, 0, "waitpid WUNTRACED on stopped: status %x", fail);
+ RETURN (EXIT_FAILURE);
+ }
+ CHECK_SIGCHLD ("stopped", CLD_STOPPED, SIGSTOP);
+
+ expecting_sigchld = 1;
+ if (kill (pid, SIGCONT) != 0)
+ {
+ error (0, errno, "kill (%d, SIGCONT)", pid);
+ RETURN (EXIT_FAILURE);
+ }
+
+ /* Wait for the child to have continued. */
+ sleep (2);
+
+ if (expecting_sigchld)
+ {
+ error (0, 0, "no SIGCHLD seen for SIGCONT (optional)");
+ expecting_sigchld = 0;
+ }
+ else
+ CHECK_SIGCHLD ("continued", CLD_CONTINUED, SIGCONT);
+
+ wpid = waitpid (pid, &fail, WCONTINUED);
+ if (wpid < 0)
+ {
+ if (errno == EINVAL)
+ error (0, 0, "waitpid does not support WCONTINUED");
+ else
+ {
+ error (0, errno, "waitpid WCONTINUED on continued");
+ RETURN (EXIT_FAILURE);
+ }
+ }
+ else if (wpid != pid)
+ {
+ error (0, 0,
+ "waitpid WCONTINUED on continued returned %d != %d (status %x)",
+ wpid, pid, fail);
+ RETURN (EXIT_FAILURE);
+ }
+ else if (WIFSTOPPED (fail) || WIFSIGNALED (fail) || WIFEXITED (fail)
+ || !WIFCONTINUED (fail))
+ {
+ error (0, 0, "waitpid WCONTINUED on continued: status %x", fail);
+ RETURN (EXIT_FAILURE);
+ }
#endif
expecting_sigchld = 1;