D-Bus  1.12.16
dbus-spawn-test.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* dbus-spawn-test.c
3  *
4  * Copyright (C) 2002, 2003, 2004 Red Hat, Inc.
5  * Copyright (C) 2003 CodeFactory AB
6  * Copyright (C) 2005 Novell, Inc.
7  *
8  * Licensed under the Academic Free License version 2.1
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23  *
24  */
25 #include <config.h>
26 
27 
28 #include "dbus-spawn.h"
29 #include "dbus-sysdeps.h"
30 #include "dbus-test.h"
31 
32 static char *
33 get_test_exec (const char *exe,
34  DBusString *scratch_space)
35 {
36  const char *dbus_test_exec;
37 
38  dbus_test_exec = _dbus_getenv ("DBUS_TEST_EXEC");
39 
40  if (dbus_test_exec == NULL)
41  return NULL;
42 
43  if (!_dbus_string_init (scratch_space))
44  return NULL;
45 
46  if (!_dbus_string_append_printf (scratch_space, "%s/%s%s",
47  dbus_test_exec, exe, DBUS_EXEEXT))
48  {
49  _dbus_string_free (scratch_space);
50  return NULL;
51  }
52 
53  return _dbus_string_get_data (scratch_space);
54 }
55 
56 static dbus_bool_t
57 check_spawn_nonexistent (void *data)
58 {
59  static const char arg_does_not_exist[] = "/this/does/not/exist/32542sdgafgafdg";
60 
61  const char *argv[4] = { NULL, NULL, NULL, NULL };
62  DBusBabysitter *sitter = NULL;
63  DBusError error = DBUS_ERROR_INIT;
64 
65  /*** Test launching nonexistent binary */
66 
67  argv[0] = arg_does_not_exist;
68  if (_dbus_spawn_async_with_babysitter (&sitter, "spawn_nonexistent",
69  (char * const *) argv,
70  NULL, DBUS_SPAWN_NONE, NULL, NULL,
71  &error))
72  {
73  _dbus_babysitter_block_for_child_exit (sitter);
75  }
76 
77  if (sitter)
78  _dbus_babysitter_unref (sitter);
79 
80  if (!dbus_error_is_set (&error))
81  {
82  _dbus_warn ("Did not get an error launching nonexistent executable");
83  return FALSE;
84  }
85 
86  if (!(dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY) ||
88  {
89  _dbus_warn ("Not expecting error when launching nonexistent executable: %s: %s",
90  error.name, error.message);
91  dbus_error_free (&error);
92  return FALSE;
93  }
94 
95  dbus_error_free (&error);
96 
97  return TRUE;
98 }
99 
100 static dbus_bool_t
101 check_spawn_segfault (void *data)
102 {
103  char *argv[4] = { NULL, NULL, NULL, NULL };
104  DBusBabysitter *sitter = NULL;
105  DBusError error = DBUS_ERROR_INIT;
106  DBusString argv0;
107 
108  /*** Test launching segfault binary */
109 
110  argv[0] = get_test_exec ("test-segfault", &argv0);
111 
112  if (argv[0] == NULL)
113  {
114  /* OOM was simulated or DBUS_TEST_EXEC was unset; either is OK */
115  return TRUE;
116  }
117 
118  if (_dbus_spawn_async_with_babysitter (&sitter, "spawn_segfault", argv,
119  NULL, DBUS_SPAWN_NONE, NULL, NULL,
120  &error))
121  {
122  _dbus_babysitter_block_for_child_exit (sitter);
123  _dbus_babysitter_set_child_exit_error (sitter, &error);
124  }
125 
126  _dbus_string_free (&argv0);
127 
128  if (sitter)
129  _dbus_babysitter_unref (sitter);
130 
131  if (!dbus_error_is_set (&error))
132  {
133  _dbus_warn ("Did not get an error launching segfaulting binary");
134  return FALSE;
135  }
136 
137  if (!(dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY) ||
138 #ifdef DBUS_WIN
140 #else
142 #endif
143  {
144  _dbus_warn ("Not expecting error when launching segfaulting executable: %s: %s",
145  error.name, error.message);
146  dbus_error_free (&error);
147  return FALSE;
148  }
149 
150  dbus_error_free (&error);
151 
152  return TRUE;
153 }
154 
155 static dbus_bool_t
156 check_spawn_exit (void *data)
157 {
158  char *argv[4] = { NULL, NULL, NULL, NULL };
159  DBusBabysitter *sitter = NULL;
160  DBusError error = DBUS_ERROR_INIT;
161  DBusString argv0;
162 
163  /*** Test launching exit failure binary */
164 
165  argv[0] = get_test_exec ("test-exit", &argv0);
166 
167  if (argv[0] == NULL)
168  {
169  /* OOM was simulated or DBUS_TEST_EXEC was unset; either is OK */
170  return TRUE;
171  }
172 
173  if (_dbus_spawn_async_with_babysitter (&sitter, "spawn_exit", argv,
174  NULL, DBUS_SPAWN_NONE, NULL, NULL,
175  &error))
176  {
177  _dbus_babysitter_block_for_child_exit (sitter);
178  _dbus_babysitter_set_child_exit_error (sitter, &error);
179  }
180 
181  _dbus_string_free (&argv0);
182 
183  if (sitter)
184  _dbus_babysitter_unref (sitter);
185 
186  if (!dbus_error_is_set (&error))
187  {
188  _dbus_warn ("Did not get an error launching binary that exited with failure code");
189  return FALSE;
190  }
191 
192  if (!(dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY) ||
194  {
195  _dbus_warn ("Not expecting error when launching exiting executable: %s: %s",
196  error.name, error.message);
197  dbus_error_free (&error);
198  return FALSE;
199  }
200 
201  dbus_error_free (&error);
202 
203  return TRUE;
204 }
205 
206 static dbus_bool_t
207 check_spawn_and_kill (void *data)
208 {
209  char *argv[4] = { NULL, NULL, NULL, NULL };
210  DBusBabysitter *sitter = NULL;
211  DBusError error = DBUS_ERROR_INIT;
212  DBusString argv0;
213 
214  /*** Test launching sleeping binary then killing it */
215 
216  argv[0] = get_test_exec ("test-sleep-forever", &argv0);
217 
218  if (argv[0] == NULL)
219  {
220  /* OOM was simulated or DBUS_TEST_EXEC was unset; either is OK */
221  return TRUE;
222  }
223 
224  if (_dbus_spawn_async_with_babysitter (&sitter, "spawn_and_kill", argv,
225  NULL, DBUS_SPAWN_NONE, NULL, NULL,
226  &error))
227  {
229 
230  _dbus_babysitter_block_for_child_exit (sitter);
231 
232  _dbus_babysitter_set_child_exit_error (sitter, &error);
233  }
234 
235  _dbus_string_free (&argv0);
236 
237  if (sitter)
238  _dbus_babysitter_unref (sitter);
239 
240  if (!dbus_error_is_set (&error))
241  {
242  _dbus_warn ("Did not get an error after killing spawned binary");
243  return FALSE;
244  }
245 
246  if (!(dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY) ||
247 #ifdef DBUS_WIN
249 #else
251 #endif
252  {
253  _dbus_warn ("Not expecting error when killing executable: %s: %s",
254  error.name, error.message);
255  dbus_error_free (&error);
256  return FALSE;
257  }
258 
259  dbus_error_free (&error);
260 
261  return TRUE;
262 }
263 
265 _dbus_spawn_test (const char *test_data_dir)
266 {
267  if (!_dbus_test_oom_handling ("spawn_nonexistent",
268  check_spawn_nonexistent,
269  NULL))
270  return FALSE;
271 
272  if (!_dbus_test_oom_handling ("spawn_segfault",
273  check_spawn_segfault,
274  NULL))
275  return FALSE;
276 
277  if (!_dbus_test_oom_handling ("spawn_exit",
278  check_spawn_exit,
279  NULL))
280  return FALSE;
281 
282  if (!_dbus_test_oom_handling ("spawn_and_kill",
283  check_spawn_and_kill,
284  NULL))
285  return FALSE;
286 
287  return TRUE;
288 }