* posix/tst-waitid.c (do_test): Add tests for waitpid with WCONTINUED.
authorRoland McGrath <roland@gnu.org>
Tue, 28 Sep 2004 01:42:49 +0000 (01:42 +0000)
committerRoland McGrath <roland@gnu.org>
Tue, 28 Sep 2004 01:42:49 +0000 (01:42 +0000)
* posix/sys/wait.h [__WIFCONTINUED] (WIFCONTINUED): New macro.
* stdlib/stdlib.h [__WIFCONTINUED] (WIFCONTINUED): New macro.
* sysdeps/generic/bits/waitstatus.h (__W_CONTINUED): New macro.
[WCONTINUED] (__WIFCONTINUED): New macro.
(__WIFSIGNALED): Rewritten to exclude __W_CONTINUED value, and have no
branches.

ChangeLog
bits/waitstatus.h
posix/sys/wait.h
posix/tst-waitid.c
stdlib/stdlib.h
sysdeps/generic/bits/waitstatus.h

index 37534d5..97cea59 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
 2004-09-27  Roland McGrath  <roland@redhat.com>
 
+       * posix/tst-waitid.c (do_test): Add tests for waitpid with WCONTINUED.
+
+       * posix/sys/wait.h [__WIFCONTINUED] (WIFCONTINUED): New macro.
+       * stdlib/stdlib.h [__WIFCONTINUED] (WIFCONTINUED): New macro.
+       * sysdeps/generic/bits/waitstatus.h (__W_CONTINUED): New macro.
+       [WCONTINUED] (__WIFCONTINUED): New macro.
+       (__WIFSIGNALED): Rewritten to exclude __W_CONTINUED value, and have no
+       branches.
+
        * sysdeps/unix/sysv/linux/waitid.c (do_waitid): Add fifth argument to
        all three syscall uses, not just one!
 
index 982c9db..98da418 100644 (file)
@@ -1,5 +1,5 @@
 /* Definitions of status bits for `wait' et al.
-   Copyright (C) 1992, 1994, 1996, 1997, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1992,1994,1996,1997,2000,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
 #define        __WIFEXITED(status)     (__WTERMSIG(status) == 0)
 
 /* Nonzero if STATUS indicates termination by a signal.  */
-#ifdef __GNUC__
-# define __WIFSIGNALED(status) \
-  (__extension__ ({ int __status = (status);                                 \
-                   !__WIFSTOPPED(__status) && !__WIFEXITED(__status); }))
-#else  /* Not GCC.  */
-# define __WIFSIGNALED(status) (!__WIFSTOPPED(status) && !__WIFEXITED(status))
-#endif /* GCC.  */
+#define __WIFSIGNALED(status) \
+  (((signed char) ((((((status) + 1) & 0xffff) - 1) & 0x7f) + 1) >> 1) > 0)
 
 /* Nonzero if STATUS indicates the child is stopped.  */
 #define        __WIFSTOPPED(status)    (((status) & 0xff) == 0x7f)
 
+/* Nonzero if STATUS indicates the child continued after a stop.  We only
+   define this if <bits/waitflags.h> provides the WCONTINUED flag bit.  */
+#ifdef WCONTINUED
+# define __WIFCONTINUED(status)        ((status) == __W_CONTINUED)
+#endif
+
 /* Nonzero if STATUS indicates the child dumped core.  */
 #define        __WCOREDUMP(status)     ((status) & __WCOREFLAG)
 
 /* Macros for constructing status values.  */
 #define        __W_EXITCODE(ret, sig)  ((ret) << 8 | (sig))
 #define        __W_STOPCODE(sig)       ((sig) << 8 | 0x7f)
+#define __W_CONTINUED          0xffff
 #define        __WCOREFLAG             0x80
 
 
index e758f9e..372d46c 100644 (file)
@@ -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
index 3e81d7a..642d529 100644 (file)
@@ -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;
index dc0c712..e4f7936 100644 (file)
@@ -88,6 +88,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 /* X/Open and <sys/wait.h> not included.  */
 
 __BEGIN_NAMESPACE_STD
index 982c9db..98da418 100644 (file)
@@ -1,5 +1,5 @@
 /* Definitions of status bits for `wait' et al.
-   Copyright (C) 1992, 1994, 1996, 1997, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1992,1994,1996,1997,2000,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
 #define        __WIFEXITED(status)     (__WTERMSIG(status) == 0)
 
 /* Nonzero if STATUS indicates termination by a signal.  */
-#ifdef __GNUC__
-# define __WIFSIGNALED(status) \
-  (__extension__ ({ int __status = (status);                                 \
-                   !__WIFSTOPPED(__status) && !__WIFEXITED(__status); }))
-#else  /* Not GCC.  */
-# define __WIFSIGNALED(status) (!__WIFSTOPPED(status) && !__WIFEXITED(status))
-#endif /* GCC.  */
+#define __WIFSIGNALED(status) \
+  (((signed char) ((((((status) + 1) & 0xffff) - 1) & 0x7f) + 1) >> 1) > 0)
 
 /* Nonzero if STATUS indicates the child is stopped.  */
 #define        __WIFSTOPPED(status)    (((status) & 0xff) == 0x7f)
 
+/* Nonzero if STATUS indicates the child continued after a stop.  We only
+   define this if <bits/waitflags.h> provides the WCONTINUED flag bit.  */
+#ifdef WCONTINUED
+# define __WIFCONTINUED(status)        ((status) == __W_CONTINUED)
+#endif
+
 /* Nonzero if STATUS indicates the child dumped core.  */
 #define        __WCOREDUMP(status)     ((status) & __WCOREFLAG)
 
 /* Macros for constructing status values.  */
 #define        __W_EXITCODE(ret, sig)  ((ret) << 8 | (sig))
 #define        __W_STOPCODE(sig)       ((sig) << 8 | 0x7f)
+#define __W_CONTINUED          0xffff
 #define        __WCOREFLAG             0x80