1 #include <darwintest.h>
7 #include <spawn_private.h>
13 #include <sys/proc_info.h>
14 #include <sys/spawn_internal.h>
15 #include <sys/sysctl.h>
18 #include <sys/fileport.h>
20 T_GLOBAL_META(T_META_RUN_CONCURRENTLY(true));
22 T_DECL(posix_spawn_file_actions_add_fileportdup2_np
,
23 "Check posix_spawnattr for posix_spawn_file_actions_add_fileportdup2_np",
26 posix_spawnattr_t attr
;
27 posix_spawn_file_actions_t fact
;
32 T_QUIET
; T_ASSERT_POSIX_SUCCESS(ret
, "pipe");
34 ret
= fileport_makeport(pipes
[1], &mp
);
35 T_QUIET
; T_ASSERT_POSIX_SUCCESS(ret
, "fileport_makefd");
37 ret
= posix_spawnattr_init(&attr
);
38 T_QUIET
; T_ASSERT_POSIX_SUCCESS(ret
, "posix_spawnattr_init");
40 ret
= posix_spawn_file_actions_init(&fact
);
41 T_QUIET
; T_ASSERT_POSIX_SUCCESS(ret
, "posix_spawn_file_actions_init");
43 ret
= posix_spawn_file_actions_add_fileportdup2_np(&fact
, mp
, STDOUT_FILENO
);
44 T_ASSERT_POSIX_SUCCESS(ret
, "posix_spawn_file_actions_add_fileportdup2_np");
46 char * const prog
= "/bin/echo";
47 char * const argv_child
[] = { prog
, "1", NULL
};
49 extern char **environ
;
51 ret
= posix_spawn(&child_pid
, prog
, &fact
, &attr
, argv_child
, environ
);
52 T_ASSERT_POSIX_SUCCESS(ret
, "posix_spawn");
54 ret
= posix_spawn_file_actions_destroy(&fact
);
55 T_QUIET
; T_ASSERT_POSIX_SUCCESS(ret
, "posix_spawn_file_actions_destroy");
57 ret
= posix_spawnattr_destroy(&attr
);
58 T_QUIET
; T_ASSERT_POSIX_SUCCESS(ret
, "posix_spawnattr_destroy");
60 T_LOG("parent: spawned child with pid %d\n", child_pid
);
63 int waitpid_result
= waitpid(child_pid
, &status
, 0);
64 T_ASSERT_POSIX_SUCCESS(waitpid_result
, "waitpid");
65 T_ASSERT_EQ(waitpid_result
, child_pid
, "waitpid should return child we spawned");
66 T_ASSERT_EQ(WIFEXITED(status
), 1, "child should have exited normally");
67 T_ASSERT_EQ(WEXITSTATUS(status
), EX_OK
, "child should have exited with success");
70 ssize_t rc
= read(pipes
[0], buf
, sizeof(buf
));
71 T_ASSERT_POSIX_SUCCESS(rc
, "read");
72 T_ASSERT_EQ(rc
, 1l, "should have read one byte");
73 T_ASSERT_EQ(buf
[0], '1', "should have read '1'");