This source file includes following definitions.
- parent_main
- child_main
- cleanup_then_die
- main
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 #include <config.h>
23
24 #include <spawn.h>
25
26 #include "signature.h"
27 SIGNATURE_CHECK (posix_spawn, int, (pid_t *, char const *,
28 posix_spawn_file_actions_t const *,
29 posix_spawnattr_t const *,
30 char *const[], char *const[]));
31 #include <errno.h>
32 #include <fcntl.h>
33 #include <signal.h>
34 #include <stdbool.h>
35 #include <stdio.h>
36 #include <string.h>
37 #include <unistd.h>
38 #include <sys/types.h>
39 #include <sys/wait.h>
40
41 #define CHILD_PROGRAM_FILENAME "test-posix_spawn-open1"
42 #define DATA_FILENAME "t!#$%&'()*+,-;=?@[\\]^_`{|}~.tmp"
43
44
45 #if defined _WIN32 || defined __CYGWIN__
46 # undef DATA_FILENAME
47 # define DATA_FILENAME "t!#$%&'()+,-;=@[]^_`{}~.tmp"
48 #endif
49
50 static int
51 parent_main (void)
52 {
53 FILE *fp;
54 char *argv[3] = { CHILD_PROGRAM_FILENAME, "-child", NULL };
55 posix_spawn_file_actions_t actions;
56 bool actions_allocated;
57 int err;
58 pid_t child;
59 int status;
60 int exitstatus;
61
62
63 fp = fopen (DATA_FILENAME, "wb");
64 if (fp == NULL)
65 {
66 perror ("cannot create data file");
67 return 1;
68 }
69 fwrite ("Halle Potta", 1, 11, fp);
70 if (fflush (fp) || fclose (fp))
71 {
72 perror ("cannot prepare data file");
73 return 1;
74 }
75
76
77 if (freopen ("/dev/null", "rb", stdin) == NULL)
78 {
79 perror ("cannot redirect stdin");
80 return 1;
81 }
82
83
84
85 actions_allocated = false;
86 if ((err = posix_spawn_file_actions_init (&actions)) != 0
87 || (actions_allocated = true,
88 (err = posix_spawn_file_actions_addopen (&actions, STDIN_FILENO, DATA_FILENAME, O_RDONLY, 0600)) != 0
89 || (err = posix_spawn (&child, CHILD_PROGRAM_FILENAME, &actions, NULL, argv, environ)) != 0))
90 {
91 if (actions_allocated)
92 posix_spawn_file_actions_destroy (&actions);
93 errno = err;
94 perror ("subprocess failed");
95 return 1;
96 }
97 posix_spawn_file_actions_destroy (&actions);
98 status = 0;
99 while (waitpid (child, &status, 0) != child)
100 ;
101 if (!WIFEXITED (status))
102 {
103 fprintf (stderr, "subprocess terminated with unexpected wait status %d\n", status);
104 return 1;
105 }
106 exitstatus = WEXITSTATUS (status);
107 if (exitstatus != 0)
108 {
109 fprintf (stderr, "subprocess terminated with unexpected exit status %d\n", exitstatus);
110 return 1;
111 }
112 return 0;
113 }
114
115 static int
116 child_main (void)
117 {
118 char buf[1024];
119
120
121 if (fread (buf, 1, sizeof (buf), stdin) == 11
122 && memcmp (buf, "Halle Potta", 11) == 0)
123 return 0;
124 else
125 return 2;
126 }
127
128 static void
129 cleanup_then_die (int sig)
130 {
131
132 unlink (DATA_FILENAME);
133
134
135 signal (sig, SIG_DFL);
136 raise (sig);
137 }
138
139 int
140 main (int argc, char *argv[])
141 {
142 int exitstatus;
143
144 if (!(argc > 1 && strcmp (argv[1], "-child") == 0))
145 {
146
147 signal (SIGINT, cleanup_then_die);
148 signal (SIGTERM, cleanup_then_die);
149 #ifdef SIGHUP
150 signal (SIGHUP, cleanup_then_die);
151 #endif
152
153 exitstatus = parent_main ();
154 }
155 else
156 {
157
158
159 exitstatus = child_main ();
160 }
161 unlink (DATA_FILENAME);
162 return exitstatus;
163 }