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