https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=6df7cdc54b042451f76f3f9cbe3cc1138053a90c

commit 6df7cdc54b042451f76f3f9cbe3cc1138053a90c
Author: Jeremy Drake <cyg...@jdrake.com>
Date:   Tue Jun 17 16:40:56 2025 -0700

    Cygwin: testsuite: add posix_spawn tests
    
    Currently just a couple of tests of error conditions, but I have more
    tests to add.
    
    Signed-off-by: Jeremy Drake <cyg...@jdrake.com>

Diff:
---
 winsup/testsuite/Makefile.am                     |  1 +
 winsup/testsuite/winsup.api/posix_spawn/errors.c | 57 ++++++++++++++++++++++++
 winsup/testsuite/winsup.api/posix_spawn/test.h   | 38 ++++++++++++++++
 3 files changed, 96 insertions(+)

diff --git a/winsup/testsuite/Makefile.am b/winsup/testsuite/Makefile.am
index 8f2967a6d..0b265261c 100644
--- a/winsup/testsuite/Makefile.am
+++ b/winsup/testsuite/Makefile.am
@@ -311,6 +311,7 @@ check_PROGRAMS = \
        winsup.api/pthread/self2 \
        winsup.api/pthread/threadidafterfork \
        winsup.api/pthread/tsd1 \
+       winsup.api/posix_spawn/errors \
        winsup.api/samples/sample-fail \
        winsup.api/samples/sample-pass
 # winsup.api/ltp/ulimit01 is omitted as we don't have <ulimit.h>
diff --git a/winsup/testsuite/winsup.api/posix_spawn/errors.c 
b/winsup/testsuite/winsup.api/posix_spawn/errors.c
new file mode 100644
index 000000000..38563441f
--- /dev/null
+++ b/winsup/testsuite/winsup.api/posix_spawn/errors.c
@@ -0,0 +1,57 @@
+#include "test.h"
+#include <spawn.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static char tmppath[] = "pspawn.XXXXXX";
+static const char exit0[] = "exit 0\n";
+
+void cleanup_tmpfile (void)
+{
+  unlink (tmppath);
+}
+
+int main (void)
+{
+  pid_t pid;
+  int fd;
+  char *childargv[] = {"ls", NULL};
+  char tmpsub[sizeof (tmppath) + 3];
+  char *p;
+
+  /* unbuffer stdout */
+  setvbuf(stdout, NULL, _IONBF, 0);
+
+  negError (fd = mkstemp (tmppath));
+  atexit (cleanup_tmpfile);
+  negError (write (fd, exit0, sizeof (exit0) - 1));
+  negError (close (fd));
+
+  /* expected ENOENT: posix_spawn without full path */
+  errCodeExpected (ENOENT,
+      posix_spawn (&pid, childargv[0], NULL, NULL, childargv, environ));
+
+  /* expected EACCES: posix_spawn with path to non-executable file */
+  errCodeExpected (EACCES,
+      posix_spawn (&pid, tmppath, NULL, NULL, childargv, environ));
+
+  negError (chmod (tmppath, 0755));
+
+  /* expected ENOEXEC: posix_spawn with unrecognized file format */
+  errCodeExpected (ENOEXEC,
+      posix_spawn (&pid, tmppath, NULL, NULL, childargv, environ));
+
+  p = stpcpy (tmpsub, tmppath);
+  p = stpcpy (p, "/ls");
+
+#ifndef __CYGWIN__
+  /* Cygwin returns ENOENT rather than ENOTDIR here */
+  /* expected ENOTDIR: posix_spawn with file as non-leaf entry in path */
+  errCodeExpected (ENOTDIR,
+      posix_spawn (&pid, tmpsub, NULL, NULL, childargv, environ));
+#endif
+
+  return 0;
+}
diff --git a/winsup/testsuite/winsup.api/posix_spawn/test.h 
b/winsup/testsuite/winsup.api/posix_spawn/test.h
new file mode 100644
index 000000000..e10b6ce5e
--- /dev/null
+++ b/winsup/testsuite/winsup.api/posix_spawn/test.h
@@ -0,0 +1,38 @@
+#ifndef _POSIX_SPAWN_TEST_H_
+#define _POSIX_SPAWN_TEST_H_
+
+#define _GNU_SOURCE
+#include <errno.h>
+#include <error.h>
+#include <signal.h>
+#include <sys/wait.h>
+
+#define negError(x) do { \
+  if ((x) < 0) \
+    error_at_line(1, errno, __FILE__, __LINE__, "%s", #x); \
+} while (0)
+
+#define sigError(x) do { \
+  if ((x) == SIG_ERR) \
+    error_at_line(1, errno, __FILE__, __LINE__, "%s", #x); \
+} while (0)
+
+#define errCodeExpected(expected, x) do { \
+  int _errcode = (x); \
+  if (_errcode != (expected)) \
+    error_at_line(1, _errcode, __FILE__, __LINE__, "%s", #x); \
+} while (0)
+
+#define errCode(x) errCodeExpected(0, x)
+
+#define exitStatus(status, expectedExitCode) do { \
+  if (WIFSIGNALED ((status))) \
+    error_at_line (128 + WTERMSIG ((status)), 0, __FILE__, __LINE__ - 2, \
+                  "child terminated with signal %d", WTERMSIG ((status))); \
+  else if (WIFEXITED ((status)) && WEXITSTATUS ((status)) != 
(expectedExitCode)) \
+    error_at_line (WEXITSTATUS ((status)), 0, __FILE__, __LINE__ - 2, \
+                  "child exited with code %d", WEXITSTATUS ((status))); \
+} while (0)
+
+#endif /* _POSIX_SPAWN_TEST_H_ */
+

Reply via email to