+2020-12-24 Bruno Haible <bruno@clisp.org>
+
+ posix_spawn* tests: Add support for native Windows.
+ * tests/test-posix_spawn-open1.c (DATA_FILENAME): Treat native Windows
+ like Cygwin.
+ * tests/test-posix_spawn-dup2-stdin.c (main): Don't assume the signals
+ SIGHUP and SIGPIPE. On native Windows, don't call
+ posix_spawnattr_setsigmask.
+ * tests/test-posix_spawn-dup2-stdout.c (main): Likewise.
+ * tests/test-posix_spawn-fchdir.c (main): Likewise.
+ * tests/test-posix_spawn-chdir.c (test): Likewise. Accept the child
+ output from Cygwin's 'pwd' program.
+ * tests/test-posix_spawn-script.c (main): On native Windows, skip the
+ executable-shell-script part of the test.
+ * tests/test-posix_spawnp-script.c (main): Likewise.
+ * modules/posix_spawn-tests (Depends-on): Add freopen, waitpid.
+ (configure.ac): Don't define the POSIX_SPAWN_PORTED conditional.
+ (Makefile.am): Don't test the POSIX_SPAWN_PORTED conditional.
+ * modules/posix_spawnp-tests (Depends-on): Add waitpid.
+ (configure.ac): Don't define the POSIX_SPAWN_PORTED conditional.
+ (Makefile.am): Don't test the POSIX_SPAWN_PORTED conditional.
+ * modules/posix_spawn_file_actions_addchdir-tests (Makefile.am): Don't
+ test the POSIX_SPAWN_PORTED conditional.
+ * modules/posix_spawn_file_actions_addfchdir-tests (configure.ac):
+ Define the POSIX_SPAWN_PORTED conditional here.
+
2020-12-24 Bruno Haible <bruno@clisp.org>
sh-filename: Add support for native Windows.
sys_wait
environ
fflush
+freopen
+waitpid
configure.ac:
-AC_EGREP_CPP([notposix], [[
-#if defined _MSC_VER || defined __MINGW32__
- notposix
-#endif
- ]],
- [posix_spawn_ported=no],
- [posix_spawn_ported=yes])
-AM_CONDITIONAL([POSIX_SPAWN_PORTED], [test $posix_spawn_ported = yes])
Makefile.am:
-if POSIX_SPAWN_PORTED
TESTS += \
test-posix_spawn-open1 \
test-posix_spawn-open2 \
test-posix_spawn-inherit1 \
test-posix_spawn-script
test_posix_spawn_script_CPPFLAGS = $(AM_CPPFLAGS) -DSRCDIR=\"$(srcdir)/\"
-endif
configure.ac:
Makefile.am:
-TESTS += test-posix_spawn_file_actions_addchdir
-check_PROGRAMS += test-posix_spawn_file_actions_addchdir
-
-if POSIX_SPAWN_PORTED
-TESTS += test-posix_spawn-chdir
-check_PROGRAMS += test-posix_spawn-chdir
-endif
+TESTS += \
+ test-posix_spawn_file_actions_addchdir \
+ test-posix_spawn-chdir
+check_PROGRAMS += \
+ test-posix_spawn_file_actions_addchdir \
+ test-posix_spawn-chdir
findprog
configure.ac:
+AC_EGREP_CPP([notposix], [[
+#if defined _MSC_VER || defined __MINGW32__
+ notposix
+#endif
+ ]],
+ [posix_spawn_ported=no],
+ [posix_spawn_ported=yes])
+AM_CONDITIONAL([POSIX_SPAWN_PORTED], [test $posix_spawn_ported = yes])
Makefile.am:
TESTS += test-posix_spawn_file_actions_addfchdir
environ
sh-filename
sigprocmask
+waitpid
configure.ac:
-AC_EGREP_CPP([notposix], [[
-#if defined _MSC_VER || defined __MINGW32__
- notposix
-#endif
- ]],
- [posix_spawn_ported=no],
- [posix_spawn_ported=yes])
-AM_CONDITIONAL([POSIX_SPAWN_PORTED], [test $posix_spawn_ported = yes])
Makefile.am:
-if POSIX_SPAWN_PORTED
TESTS += \
test-posix_spawn-dup2-stdout \
test-posix_spawn-dup2-stdin \
MOSTLYCLEANFILES += test-posix_spawn-dup2-stdin.sh test-posix_spawn-dup2-stdin.sh-t
test_posix_spawnp_script_CPPFLAGS = $(AM_CPPFLAGS) -DSRCDIR=\"$(srcdir)/\"
-endif
int fd;
FILE *fp;
char line[80];
+ int line_len;
int status;
int exitstatus;
sigemptyset (&fatal_signal_set);
sigaddset (&fatal_signal_set, SIGINT);
sigaddset (&fatal_signal_set, SIGTERM);
+ #ifdef SIGHUP
sigaddset (&fatal_signal_set, SIGHUP);
+ #endif
+ #ifdef SIGPIPE
sigaddset (&fatal_signal_set, SIGPIPE);
+ #endif
sigprocmask (SIG_BLOCK, &fatal_signal_set, NULL);
actions_allocated = false;
attrs_allocated = false;
|| (err = posix_spawn_file_actions_addchdir (&actions, "/")) != 0
|| (err = posix_spawnattr_init (&attrs)) != 0
|| (attrs_allocated = true,
+ #if defined _WIN32 && !defined __CYGWIN__
+ 0
+ #else
(err = posix_spawnattr_setsigmask (&attrs, &blocked_signals)) != 0
- || (err = posix_spawnattr_setflags (&attrs, POSIX_SPAWN_SETSIGMASK)) != 0)
+ || (err = posix_spawnattr_setflags (&attrs, POSIX_SPAWN_SETSIGMASK)) != 0
+ #endif
+ )
|| (err = posix_spawnp (&child, pwd_prog, &actions, &attrs, argv, environ)) != 0))
{
if (actions_allocated)
sigprocmask (SIG_UNBLOCK, &fatal_signal_set, NULL);
close (ifd[1]);
fd = ifd[0];
- fp = fdopen (fd, "r");
+ fp = fdopen (fd, "rb");
if (fp == NULL)
{
fprintf (stderr, "fdopen() failed\n");
exit (1);
}
- if (fread (line, 1, 80, fp) < 2)
+ line_len = fread (line, 1, 80, fp);
+ if (line_len < 2)
{
fprintf (stderr, "could not read expected output\n");
exit (1);
}
- if (memcmp (line, "/\n", 2) != 0)
- {
- fprintf (stderr, "read output is not the expected output");
- exit (1);
- }
+ if (!(line_len == 2 && memcmp (line, "/\n", 2) == 0))
+#if defined _WIN32 && !defined __CYGWIN__
+ /* If the pwd program is Cygwin's pwd, its output in the root directory is
+ "/cygdrive/N", where N is a lowercase letter. */
+ if (!(line_len > 11
+ && memcmp (line, "/cygdrive/", 10) == 0
+ && line[10] >= 'a' && line[10] <= 'z'
+ && ((line_len == 12 && line[11] == '\n')
+ || (line_len == 13 && line[11] == '\r' && line[12] == '\n'))))
+#endif
+ {
+ fprintf (stderr, "read output is not the expected output\n");
+ exit (1);
+ }
fclose (fp);
status = 0;
while (waitpid (child, &status, 0) != child)
sigemptyset (&fatal_signal_set);
sigaddset (&fatal_signal_set, SIGINT);
sigaddset (&fatal_signal_set, SIGTERM);
+ #ifdef SIGHUP
sigaddset (&fatal_signal_set, SIGHUP);
+ #endif
+ #ifdef SIGPIPE
sigaddset (&fatal_signal_set, SIGPIPE);
+ #endif
sigprocmask (SIG_BLOCK, &fatal_signal_set, NULL);
actions_allocated = false;
attrs_allocated = false;
|| (err = posix_spawn_file_actions_addclose (&actions, ofd[1])) != 0
|| (err = posix_spawnattr_init (&attrs)) != 0
|| (attrs_allocated = true,
+ #if defined _WIN32 && !defined __CYGWIN__
+ 0
+ #else
(err = posix_spawnattr_setsigmask (&attrs, &blocked_signals)) != 0
- || (err = posix_spawnattr_setflags (&attrs, POSIX_SPAWN_SETSIGMASK)) != 0)
+ || (err = posix_spawnattr_setflags (&attrs, POSIX_SPAWN_SETSIGMASK)) != 0
+ #endif
+ )
|| (err = posix_spawnp (&child, BOURNE_SHELL, &actions, &attrs, argv, environ)) != 0))
{
if (actions_allocated)
sigemptyset (&fatal_signal_set);
sigaddset (&fatal_signal_set, SIGINT);
sigaddset (&fatal_signal_set, SIGTERM);
+ #ifdef SIGHUP
sigaddset (&fatal_signal_set, SIGHUP);
+ #endif
+ #ifdef SIGPIPE
sigaddset (&fatal_signal_set, SIGPIPE);
+ #endif
sigprocmask (SIG_BLOCK, &fatal_signal_set, NULL);
actions_allocated = false;
attrs_allocated = false;
|| (err = posix_spawn_file_actions_addopen (&actions, STDIN_FILENO, "/dev/null", O_RDONLY, 0)) != 0
|| (err = posix_spawnattr_init (&attrs)) != 0
|| (attrs_allocated = true,
+ #if defined _WIN32 && !defined __CYGWIN__
+ 0
+ #else
(err = posix_spawnattr_setsigmask (&attrs, &blocked_signals)) != 0
- || (err = posix_spawnattr_setflags (&attrs, POSIX_SPAWN_SETSIGMASK)) != 0)
+ || (err = posix_spawnattr_setflags (&attrs, POSIX_SPAWN_SETSIGMASK)) != 0
+ #endif
+ )
|| (err = posix_spawnp (&child, BOURNE_SHELL, &actions, &attrs, argv, environ)) != 0))
{
if (actions_allocated)
}
if (memcmp (line, "Halle Potta", 11) != 0)
{
- fprintf (stderr, "read output is not the expected output");
+ fprintf (stderr, "read output is not the expected output\n");
exit (1);
}
fclose (fp);
sigemptyset (&fatal_signal_set);
sigaddset (&fatal_signal_set, SIGINT);
sigaddset (&fatal_signal_set, SIGTERM);
+ #ifdef SIGHUP
sigaddset (&fatal_signal_set, SIGHUP);
+ #endif
+ #ifdef SIGPIPE
sigaddset (&fatal_signal_set, SIGPIPE);
+ #endif
sigprocmask (SIG_BLOCK, &fatal_signal_set, NULL);
actions_allocated = false;
attrs_allocated = false;
|| (err = posix_spawn_file_actions_addfchdir (&actions, rootfd)) != 0
|| (err = posix_spawnattr_init (&attrs)) != 0
|| (attrs_allocated = true,
+ #if defined _WIN32 && !defined __CYGWIN__
+ 0
+ #else
(err = posix_spawnattr_setsigmask (&attrs, &blocked_signals)) != 0
- || (err = posix_spawnattr_setflags (&attrs, POSIX_SPAWN_SETSIGMASK)) != 0)
+ || (err = posix_spawnattr_setflags (&attrs, POSIX_SPAWN_SETSIGMASK)) != 0
+ #endif
+ )
|| (err = posix_spawnp (&child, pwd_prog, &actions, &attrs, argv, environ)) != 0))
{
if (actions_allocated)
}
if (memcmp (line, "/\n", 2) != 0)
{
- fprintf (stderr, "read output is not the expected output");
+ fprintf (stderr, "read output is not the expected output\n");
exit (1);
}
fclose (fp);
#define CHILD_PROGRAM_FILENAME "test-posix_spawn-open1"
#define DATA_FILENAME "t!#$%&'()*+,-;=?@[\\]^_`{|}~.tmp"
-/* On Cygwin, '*' '?' '\\' '|' cannot be used in file names. */
-#if defined __CYGWIN__
+/* On Windows (including Cygwin), '*' '?' '\\' '|' cannot be used in file
+ names. */
+#if defined _WIN32 || defined __CYGWIN__
# undef DATA_FILENAME
# define DATA_FILENAME "t!#$%&'()+,-;=@[]^_`{}~.tmp"
#endif
}
}
+#if defined _WIN32 && !defined __CYGWIN__
+ /* On native Windows, scripts - even with '#!' marker - are not executable.
+ Only .bat and .cmd files are. */
+ fprintf (stderr, "Skipping test: scripts are not executable on this platform.\n");
+ return 77;
+#else
{
const char *prog_path = SRCDIR "executable-shell-script";
const char *prog_argv[2] = { prog_path, NULL };
return 1;
}
}
+#endif
/* Clean up data file. */
unlink (DATA_FILENAME);
}
}
+#if defined _WIN32 && !defined __CYGWIN__
+ /* On native Windows, scripts - even with '#!' marker - are not executable.
+ Only .bat and .cmd files are. */
+ fprintf (stderr, "Skipping test: scripts are not executable on this platform.\n");
+ return 77;
+#else
{
const char *prog_path = SRCDIR "executable-shell-script";
const char *prog_argv[2] = { prog_path, NULL };
return 1;
}
}
+#endif
/* Clean up data file. */
unlink (DATA_FILENAME);