[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
another posix_spawn bug on AIX
From: |
Bruno Haible |
Subject: |
another posix_spawn bug on AIX |
Date: |
Mon, 20 Oct 2008 13:19:41 +0200 |
User-agent: |
KMail/1.5.4 |
The implementation of posix_spawn on AIX 5.3..6.1 has yet another bug: it fails
when asked to open a file whose name contains a '*'. Apparently the implementors
(from a subcontractor of IBM, not IBM itself, I am being told) just took the
primitive sample implementation from
<http://www.opengroup.org/onlinepubs/000095399/xrat/xsh_chap03.html>
This patch adds a test against this bug.
2008-10-20 Bruno Haible <address@hidden>
* m4/posix_spawn.m4 (gl_POSIX_SPAWN_WORKS): Test against another bug
of posix_spawn on AIX 5.3.
*** m4/posix_spawn.m4.orig 2008-10-20 13:09:09.000000000 +0200
--- m4/posix_spawn.m4 2008-10-20 13:09:03.000000000 +0200
***************
*** 48,57 ****
])
dnl Test whether posix_spawn actually works.
! dnl posix_spawn on AIX 5.3..6.1 has a bug: When it fails to execute the
! dnl program, the child process exits with exit() rather than _exit(),
! dnl which causes the stdio buffers to be flushed. Reported by Rainer Tammer.
! dnl posix_spawn on AIX 5.3..6.1 has also a second bug: It does not work
dnl when POSIX threads are used. But we don't test against this bug here.
AC_DEFUN([gl_POSIX_SPAWN_WORKS],
[
--- 48,60 ----
])
dnl Test whether posix_spawn actually works.
! dnl posix_spawn on AIX 5.3..6.1 has two bugs:
! dnl 1) When it fails to execute the program, the child process exits with
! dnl exit() rather than _exit(), which causes the stdio buffers to be
! dnl flushed. Reported by Rainer Tammer.
! dnl 2) The posix_spawn_file_actions_addopen function does not support file
! dnl names that contain a '*'.
! dnl posix_spawn on AIX 5.3..6.1 has also a third bug: It does not work
dnl when POSIX threads are used. But we don't test against this bug here.
AC_DEFUN([gl_POSIX_SPAWN_WORKS],
[
***************
*** 199,204 ****
--- 202,362 ----
gl_cv_func_posix_spawn_works=no
fi],
[gl_cv_func_posix_spawn_works=no])
+ if test $gl_cv_func_posix_spawn_works = yes; then
+ AC_RUN_IFELSE([AC_LANG_SOURCE([[
+ /* Test whether posix_spawn_file_actions_addopen supports filename arguments
+ that contain special characters such as '*'. */
+
+ #include <errno.h>
+ #include <fcntl.h>
+ #include <signal.h>
+ #include <spawn.h>
+ #include <stdbool.h>
+ #include <stdio.h>
+ #include <string.h>
+ #include <unistd.h>
+ #include <sys/types.h>
+ #include <sys/wait.h>
+
+ extern char **environ;
+
+ #ifndef STDIN_FILENO
+ # define STDIN_FILENO 0
+ #endif
+ #ifndef STDOUT_FILENO
+ # define STDOUT_FILENO 1
+ #endif
+ #ifndef STDERR_FILENO
+ # define STDERR_FILENO 2
+ #endif
+
+ #ifndef WTERMSIG
+ # define WTERMSIG(x) ((x) & 0x7f)
+ #endif
+ #ifndef WIFEXITED
+ # define WIFEXITED(x) (WTERMSIG (x) == 0)
+ #endif
+ #ifndef WEXITSTATUS
+ # define WEXITSTATUS(x) (((x) >> 8) & 0xff)
+ #endif
+
+ #define CHILD_PROGRAM_FILENAME "conftest"
+ #define DATA_FILENAME "conftest%=*#?"
+
+ static int
+ parent_main (void)
+ {
+ FILE *fp;
+ char *argv[3] = { CHILD_PROGRAM_FILENAME, "-child", NULL };
+ posix_spawn_file_actions_t actions;
+ bool actions_allocated;
+ int err;
+ pid_t child;
+ int status;
+ int exitstatus;
+
+ /* Create a data file with specific contents. */
+ fp = fopen (DATA_FILENAME, "wb");
+ if (fp == NULL)
+ {
+ perror ("cannot create data file");
+ return 1;
+ }
+ fwrite ("Halle Potta", 1, 11, fp);
+ if (fflush (fp) || fclose (fp))
+ {
+ perror ("cannot prepare data file");
+ return 1;
+ }
+
+ /* Avoid reading from our stdin, as it could block. */
+ freopen ("/dev/null", "rb", stdin);
+
+ /* Test whether posix_spawn_file_actions_addopen with this file name
+ actually works, but spawning a child that reads from this file. */
+ actions_allocated = false;
+ if ((err = posix_spawn_file_actions_init (&actions)) != 0
+ || (actions_allocated = true,
+ (err = posix_spawn_file_actions_addopen (&actions, STDIN_FILENO,
DATA_FILENAME, O_RDONLY, 0600)) != 0
+ || (err = posix_spawn (&child, CHILD_PROGRAM_FILENAME, &actions,
NULL, argv, environ)) != 0))
+ {
+ if (actions_allocated)
+ posix_spawn_file_actions_destroy (&actions);
+ errno = err;
+ perror ("subprocess failed");
+ return 1;
+ }
+ posix_spawn_file_actions_destroy (&actions);
+ status = 0;
+ while (waitpid (child, &status, 0) != child)
+ ;
+ if (!WIFEXITED (status))
+ {
+ fprintf (stderr, "subprocess terminated with unexpected wait status
%d\n", status);
+ return 1;
+ }
+ exitstatus = WEXITSTATUS (status);
+ if (exitstatus != 0)
+ {
+ fprintf (stderr, "subprocess terminated with unexpected exit status
%d\n", exitstatus);
+ return 1;
+ }
+ return 0;
+ }
+
+ static int
+ child_main (void)
+ {
+ char buf[1024];
+
+ /* See if reading from STDIN_FILENO yields the expected contents. */
+ if (fread (buf, 1, sizeof (buf), stdin) == 11
+ && memcmp (buf, "Halle Potta", 11) == 0)
+ return 0;
+ else
+ return 2;
+ }
+
+ static void
+ cleanup_then_die (int sig)
+ {
+ /* Clean up data file. */
+ unlink (DATA_FILENAME);
+
+ /* Re-raise the signal and die from it. */
+ signal (sig, SIG_DFL);
+ raise (sig);
+ }
+
+ int
+ main (int argc, char *argv[])
+ {
+ int exitstatus;
+
+ if (!(argc > 1 && strcmp (argv[1], "-child") == 0))
+ {
+ /* This is the parent process. */
+ signal (SIGINT, cleanup_then_die);
+ signal (SIGTERM, cleanup_then_die);
+ #ifdef SIGHUP
+ signal (SIGHUP, cleanup_then_die);
+ #endif
+
+ exitstatus = parent_main ();
+ }
+ else
+ {
+ /* This is the child process. */
+
+ exitstatus = child_main ();
+ }
+ unlink (DATA_FILENAME);
+ return exitstatus;
+ }
+ ]])],
+ [],
+ [gl_cv_func_posix_spawn_works=no])
+ fi
else
case "$host_os" in
aix*) gl_cv_func_posix_spawn_works="guessing no";;
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- another posix_spawn bug on AIX,
Bruno Haible <=