dbus-marshal-byteswap: Byte-swap Unix fd indexes if needed
[platform/upstream/dbus.git] / dbus / 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);
74       _dbus_babysitter_set_child_exit_error (sitter, &error);
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) ||
87         dbus_error_has_name (&error, DBUS_ERROR_SPAWN_EXEC_FAILED)))
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
139         dbus_error_has_name (&error, DBUS_ERROR_SPAWN_CHILD_EXITED)))
140 #else
141         dbus_error_has_name (&error, DBUS_ERROR_SPAWN_CHILD_SIGNALED)))
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) ||
193         dbus_error_has_name (&error, DBUS_ERROR_SPAWN_CHILD_EXITED)))
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     {
228       _dbus_babysitter_kill_child (sitter);
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
248         dbus_error_has_name (&error, DBUS_ERROR_SPAWN_CHILD_EXITED)))
249 #else
250         dbus_error_has_name (&error, DBUS_ERROR_SPAWN_CHILD_SIGNALED)))
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
264 dbus_bool_t
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 }