Mercurial > hg > octave-lojdl > gnulib-hg
annotate tests/test-posix_spawn3.c @ 16465:c0803728f645
New module 'modfl-ieee'.
* modules/modfl-ieee: New file.
author | Bruno Haible <bruno@clisp.org> |
---|---|
date | Sun, 26 Feb 2012 17:55:31 +0100 |
parents | 8250f2777afc |
children | e542fd46ad6f |
rev | line source |
---|---|
10687 | 1 /* Test of posix_spawn() function. |
16201
8250f2777afc
maint: update all copyright year number ranges
Jim Meyering <meyering@redhat.com>
parents:
14079
diff
changeset
|
2 Copyright (C) 2008-2012 Free Software Foundation, Inc. |
10687 | 3 |
4 This program is free software: you can redistribute it and/or modify | |
5 it under the terms of the GNU General Public License as published by | |
6 the Free Software Foundation; either version 3 of the License, or | |
7 (at your option) any later version. | |
8 | |
9 This program is distributed in the hope that it will be useful, | |
10 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 GNU General Public License for more details. | |
13 | |
14 You should have received a copy of the GNU General Public License | |
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
16 | |
17 /* Written by Bruno Haible <bruno@clisp.org>, 2008. */ | |
18 | |
19 /* Test whether posix_spawn_file_actions_addopen supports filename arguments | |
20 that contain special characters such as '*'. */ | |
21 | |
22 #include <config.h> | |
23 | |
24 #include <spawn.h> | |
25 | |
12489 | 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[])); | |
10687 | 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 extern char **environ; | |
42 | |
43 #define CHILD_PROGRAM_FILENAME "test-posix_spawn3" | |
44 #define DATA_FILENAME "t!#$%&'()*+,-;=?@[\\]^_`{|}~.tmp" | |
12739
28283035637b
posix_spawn: Avoid test failure on Cygwin.
Bruno Haible <bruno@clisp.org>
parents:
12559
diff
changeset
|
45 /* On Cygwin, '*' '?' '\\' '|' cannot be used in file names. */ |
28283035637b
posix_spawn: Avoid test failure on Cygwin.
Bruno Haible <bruno@clisp.org>
parents:
12559
diff
changeset
|
46 #if defined __CYGWIN__ |
28283035637b
posix_spawn: Avoid test failure on Cygwin.
Bruno Haible <bruno@clisp.org>
parents:
12559
diff
changeset
|
47 # undef DATA_FILENAME |
28283035637b
posix_spawn: Avoid test failure on Cygwin.
Bruno Haible <bruno@clisp.org>
parents:
12559
diff
changeset
|
48 # define DATA_FILENAME "t!#$%&'()+,-;=@[]^_`{}~.tmp" |
28283035637b
posix_spawn: Avoid test failure on Cygwin.
Bruno Haible <bruno@clisp.org>
parents:
12559
diff
changeset
|
49 #endif |
10687 | 50 |
51 static int | |
52 parent_main (void) | |
53 { | |
54 FILE *fp; | |
55 char *argv[3] = { CHILD_PROGRAM_FILENAME, "-child", NULL }; | |
56 posix_spawn_file_actions_t actions; | |
57 bool actions_allocated; | |
58 int err; | |
59 pid_t child; | |
60 int status; | |
61 int exitstatus; | |
62 | |
63 /* Create a data file with specific contents. */ | |
64 fp = fopen (DATA_FILENAME, "wb"); | |
65 if (fp == NULL) | |
66 { | |
67 perror ("cannot create data file"); | |
68 return 1; | |
69 } | |
70 fwrite ("Halle Potta", 1, 11, fp); | |
71 if (fflush (fp) || fclose (fp)) | |
72 { | |
73 perror ("cannot prepare data file"); | |
74 return 1; | |
75 } | |
76 | |
77 /* Avoid reading from our stdin, as it could block. */ | |
78 freopen ("/dev/null", "rb", stdin); | |
79 | |
80 /* Test whether posix_spawn_file_actions_addopen with this file name | |
81 actually works, but spawning a child that reads from this file. */ | |
82 actions_allocated = false; | |
83 if ((err = posix_spawn_file_actions_init (&actions)) != 0 | |
84 || (actions_allocated = true, | |
85 (err = posix_spawn_file_actions_addopen (&actions, STDIN_FILENO, DATA_FILENAME, O_RDONLY, 0600)) != 0 | |
86 || (err = posix_spawn (&child, CHILD_PROGRAM_FILENAME, &actions, NULL, argv, environ)) != 0)) | |
87 { | |
88 if (actions_allocated) | |
89 posix_spawn_file_actions_destroy (&actions); | |
90 errno = err; | |
91 perror ("subprocess failed"); | |
92 return 1; | |
93 } | |
94 posix_spawn_file_actions_destroy (&actions); | |
95 status = 0; | |
96 while (waitpid (child, &status, 0) != child) | |
97 ; | |
98 if (!WIFEXITED (status)) | |
99 { | |
100 fprintf (stderr, "subprocess terminated with unexpected wait status %d\n", status); | |
101 return 1; | |
102 } | |
103 exitstatus = WEXITSTATUS (status); | |
104 if (exitstatus != 0) | |
105 { | |
106 fprintf (stderr, "subprocess terminated with unexpected exit status %d\n", exitstatus); | |
107 return 1; | |
108 } | |
109 return 0; | |
110 } | |
111 | |
112 static int | |
113 child_main (void) | |
114 { | |
115 char buf[1024]; | |
116 | |
117 /* See if reading from STDIN_FILENO yields the expected contents. */ | |
118 if (fread (buf, 1, sizeof (buf), stdin) == 11 | |
119 && memcmp (buf, "Halle Potta", 11) == 0) | |
120 return 0; | |
121 else | |
122 return 2; | |
123 } | |
124 | |
125 static void | |
126 cleanup_then_die (int sig) | |
127 { | |
128 /* Clean up data file. */ | |
129 unlink (DATA_FILENAME); | |
130 | |
131 /* Re-raise the signal and die from it. */ | |
132 signal (sig, SIG_DFL); | |
133 raise (sig); | |
134 } | |
135 | |
136 int | |
137 main (int argc, char *argv[]) | |
138 { | |
139 int exitstatus; | |
140 | |
141 if (!(argc > 1 && strcmp (argv[1], "-child") == 0)) | |
142 { | |
143 /* This is the parent process. */ | |
144 signal (SIGINT, cleanup_then_die); | |
145 signal (SIGTERM, cleanup_then_die); | |
146 #ifdef SIGHUP | |
147 signal (SIGHUP, cleanup_then_die); | |
148 #endif | |
149 | |
150 exitstatus = parent_main (); | |
151 } | |
152 else | |
153 { | |
154 /* This is the child process. */ | |
155 | |
156 exitstatus = child_main (); | |
157 } | |
158 unlink (DATA_FILENAME); | |
159 return exitstatus; | |
160 } |