aboutsummaryrefslogtreecommitdiff
path: root/winsup/testsuite/winsup.api/posix_spawn/win32.c
diff options
context:
space:
mode:
Diffstat (limited to 'winsup/testsuite/winsup.api/posix_spawn/win32.c')
-rw-r--r--winsup/testsuite/winsup.api/posix_spawn/win32.c181
1 files changed, 181 insertions, 0 deletions
diff --git a/winsup/testsuite/winsup.api/posix_spawn/win32.c b/winsup/testsuite/winsup.api/posix_spawn/win32.c
new file mode 100644
index 0000000..8998c43
--- /dev/null
+++ b/winsup/testsuite/winsup.api/posix_spawn/win32.c
@@ -0,0 +1,181 @@
+#include "test.h"
+#include <dlfcn.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <spawn.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/cygwin.h>
+#include <unistd.h>
+
+char * find_winchild (void)
+{
+ static const char winchild[] = "/winchild";
+ char *mingwtestdir = getenv ("mingwtestdir");
+ if (!mingwtestdir)
+ {
+ Dl_info dli;
+ if (dladdr (&find_winchild, &dli))
+ {
+ ssize_t i = strlen (dli.dli_fname) - 1;
+ for (int slashes = 0; i >= 0 && slashes < 3; --i)
+ if (dli.dli_fname[i] == '/')
+ slashes++;
+ stpcpy (stpcpy (dli.dli_fname + i + 1, "/mingw"), winchild);
+ return realpath (dli.dli_fname, NULL);
+ }
+ else
+ {
+ return realpath ("../../mingw/winchild", NULL);
+ }
+ }
+ else
+ {
+ char *ret, *tmp = malloc (strlen (mingwtestdir) + sizeof (winchild));
+ stpcpy (stpcpy (tmp, mingwtestdir), winchild);
+ ret = realpath (tmp, NULL);
+ free (tmp);
+ return ret;
+ }
+}
+
+static char tmppath[] = "pspawn.XXXXXX";
+static char tmpcwd[] = "tmpcwd.XXXXXX";
+static char tmppath2[sizeof (tmpcwd) + 9] = {0};
+
+static void cleanup_tmpfiles (void)
+{
+ if (tmppath2[0])
+ unlink (tmppath2);
+ rmdir (tmpcwd);
+ unlink (tmppath);
+}
+
+int main (void)
+{
+ posix_spawn_file_actions_t fa;
+ pid_t pid;
+ int status;
+ int fd, fdcloexec, cwdfd;
+ char *childargv[] = {"winchild", NULL, NULL, NULL};
+ char *winchild = find_winchild ();
+
+ /* unbuffer stdout */
+ setvbuf(stdout, NULL, _IONBF, 0);
+
+ /* temp regular file */
+ negError (fd = mkstemp (tmppath));
+ atexit (cleanup_tmpfiles);
+ negError (close (fd));
+
+ /* temp directory */
+ nullError (mkdtemp (tmpcwd));
+
+ /* temp file within temp directory */
+ stpcpy (stpcpy (stpcpy (tmppath2, tmpcwd), "/"), "tmpfile2");
+ negError (fd = open (tmppath2, O_RDWR|O_CREAT|O_EXCL, S_IRUSR|S_IWUSR));
+ negError (close (fd));
+
+ /* open file descriptors to test inheritance */
+ negError (fd = open ("/dev/null", O_RDONLY, 0644));
+ negError (fdcloexec = open ("/dev/full", O_RDONLY|O_CLOEXEC, 0644));
+
+ /* test posix_spawn_file_actions_addopen */
+ errCode (posix_spawn_file_actions_init (&fa));
+ errCode (posix_spawn_file_actions_addopen (&fa, 0, "/dev/zero", O_RDONLY,
+ 0644));
+ childargv[1] = "0";
+ childargv[2] = "\\Device\\Null";
+ errCode (posix_spawn (&pid, winchild, &fa, NULL, childargv, environ));
+ negError (waitpid (pid, &status, 0));
+ exitStatus (status, 0);
+ errCode (posix_spawn_file_actions_destroy (&fa));
+
+ /* test posix_spawn_file_actions_adddup2 */
+ errCode (posix_spawn_file_actions_init (&fa));
+ errCode (posix_spawn_file_actions_adddup2 (&fa, fd, 0));
+ errCode (posix_spawn (&pid, winchild, &fa, NULL, childargv, environ));
+ negError (waitpid (pid, &status, 0));
+ exitStatus (status, 0);
+ errCode (posix_spawn_file_actions_destroy (&fa));
+
+ /* test posix_spawn_file_actions_adddup2 with CLOEXEC fd */
+ errCode (posix_spawn_file_actions_init (&fa));
+ errCode (posix_spawn_file_actions_adddup2 (&fa, fdcloexec, 0));
+ errCode (posix_spawn (&pid, winchild, &fa, NULL, childargv, environ));
+ negError (waitpid (pid, &status, 0));
+ exitStatus (status, 0);
+ errCode (posix_spawn_file_actions_destroy (&fa));
+
+ /* test posix_spawn_file_actions_adddup2 with out to err */
+ errCode (posix_spawn_file_actions_init (&fa));
+ errCode (posix_spawn_file_actions_addopen (&fa, 1, "/dev/zero", O_WRONLY,
+ 0644));
+ errCode (posix_spawn_file_actions_adddup2 (&fa, 1, 2));
+ childargv[1] = "2";
+ errCode (posix_spawn (&pid, winchild, &fa, NULL, childargv, environ));
+ negError (waitpid (pid, &status, 0));
+ exitStatus (status, 0);
+ errCode (posix_spawn_file_actions_destroy (&fa));
+
+ /* test posix_spawn_file_actions_addopen with real file */
+ errCode (posix_spawn_file_actions_init (&fa));
+ errCode (posix_spawn_file_actions_addopen (&fa, 1, tmppath, O_WRONLY, 0644));
+ childargv[1] = "1";
+ childargv[2] = cygwin_create_path (CCP_POSIX_TO_WIN_A|CCP_ABSOLUTE, tmppath);
+ errCode (posix_spawn (&pid, winchild, &fa, NULL, childargv, environ));
+ negError (waitpid (pid, &status, 0));
+ exitStatus (status, 0);
+ errCode (posix_spawn_file_actions_destroy (&fa));
+ free (childargv[2]);
+
+ /* test posix_spawn_file_actions_addchdir */
+ errCode (posix_spawn_file_actions_init (&fa));
+ errCode (posix_spawn_file_actions_addchdir (&fa, tmpcwd));
+ childargv[1] = "CWD";
+ childargv[2] = cygwin_create_path (CCP_POSIX_TO_WIN_A|CCP_ABSOLUTE, tmpcwd);
+ errCode (posix_spawn (&pid, winchild, &fa, NULL, childargv, environ));
+ negError (waitpid (pid, &status, 0));
+ exitStatus (status, 0);
+ errCode (posix_spawn_file_actions_destroy (&fa));
+
+ /* test posix_spawn_file_actions_addfchdir */
+ negError (cwdfd = open (tmpcwd, O_SEARCH|O_DIRECTORY|O_CLOEXEC, 0755));
+ errCode (posix_spawn_file_actions_init (&fa));
+ errCode (posix_spawn_file_actions_addfchdir (&fa, cwdfd));
+ errCode (posix_spawn (&pid, winchild, &fa, NULL, childargv, environ));
+ negError (waitpid (pid, &status, 0));
+ exitStatus (status, 0);
+ errCode (posix_spawn_file_actions_destroy (&fa));
+ free (childargv[2]);
+
+ /* test posix_spawn_file_actions_addfchdir followed by addopen */
+ errCode (posix_spawn_file_actions_init (&fa));
+ errCode (posix_spawn_file_actions_addfchdir (&fa, cwdfd));
+ errCode (posix_spawn_file_actions_addopen (&fa, 1, "tmpfile2", O_WRONLY, 0644));
+ childargv[1] = "1";
+ childargv[2] = cygwin_create_path (CCP_POSIX_TO_WIN_A|CCP_ABSOLUTE, tmppath2);
+ errCode (posix_spawn (&pid, winchild, &fa, NULL, childargv, environ));
+ negError (waitpid (pid, &status, 0));
+ exitStatus (status, 0);
+ errCode (posix_spawn_file_actions_destroy (&fa));
+ free (childargv[2]);
+
+ /* test posix_spawn_file_actions_adddup2 of directory handle */
+ errCode (posix_spawn_file_actions_init (&fa));
+ errCode (posix_spawn_file_actions_adddup2 (&fa, cwdfd, 0));
+ childargv[1] = "0";
+ childargv[2] = cygwin_create_path (CCP_POSIX_TO_WIN_A|CCP_ABSOLUTE, tmpcwd);
+ errCode (posix_spawn (&pid, winchild, &fa, NULL, childargv, environ));
+ negError (waitpid (pid, &status, 0));
+ exitStatus (status, 0);
+ errCode (posix_spawn_file_actions_destroy (&fa));
+ free (childargv[2]);
+
+ negError (close (cwdfd));
+ negError (close (fd));
+ negError (close (fdcloexec));
+
+ return 0;
+}