* lib/stdlib.in.h (includes): Guarantee WEXITSTATUS.
* modules/stdlib (Depends-on): Add sys_wait.
* tests/test-sys_wait.c (main): Enhance test.
* tests/test-stdlib.c (main): Likewise.
* doc/posix-headers/stdlib.texi (stdlib.h): Document the bug.
Signed-off-by: Eric Blake <eblake@redhat.com>
2010-09-15 Eric Blake <eblake@redhat.com>
+ stdlib: work around MirBSD WEXITSTATUS bug
+ * lib/stdlib.in.h (includes): Guarantee WEXITSTATUS.
+ * modules/stdlib (Depends-on): Add sys_wait.
+ * tests/test-sys_wait.c (main): Enhance test.
+ * tests/test-stdlib.c (main): Likewise.
+ * doc/posix-headers/stdlib.texi (stdlib.h): Document the bug.
+
docs: mention MacOS issue with WEXITSTATUS(constant)
* doc/posix-headers/sys_wait.texi (sys/wait.h): Document the
issue.
Some platforms provide a @code{NULL} macro that cannot be used in arbitrary
expressions:
NetBSD 5.0
+
+@item
+Some platforms fail to provide @code{WEXITSTATUS} and friends:
+MirBSD 10.
@end itemize
Portability problems not fixed by Gnulib:
/* NetBSD 5.0 mis-defines NULL. */
#include <stddef.h>
+/* MirBSD 10 fails to define WEXITSTATUS. */
+#ifndef WEXITSTATUS
+# include <sys/wait.h>
+#endif
+
/* Solaris declares getloadavg() in <sys/loadavg.h>. */
#if (@GNULIB_GETLOADAVG@ || defined GNULIB_POSIXCHECK) && @HAVE_SYS_LOADAVG_H@
# include <sys/loadavg.h>
include_next
stddef
stdint
+sys_wait
unistd
warn-on-use
#include "verify.h"
-int exitcode;
+/* Check that EXIT_SUCCESS is 0, per POSIX. */
+static int exitcode = EXIT_SUCCESS;
+#if EXIT_SUCCESS
+"oops"
+#endif
+
+/* Check for GNU value (not guaranteed by POSIX, but is guaranteed by
+ gnulib). */
+#if EXIT_FAILURE != 1
+"oops"
+#endif
/* Check that NULL can be passed through varargs as a pointer type,
per POSIX 2008. */
int
main (void)
{
- /* Check that some macros are defined and different integer constants. */
- switch (exitcode)
+ /* Check subset of <sys/wait.h> macros that must be visible here.
+ Note that some of these macros are only portable when operating
+ on an lvalue. */
+ int i;
+ for (i = 0; i < 0x10000; i = (i ? i << 1 : 1))
+ if (!!WIFSIGNALED (i) + !!WIFEXITED (i) + !!WIFSTOPPED (i) != 1)
+ return 1;
+ i = WEXITSTATUS (i) + WSTOPSIG (i) + WTERMSIG (i);
+
+ switch (i)
{
- case EXIT_SUCCESS:
- case EXIT_FAILURE:
+#if 0
+ /* Gnulib doesn't guarantee these, yet. */
+ case WNOHANG:
+ case WUNTRACED:
+#endif
break;
}
-
return 0;
}
int
main (void)
{
- return a;
+ /* Check for existence of required macros. Note that we document
+ that these are safe only on lvalues. */
+ int i;
+ for (i = 0; i < 0x10000; i = (i ? i << 1 : 1))
+ if (!!WIFSIGNALED (i) + !!WIFEXITED (i) + !!WIFSTOPPED (i) != 1)
+ return 1;
+ i = WEXITSTATUS (i) + WSTOPSIG (i) + WTERMSIG (i);
+
+ switch (i)
+ {
+#if 0
+ /* Gnulib doesn't guarantee these, yet. */
+ case WCONTINUED:
+ case WNOHANG:
+ case WUNTRACED:
+ case WEXITED:
+ case WNOWAIT:
+ case WSTOPPED:
+#endif
+ break;
+ }
+ return a ? i : 0;
}