Merge lp:~xnox/upstart/async-remove-duplicate-event into lp:upstart/async
- async-remove-duplicate-event
- Merge into async
Proposed by
Dimitri John Ledkov
Status: | Superseded |
---|---|
Proposed branch: | lp:~xnox/upstart/async-remove-duplicate-event |
Merge into: | lp:upstart/async |
Diff against target: |
2287 lines (+235/-1090) 8 files modified
init/job.c (+4/-17) init/job.h (+0/-2) init/job_process.c (+0/-837) init/job_process.h (+1/-5) init/tests/test_event.c (+4/-2) init/tests/test_job.c (+4/-19) init/tests/test_job_process.c (+187/-208) test/test_util_common.h (+35/-0) |
To merge this branch: | bzr merge lp:~xnox/upstart/async-remove-duplicate-event |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
James Hunt | Pending | ||
Review via email:
|
This proposal has been superseded by a proposal from 2014-05-21.
Commit message
Description of the change
To post a comment you must log in.
Revision history for this message
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Dimitri John Ledkov (xnox) wrote : | # |
Unmerged revisions
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'init/job.c' |
2 | --- init/job.c 2014-05-20 13:23:17 +0000 |
3 | +++ init/job.c 2014-05-21 22:39:37 +0000 |
4 | @@ -978,23 +978,8 @@ |
5 | |
6 | |
7 | /** |
8 | - * job_emit_event: |
9 | - * @job: job generating the event, |
10 | - * |
11 | - * Compat function, for migration to job_emit_event_with_state. |
12 | - * |
13 | - * Returns: new Event in the queue. |
14 | - **/ |
15 | -Event * |
16 | -job_emit_event (Job *job) |
17 | -{ |
18 | - return job_emit_event_with_state (job, job->state); |
19 | -} |
20 | - |
21 | -/** |
22 | * job_emit_event_with_state: |
23 | * @job: job generating the event, |
24 | - * @state: state job is moving to. |
25 | * |
26 | * Called from a state change because it believes an event should be |
27 | * emitted. Constructs the event with the right arguments and environment |
28 | @@ -1012,7 +997,7 @@ |
29 | * Returns: new Event in the queue. |
30 | **/ |
31 | Event * |
32 | -job_emit_event_with_state (Job *job, JobState state) |
33 | +job_emit_event (Job *job) |
34 | { |
35 | Event *event; |
36 | const char *name; |
37 | @@ -1023,7 +1008,7 @@ |
38 | |
39 | nih_assert (job != NULL); |
40 | |
41 | - switch (state) { |
42 | + switch (job->state) { |
43 | case JOB_STARTING: |
44 | name = JOB_STARTING_EVENT; |
45 | block = TRUE; |
46 | @@ -2595,6 +2580,8 @@ |
47 | nih_assert (process > PROCESS_INVALID); |
48 | nih_assert (process < PROCESS_LAST); |
49 | |
50 | + job->pid[process] = 0; |
51 | + |
52 | switch (process) { |
53 | case PROCESS_SECURITY: |
54 | job_failed (job, PROCESS_SECURITY, -1); |
55 | |
56 | === modified file 'init/job.h' |
57 | --- init/job.h 2014-05-16 12:12:20 +0000 |
58 | +++ init/job.h 2014-05-21 22:39:37 +0000 |
59 | @@ -238,8 +238,6 @@ |
60 | void job_finished (Job *job, int failed); |
61 | |
62 | Event *job_emit_event (Job *job); |
63 | -Event *job_emit_event_with_state (Job *job, JobState state); |
64 | - |
65 | |
66 | const char *job_name (Job *job); |
67 | |
68 | |
69 | === modified file 'init/job_process.c' |
70 | --- init/job_process.c 2014-05-21 16:52:42 +0000 |
71 | +++ init/job_process.c 2014-05-21 22:39:37 +0000 |
72 | @@ -111,8 +111,6 @@ |
73 | static void job_process_error_abort (int fd, JobProcessErrorType type, |
74 | int arg) |
75 | __attribute__ ((noreturn)); |
76 | -static int job_process_error_read (int fd) |
77 | - __attribute__ ((warn_unused_result)); |
78 | static void job_process_remap_fd (int *fd, int reserved_fd, int error_fd); |
79 | |
80 | /** |
81 | @@ -149,802 +147,6 @@ |
82 | extern int session_end; |
83 | extern time_t quiesce_phase_time; |
84 | |
85 | -/** |
86 | - * job_process_run: |
87 | - * @job: job context for process to be run in, |
88 | - * @process: job process to run. |
89 | - * |
90 | - * This function looks up @process in the job's process table and uses |
91 | - * the information there to spawn a new process for the @job, storing the |
92 | - * pid in that table entry. |
93 | - * |
94 | - * The process is normally executed using the system shell, unless the |
95 | - * script member of @process is FALSE and there are no typical shell |
96 | - * characters within the command member, in which case it is executed |
97 | - * directly using exec after splitting on whitespace. |
98 | - * |
99 | - * When executed with the shell, if the command (which may be an entire |
100 | - * script) is reasonably small (less than 1KB) it is passed to the |
101 | - * shell using the POSIX-specified -c option. Otherwise the shell is told |
102 | - * to read commands from one of the special /proc/self/fd/NN devices and NihIo |
103 | - * used to feed the script into that device. A pointer to the NihIo object |
104 | - * is not kept or stored because it will automatically clean itself up should |
105 | - * the script go away as the other end of the pipe will be closed. |
106 | - * |
107 | - * In either case the shell is run with the -e option so that commands will |
108 | - * fail if their exit status is not checked. |
109 | - * |
110 | - * This function will block until the job_process_spawn() call succeeds or |
111 | - * a non-temporary error occurs (such as file not found). It is up to the |
112 | - * called to decide whether non-temporary errors are a reason to change the |
113 | - * job state or not. |
114 | - * |
115 | - * Returns: zero on success, negative value on non-temporary error. |
116 | - **/ |
117 | -int |
118 | -job_process_run (Job *job, |
119 | - ProcessType process) |
120 | -{ |
121 | - Process *proc; |
122 | - nih_local char **argv = NULL; |
123 | - nih_local char **env = NULL; |
124 | - nih_local char *script = NULL; |
125 | - char **e; |
126 | - size_t argc, envc; |
127 | - int fds[2] = { -1, -1 }; |
128 | - int error = FALSE, trace = FALSE, shell = FALSE; |
129 | - |
130 | - nih_assert (job != NULL); |
131 | - |
132 | - proc = job->class->process[process]; |
133 | - nih_assert (proc != NULL); |
134 | - nih_assert (proc->command != NULL); |
135 | - |
136 | - /* We run the process using a shell if it says it wants to be run |
137 | - * as such, or if it contains any shell-like characters; since that's |
138 | - * the best way to deal with things like variables. |
139 | - */ |
140 | - if ((proc->script) || strpbrk (proc->command, SHELL_CHARS)) { |
141 | - char *nl, *p; |
142 | - |
143 | - argc = 0; |
144 | - argv = NIH_MUST (nih_str_array_new (NULL)); |
145 | - |
146 | - NIH_MUST (nih_str_array_add (&argv, NULL, &argc, SHELL)); |
147 | - NIH_MUST (nih_str_array_add (&argv, NULL, &argc, "-e")); |
148 | - |
149 | - /* If the process wasn't originally marked to be run through |
150 | - * a shell, prepend exec to the script so that the shell |
151 | - * gets out of the way after parsing. |
152 | - */ |
153 | - if (proc->script) { |
154 | - script = NIH_MUST (nih_strdup (NULL, proc->command)); |
155 | - } else { |
156 | - script = NIH_MUST (nih_sprintf (NULL, "exec %s", |
157 | - proc->command)); |
158 | - } |
159 | - |
160 | - /* Don't pipe single-line scripts into the shell using |
161 | - * /proc/self/fd/NNN, instead just pass them over the |
162 | - * command-line (taking care to strip off the trailing |
163 | - * newlines). |
164 | - */ |
165 | - p = nl = strchr (script, '\n'); |
166 | - while (p && (*p == '\n')) |
167 | - p++; |
168 | - |
169 | - if ((! nl) || (! *p)) { |
170 | - /* Strip off the newline(s) */ |
171 | - if (nl) |
172 | - *nl = '\0'; |
173 | - |
174 | - NIH_MUST (nih_str_array_add (&argv, NULL, |
175 | - &argc, "-c")); |
176 | - NIH_MUST (nih_str_array_addp (&argv, NULL, |
177 | - &argc, script)); |
178 | - |
179 | - /* Next argument is argv[0]; just pass the shell */ |
180 | - NIH_MUST (nih_str_array_add (&argv, NULL, |
181 | - &argc, SHELL)); |
182 | - } else { |
183 | - nih_local char *cmd = NULL; |
184 | - |
185 | - /* Close the writing end when the child is exec'd */ |
186 | - NIH_ZERO (pipe (fds)); |
187 | - nih_io_set_cloexec (fds[1]); |
188 | - |
189 | - shell = TRUE; |
190 | - |
191 | - cmd = NIH_MUST (nih_sprintf (argv, "%s/%d", |
192 | - "/proc/self/fd", |
193 | - JOB_PROCESS_SCRIPT_FD)); |
194 | - NIH_MUST (nih_str_array_addp (&argv, NULL, |
195 | - &argc, cmd)); |
196 | - } |
197 | - } else { |
198 | - /* Split the command on whitespace to produce a list of |
199 | - * arguments that we can exec directly. |
200 | - */ |
201 | - argv = NIH_MUST (nih_str_split (NULL, proc->command, |
202 | - " \t\r\n", TRUE)); |
203 | - } |
204 | - |
205 | - /* We provide the standard job environment to all of its processes, |
206 | - * except for pre-stop which also has the stop event environment, |
207 | - * adding special variables that indicate which job it was -- mostly |
208 | - * so that initctl can have clever behaviour when called within them. |
209 | - */ |
210 | - envc = 0; |
211 | - env = NIH_MUST (nih_str_array_new (NULL)); |
212 | - |
213 | - if (job->env) |
214 | - NIH_MUST (environ_append (&env, NULL, &envc, TRUE, job->env)); |
215 | - |
216 | - if (job->stop_env |
217 | - && ((process == PROCESS_PRE_STOP) |
218 | - || (process == PROCESS_POST_STOP))) |
219 | - for (e = job->stop_env; *e; e++) |
220 | - NIH_MUST (environ_set (&env, NULL, &envc, TRUE, *e)); |
221 | - |
222 | - NIH_MUST (environ_set (&env, NULL, &envc, TRUE, |
223 | - "UPSTART_JOB=%s", job->class->name)); |
224 | - NIH_MUST (environ_set (&env, NULL, &envc, TRUE, |
225 | - "UPSTART_INSTANCE=%s", job->name)); |
226 | - if (user_mode) |
227 | - NIH_MUST (environ_set (&env, NULL, &envc, TRUE, |
228 | - "UPSTART_SESSION=%s", control_server_address)); |
229 | - |
230 | - /* If we're about to spawn the main job and we expect it to become |
231 | - * a daemon or fork before we can move out of spawned, we need to |
232 | - * set a trace on it. |
233 | - */ |
234 | - if ((process == PROCESS_MAIN) |
235 | - && ((job->class->expect == EXPECT_DAEMON) |
236 | - || (job->class->expect == EXPECT_FORK))) |
237 | - trace = TRUE; |
238 | - |
239 | - /* Spawn the process, repeat until fork() works */ |
240 | - while ((job->pid[process] = job_process_spawn (job, argv, env, |
241 | - trace, fds[0], process)) < 0) { |
242 | - NihError *err; |
243 | - |
244 | - err = nih_error_get (); |
245 | - if (err->number == JOB_PROCESS_ERROR) { |
246 | - /* Non-temporary error condition, we're not going |
247 | - * to be able to spawn this process. Clean up after |
248 | - * ourselves before returning. |
249 | - */ |
250 | - if (shell) { |
251 | - close (fds[0]); |
252 | - close (fds[1]); |
253 | - } |
254 | - |
255 | - job->pid[process] = 0; |
256 | - |
257 | - /* Return non-temporary error condition */ |
258 | - nih_warn (_("Failed to spawn %s %s process: %s"), |
259 | - job_name (job), process_name (process), |
260 | - err->message); |
261 | - nih_free (err); |
262 | - return -1; |
263 | - } else if (! error) |
264 | - nih_warn ("%s: %s", _("Temporary process spawn error"), |
265 | - err->message); |
266 | - nih_free (err); |
267 | - |
268 | - error = TRUE; |
269 | - } |
270 | - |
271 | - nih_info (_("%s %s process (%d)"), |
272 | - job_name (job), process_name (process), job->pid[process]); |
273 | - |
274 | - job->trace_forks = 0; |
275 | - job->trace_state = trace ? TRACE_NEW : TRACE_NONE; |
276 | - |
277 | - /* Feed the script to the child process */ |
278 | - if (shell) { |
279 | - NihIo *io; |
280 | - |
281 | - /* Clean up and close the reading end (we don't need it) */ |
282 | - close (fds[0]); |
283 | - |
284 | - /* Put the entire script into an NihIo send buffer and |
285 | - * then mark it for closure so that the shell gets EOF |
286 | - * and the structure gets cleaned up automatically. |
287 | - */ |
288 | - while (! (io = nih_io_reopen (job, fds[1], NIH_IO_STREAM, |
289 | - NULL, NULL, NULL, NULL))) { |
290 | - NihError *err; |
291 | - |
292 | - err = nih_error_get (); |
293 | - if (err->number != ENOMEM) |
294 | - nih_assert_not_reached (); |
295 | - nih_free (err); |
296 | - } |
297 | - |
298 | - /* We're feeding using a pipe, which has a file descriptor |
299 | - * on the child end even though it open()s it again using |
300 | - * a path. Instruct the shell to close this extra fd and |
301 | - * not to leak it. |
302 | - */ |
303 | - NIH_ZERO (nih_io_printf (io, "exec %d<&-\n", |
304 | - JOB_PROCESS_SCRIPT_FD)); |
305 | - |
306 | - NIH_ZERO (nih_io_write (io, script, strlen (script))); |
307 | - nih_io_shutdown (io); |
308 | - } |
309 | - |
310 | - return 0; |
311 | -} |
312 | - |
313 | - |
314 | -/** |
315 | - * job_process_spawn: |
316 | - * @job: job of process to be spawned, |
317 | - * @argv: NULL-terminated list of arguments for the process, |
318 | - * @env: NULL-terminated list of environment variables for the process, |
319 | - * @trace: whether to trace this process, |
320 | - * @script_fd: script file descriptor, |
321 | - * @process: job process to spawn. |
322 | - * |
323 | - * This function spawns a new process using the class details in @job to set up |
324 | - * the environment for it; the process is always a session and process group |
325 | - * leader as we never want anything in our own group. |
326 | - * |
327 | - * The process to be executed is given in the @argv array which is passed |
328 | - * directly to execvp(), so should be in the same NULL-terminated form with |
329 | - * the first argument containing the path or filename of the binary. The |
330 | - * PATH environment in the @job's associated class will be searched. |
331 | - * |
332 | - * If @trace is TRUE, the process will be traced with ptrace and this will |
333 | - * cause the process to be stopped when the exec() call is made. You must |
334 | - * wait for this and then may use it to set options before continuing the |
335 | - * process. |
336 | - * |
337 | - * If @script_fd is not -1, this file descriptor is dup()d to the special fd 9 |
338 | - * (moving any other out of the way if necessary). |
339 | - * |
340 | - * This function only spawns the process, it is up to the caller to ensure |
341 | - * that the information is saved into the job and that the process is watched, |
342 | - * etc. |
343 | - * |
344 | - * Spawning a process may fail for temporary reasons, usually due to a failure |
345 | - * of the fork() syscall or communication with the child; or more permanent |
346 | - * reasons such as a failure to setup the child environment. These latter |
347 | - * are always represented by a JOB_PROCESS_ERROR error. |
348 | - * |
349 | - * Returns: process id of new process on success, -1 on raised error |
350 | - **/ |
351 | -pid_t |
352 | -job_process_spawn (Job *job, |
353 | - char * const argv[], |
354 | - char * const *env, |
355 | - int trace, |
356 | - int script_fd, |
357 | - ProcessType process) |
358 | -{ |
359 | - sigset_t child_set, orig_set; |
360 | - pid_t pid; |
361 | - int i, fds[2]; |
362 | - int pty_master = -1; |
363 | - int pty_slave = -1; |
364 | - char pts_name[PATH_MAX]; |
365 | - char filename[PATH_MAX]; |
366 | - FILE *fd; |
367 | - nih_local char *log_path = NULL; |
368 | - JobClass *class; |
369 | - uid_t job_setuid = -1; |
370 | - gid_t job_setgid = -1; |
371 | - struct passwd *pwd = NULL; |
372 | - struct group *grp = NULL; |
373 | - |
374 | - |
375 | - nih_assert (job != NULL); |
376 | - nih_assert (job->class != NULL); |
377 | - nih_assert (job->log != NULL); |
378 | - nih_assert (process < PROCESS_LAST); |
379 | - |
380 | - class = job->class; |
381 | - |
382 | - nih_assert (class != NULL); |
383 | - |
384 | - /* Create a pipe to communicate with the child process until it |
385 | - * execs so we know whether that was successful or an error occurred. |
386 | - */ |
387 | - if (pipe (fds) < 0) |
388 | - nih_return_system_error (-1); |
389 | - |
390 | - if (class->console == CONSOLE_LOG && disable_job_logging) |
391 | - class->console = CONSOLE_NONE; |
392 | - |
393 | - if (class->console == CONSOLE_LOG) { |
394 | - NihError *err; |
395 | - |
396 | - /* Ensure log destroyed for previous matching job process |
397 | - * (occurs when job restarted but previous process has not |
398 | - * yet been reaped). |
399 | - */ |
400 | - if (job->log[process]) { |
401 | - nih_free (job->log[process]); |
402 | - job->log[process] = NULL; |
403 | - } |
404 | - |
405 | - log_path = job_process_log_path (job, 0); |
406 | - |
407 | - if (! log_path) { |
408 | - /* Consume and re-raise */ |
409 | - err = nih_error_get (); |
410 | - nih_assert (err->number == ENOMEM); |
411 | - nih_free (err); |
412 | - close (fds[0]); |
413 | - close (fds[1]); |
414 | - nih_return_no_memory_error(-1); |
415 | - } |
416 | - |
417 | - pty_master = posix_openpt (O_RDWR | O_NOCTTY); |
418 | - |
419 | - if (pty_master < 0) { |
420 | - nih_error (_("Failed to create pty - disabling logging for job")); |
421 | - |
422 | - /* Ensure that the job can still be started by |
423 | - * disabling logging. |
424 | - */ |
425 | - class->console = CONSOLE_NONE; |
426 | - |
427 | - close (fds[0]); |
428 | - close (fds[1]); |
429 | - nih_return_system_error (-1); |
430 | - } |
431 | - |
432 | - /* Stop any process created _before_ the log object below is |
433 | - * freed from inheriting this fd. |
434 | - */ |
435 | - nih_io_set_cloexec (pty_master); |
436 | - |
437 | - /* pty_master will be closed by log_destroy() */ |
438 | - job->log[process] = log_new (job->log, log_path, pty_master, 0); |
439 | - if (! job->log[process]) { |
440 | - close (pty_master); |
441 | - close (fds[0]); |
442 | - close (fds[1]); |
443 | - nih_return_system_error (-1); |
444 | - } |
445 | - } |
446 | - |
447 | - /* Block all signals while we fork to avoid the child process running |
448 | - * our own signal handlers before we've reset them all back to the |
449 | - * default. |
450 | - */ |
451 | - sigfillset (&child_set); |
452 | - sigprocmask (SIG_BLOCK, &child_set, &orig_set); |
453 | - |
454 | - /* Ensure that any lingering data in stdio buffers is flushed |
455 | - * to avoid the child getting a copy of it. |
456 | - * If not done, CONSOLE_LOG jobs may end up with unexpected data |
457 | - * in their logs if we run with for example '--debug'. |
458 | - */ |
459 | - fflush (NULL); |
460 | - |
461 | - /* Fork the child process, handling success and failure by resetting |
462 | - * the signal mask and returning the new process id or a raised error. |
463 | - */ |
464 | - pid = fork (); |
465 | - if (pid > 0) { |
466 | - if (class->debug) { |
467 | - nih_info (_("Pausing %s (%d) [pre-exec] for debug"), |
468 | - class->name, pid); |
469 | - } |
470 | - |
471 | - sigprocmask (SIG_SETMASK, &orig_set, NULL); |
472 | - close (fds[1]); |
473 | - |
474 | - /* Read error from the pipe, return if one is raised */ |
475 | - if (job_process_error_read (fds[0]) < 0) { |
476 | - if (class->console == CONSOLE_LOG) { |
477 | - /* Ensure the pty_master watch gets |
478 | - * removed and the fd closed. |
479 | - */ |
480 | - nih_free (job->log[process]); |
481 | - job->log[process] = NULL; |
482 | - } |
483 | - close (fds[0]); |
484 | - return -1; |
485 | - } |
486 | - |
487 | - /* Note that pts_master is closed automatically in the parent when the |
488 | - * log object is destroyed. |
489 | - */ |
490 | - close (fds[0]); |
491 | - return pid; |
492 | - } else if (pid < 0) { |
493 | - nih_error_raise_system (); |
494 | - |
495 | - sigprocmask (SIG_SETMASK, &orig_set, NULL); |
496 | - close (fds[0]); |
497 | - close (fds[1]); |
498 | - if (class->console == CONSOLE_LOG) { |
499 | - nih_free (job->log[process]); |
500 | - job->log[process] = NULL; |
501 | - } |
502 | - return -1; |
503 | - } |
504 | - |
505 | - /* We're now in the child process. |
506 | - * |
507 | - * The rest of this function sets the child up and ends by executing |
508 | - * the new binary. Failures are handled by terminating the child |
509 | - * and writing an error back to the parent. |
510 | - */ |
511 | - |
512 | - /* Close the reading end of the pipe with our parent and mark the |
513 | - * writing end to be closed-on-exec so the parent knows we got that |
514 | - * far because read() returned zero. |
515 | - */ |
516 | - close (fds[0]); |
517 | - |
518 | - job_process_remap_fd (&fds[1], JOB_PROCESS_SCRIPT_FD, fds[1]); |
519 | - nih_io_set_cloexec (fds[1]); |
520 | - |
521 | - if (class->console == CONSOLE_LOG) { |
522 | - struct sigaction act; |
523 | - struct sigaction ignore; |
524 | - |
525 | - job_process_remap_fd (&pty_master, JOB_PROCESS_SCRIPT_FD, fds[1]); |
526 | - |
527 | - /* Child is the slave, so won't need this */ |
528 | - nih_io_set_cloexec (pty_master); |
529 | - |
530 | - /* Temporarily disable child handler as grantpt(3) disallows one |
531 | - * being in effect when called. |
532 | - */ |
533 | - ignore.sa_handler = SIG_DFL; |
534 | - ignore.sa_flags = 0; |
535 | - sigemptyset (&ignore.sa_mask); |
536 | - |
537 | - if (sigaction (SIGCHLD, &ignore, &act) < 0) { |
538 | - nih_error_raise_system (); |
539 | - job_process_error_abort (fds[1], JOB_PROCESS_ERROR_SIGNAL, 0); |
540 | - } |
541 | - |
542 | - if (grantpt (pty_master) < 0) { |
543 | - nih_error_raise_system (); |
544 | - job_process_error_abort (fds[1], JOB_PROCESS_ERROR_GRANTPT, 0); |
545 | - } |
546 | - |
547 | - /* Restore child handler */ |
548 | - if (sigaction (SIGCHLD, &act, NULL) < 0) { |
549 | - nih_error_raise_system (); |
550 | - job_process_error_abort (fds[1], JOB_PROCESS_ERROR_SIGNAL, 0); |
551 | - } |
552 | - |
553 | - if (unlockpt (pty_master) < 0) { |
554 | - nih_error_raise_system (); |
555 | - job_process_error_abort (fds[1], JOB_PROCESS_ERROR_UNLOCKPT, 0); |
556 | - } |
557 | - |
558 | - if (ptsname_r (pty_master, pts_name, sizeof(pts_name)) < 0) { |
559 | - nih_error_raise_system (); |
560 | - job_process_error_abort (fds[1], JOB_PROCESS_ERROR_PTSNAME, 0); |
561 | - } |
562 | - |
563 | - pty_slave = open (pts_name, O_RDWR | O_NOCTTY); |
564 | - |
565 | - if (pty_slave < 0) { |
566 | - nih_error_raise_system (); |
567 | - job_process_error_abort (fds[1], JOB_PROCESS_ERROR_OPENPT_SLAVE, 0); |
568 | - } |
569 | - |
570 | - job_process_remap_fd (&pty_slave, JOB_PROCESS_SCRIPT_FD, fds[1]); |
571 | - } |
572 | - |
573 | - /* Move the script fd to special fd 9; the only gotcha is if that |
574 | - * would be our error descriptor, but that's handled above. |
575 | - */ |
576 | - if ((script_fd != -1) && (script_fd != JOB_PROCESS_SCRIPT_FD)) { |
577 | - int tmp = dup2 (script_fd, JOB_PROCESS_SCRIPT_FD); |
578 | - if (tmp < 0) { |
579 | - nih_error_raise_system (); |
580 | - job_process_error_abort (fds[1], JOB_PROCESS_ERROR_DUP, 0); |
581 | - } |
582 | - close (script_fd); |
583 | - script_fd = tmp; |
584 | - } |
585 | - |
586 | - /* Become the leader of a new session and process group, shedding |
587 | - * any controlling tty (which we shouldn't have had anyway). |
588 | - */ |
589 | - setsid (); |
590 | - |
591 | - /* Set the process environment from the function parameters. */ |
592 | - environ = (char **)env; |
593 | - |
594 | - /* Set the standard file descriptors to an output of our chosing; |
595 | - * any other open descriptor must be intended for the child, or have |
596 | - * the FD_CLOEXEC flag so it's automatically closed when we exec() |
597 | - * later. |
598 | - */ |
599 | - if (system_setup_console (class->console, FALSE) < 0) { |
600 | - if (class->console == CONSOLE_OUTPUT) { |
601 | - NihError *err; |
602 | - |
603 | - err = nih_error_get (); |
604 | - nih_warn (_("Failed to open system console: %s"), |
605 | - err->message); |
606 | - nih_free (err); |
607 | - |
608 | - if (system_setup_console (CONSOLE_NONE, FALSE) < 0) |
609 | - job_process_error_abort (fds[1], JOB_PROCESS_ERROR_CONSOLE, 0); |
610 | - } else |
611 | - job_process_error_abort (fds[1], JOB_PROCESS_ERROR_CONSOLE, 0); |
612 | - } |
613 | - |
614 | - if (class->console == CONSOLE_LOG) { |
615 | - /* Redirect stdout and stderr to the logger fd */ |
616 | - if (dup2 (pty_slave, STDOUT_FILENO) < 0) { |
617 | - nih_error_raise_system (); |
618 | - job_process_error_abort (fds[1], JOB_PROCESS_ERROR_DUP, 0); |
619 | - } |
620 | - |
621 | - if (dup2 (pty_slave, STDERR_FILENO) < 0) { |
622 | - nih_error_raise_system (); |
623 | - job_process_error_abort (fds[1], JOB_PROCESS_ERROR_DUP, 0); |
624 | - } |
625 | - |
626 | - close (pty_slave); |
627 | - } |
628 | - |
629 | - /* Switch to the specified AppArmor profile, but only for the main |
630 | - process, so we don't confine the pre- and post- processes. |
631 | - */ |
632 | - if ((class->apparmor_switch) && (process == PROCESS_MAIN)) { |
633 | - nih_local char *profile = NULL; |
634 | - |
635 | - /* Use the environment to expand the AppArmor profile name |
636 | - */ |
637 | - profile = NIH_SHOULD (environ_expand (NULL, |
638 | - class->apparmor_switch, |
639 | - environ)); |
640 | - |
641 | - if (! profile) { |
642 | - job_process_error_abort (fds[1], JOB_PROCESS_ERROR_SECURITY, 0); |
643 | - } |
644 | - |
645 | - if (apparmor_switch (profile) < 0) { |
646 | - nih_error_raise_system (); |
647 | - job_process_error_abort (fds[1], JOB_PROCESS_ERROR_SECURITY, 0); |
648 | - } |
649 | - } |
650 | - |
651 | - if (process != PROCESS_SECURITY) { |
652 | - /* Set resource limits for the process, skipping over any that |
653 | - * aren't set in the job class such that they inherit from |
654 | - * ourselves (and we inherit from kernel defaults). |
655 | - */ |
656 | - for (i = 0; i < RLIMIT_NLIMITS; i++) { |
657 | - if (! class->limits[i]) |
658 | - continue; |
659 | - |
660 | - if (setrlimit (i, class->limits[i]) < 0) { |
661 | - nih_error_raise_system (); |
662 | - job_process_error_abort (fds[1], |
663 | - JOB_PROCESS_ERROR_RLIMIT, i); |
664 | - } |
665 | - } |
666 | - |
667 | - /* Set the file mode creation mask; this is one of the few operations |
668 | - * that can never fail. |
669 | - */ |
670 | - umask (class->umask); |
671 | - |
672 | - /* Adjust the process priority ("nice level"). |
673 | - */ |
674 | - if (class->nice != JOB_NICE_INVALID && |
675 | - setpriority (PRIO_PROCESS, 0, class->nice) < 0) { |
676 | - nih_error_raise_system (); |
677 | - job_process_error_abort (fds[1], |
678 | - JOB_PROCESS_ERROR_PRIORITY, 0); |
679 | - } |
680 | - |
681 | - /* Adjust the process OOM killer priority. |
682 | - */ |
683 | - if (class->oom_score_adj != JOB_DEFAULT_OOM_SCORE_ADJ) { |
684 | - int oom_value; |
685 | - snprintf (filename, sizeof (filename), |
686 | - "/proc/%d/oom_score_adj", getpid ()); |
687 | - oom_value = class->oom_score_adj; |
688 | - fd = fopen (filename, "w"); |
689 | - if ((! fd) && (errno == ENOENT)) { |
690 | - snprintf (filename, sizeof (filename), |
691 | - "/proc/%d/oom_adj", getpid ()); |
692 | - oom_value = (class->oom_score_adj |
693 | - * ((class->oom_score_adj < 0) ? 17 : 15)) / 1000; |
694 | - fd = fopen (filename, "w"); |
695 | - } |
696 | - if (! fd) { |
697 | - nih_error_raise_system (); |
698 | - job_process_error_abort (fds[1], JOB_PROCESS_ERROR_OOM_ADJ, 0); |
699 | - } else { |
700 | - fprintf (fd, "%d\n", oom_value); |
701 | - |
702 | - if (fclose (fd)) { |
703 | - nih_error_raise_system (); |
704 | - job_process_error_abort (fds[1], JOB_PROCESS_ERROR_OOM_ADJ, 0); |
705 | - } |
706 | - } |
707 | - } |
708 | - |
709 | - /* Handle changing a chroot session job prior to dealing with |
710 | - * the 'chroot' stanza. |
711 | - */ |
712 | - if (class->session && class->session->chroot) { |
713 | - if (chroot (class->session->chroot) < 0) { |
714 | - nih_error_raise_system (); |
715 | - job_process_error_abort (fds[1], JOB_PROCESS_ERROR_CHROOT, 0); |
716 | - } |
717 | - } |
718 | - |
719 | - /* Change the root directory, confining path resolution within it; |
720 | - * we do this before the working directory call so that is always |
721 | - * relative to the new root. |
722 | - */ |
723 | - if (class->chroot) { |
724 | - if (chroot (class->chroot) < 0) { |
725 | - nih_error_raise_system (); |
726 | - job_process_error_abort (fds[1], |
727 | - JOB_PROCESS_ERROR_CHROOT, 0); |
728 | - } |
729 | - } |
730 | - |
731 | - /* Change the working directory of the process, either to the one |
732 | - * configured in the job, or to the root directory of the filesystem |
733 | - * (or at least relative to the chroot). |
734 | - */ |
735 | - if (class->chdir || user_mode == FALSE) { |
736 | - if (chdir (class->chdir ? class->chdir : "/") < 0) { |
737 | - nih_error_raise_system (); |
738 | - job_process_error_abort (fds[1], JOB_PROCESS_ERROR_CHDIR, 0); |
739 | - } |
740 | - } |
741 | - |
742 | - /* Change the user and group of the process to the one |
743 | - * configured in the job. We must wait until now to lookup the |
744 | - * UID and GID from the names to accommodate both chroot |
745 | - * session jobs and jobs with a chroot stanza. |
746 | - */ |
747 | - if (class->setuid) { |
748 | - /* Without resetting errno, it's impossible to |
749 | - * distinguish between a non-existent user and and |
750 | - * error during lookup */ |
751 | - errno = 0; |
752 | - pwd = getpwnam (class->setuid); |
753 | - if (! pwd) { |
754 | - if (errno != 0) { |
755 | - nih_error_raise_system (); |
756 | - job_process_error_abort (fds[1], JOB_PROCESS_ERROR_GETPWNAM, 0); |
757 | - } else { |
758 | - nih_error_raise (JOB_PROCESS_INVALID_SETUID, |
759 | - JOB_PROCESS_INVALID_SETUID_STR); |
760 | - job_process_error_abort (fds[1], JOB_PROCESS_ERROR_BAD_SETUID, 0); |
761 | - } |
762 | - } |
763 | - |
764 | - job_setuid = pwd->pw_uid; |
765 | - /* This will be overridden if setgid is also set: */ |
766 | - job_setgid = pwd->pw_gid; |
767 | - } |
768 | - |
769 | - if (class->setgid) { |
770 | - errno = 0; |
771 | - grp = getgrnam (class->setgid); |
772 | - if (! grp) { |
773 | - if (errno != 0) { |
774 | - nih_error_raise_system (); |
775 | - job_process_error_abort (fds[1], JOB_PROCESS_ERROR_GETGRNAM, 0); |
776 | - } else { |
777 | - nih_error_raise (JOB_PROCESS_INVALID_SETGID, |
778 | - JOB_PROCESS_INVALID_SETGID_STR); |
779 | - job_process_error_abort (fds[1], JOB_PROCESS_ERROR_BAD_SETGID, 0); |
780 | - } |
781 | - } |
782 | - |
783 | - job_setgid = grp->gr_gid; |
784 | - } |
785 | - |
786 | - if (script_fd != -1 && |
787 | - (job_setuid != (uid_t) -1 || job_setgid != (gid_t) -1) && |
788 | - fchown (script_fd, job_setuid, job_setgid) < 0) { |
789 | - nih_error_raise_system (); |
790 | - job_process_error_abort (fds[1], JOB_PROCESS_ERROR_CHOWN, 0); |
791 | - } |
792 | - |
793 | - /* Make sure we always have the needed pwd and grp structs. |
794 | - * Then pass those to initgroups() to setup the user's group list. |
795 | - * Only do that if we're root as initgroups() won't work when non-root. */ |
796 | - if (geteuid () == 0) { |
797 | - if (! pwd) { |
798 | - pwd = getpwuid (geteuid ()); |
799 | - if (! pwd) { |
800 | - nih_error_raise_system (); |
801 | - job_process_error_abort (fds[1], JOB_PROCESS_ERROR_GETPWUID, 0); |
802 | - } |
803 | - } |
804 | - |
805 | - if (! grp) { |
806 | - grp = getgrgid (getegid ()); |
807 | - if (! grp) { |
808 | - nih_error_raise_system (); |
809 | - job_process_error_abort (fds[1], JOB_PROCESS_ERROR_GETGRGID, 0); |
810 | - } |
811 | - } |
812 | - |
813 | - if (pwd && grp) { |
814 | - if (initgroups (pwd->pw_name, grp->gr_gid) < 0) { |
815 | - nih_error_raise_system (); |
816 | - job_process_error_abort (fds[1], JOB_PROCESS_ERROR_INITGROUPS, 0); |
817 | - } |
818 | - } |
819 | - } |
820 | - |
821 | - /* Start dropping privileges */ |
822 | - if (job_setgid != (gid_t) -1 && setgid (job_setgid) < 0) { |
823 | - nih_error_raise_system (); |
824 | - job_process_error_abort (fds[1], JOB_PROCESS_ERROR_SETGID, 0); |
825 | - } |
826 | - |
827 | - if (job_setuid != (uid_t)-1 && setuid (job_setuid) < 0) { |
828 | - nih_error_raise_system (); |
829 | - job_process_error_abort (fds[1], JOB_PROCESS_ERROR_SETUID, 0); |
830 | - } |
831 | - } |
832 | - |
833 | - /* Reset all the signal handlers back to their default handling so |
834 | - * the child isn't unexpectedly ignoring any, and so we won't |
835 | - * surprisingly handle them before we've exec()d the new process. |
836 | - */ |
837 | - nih_signal_reset (); |
838 | - sigprocmask (SIG_SETMASK, &orig_set, NULL); |
839 | - |
840 | - /* Notes: |
841 | - * |
842 | - * - we can't use pause() here since there would then be no way to |
843 | - * resume the process without killing it. |
844 | - * |
845 | - * - we have to close the pipe back to the parent since if we don't, |
846 | - * the parent hangs until the STOP is cleared. Although this may be |
847 | - * acceptable for normal operation, this causes the test suite to |
848 | - * fail. Note that closing the pipe means from this point onwards, |
849 | - * the parent cannot know the true outcome of the spawn: that |
850 | - * responsibility lies with the debugger. |
851 | - * |
852 | - * - note that running with the debug stanza enabled will |
853 | - * unavoidably stop stateful re-exec from working correctly |
854 | - * since the stopped debug child process will hold copies of |
855 | - * the parents file descriptors open until it continues to |
856 | - * call exec below. |
857 | - */ |
858 | - if (class->debug) { |
859 | - close (fds[1]); |
860 | - raise (SIGSTOP); |
861 | - } |
862 | - |
863 | - /* Set up a process trace if we need to trace forks */ |
864 | - if (trace) { |
865 | - if (ptrace (PTRACE_TRACEME, 0, NULL, 0) < 0) { |
866 | - nih_error_raise_system(); |
867 | - job_process_error_abort (fds[1], |
868 | - JOB_PROCESS_ERROR_PTRACE, 0); |
869 | - } |
870 | - } |
871 | - |
872 | - /* Execute the process, if we escape from here it failed */ |
873 | - if (execvp (argv[0], argv) < 0) { |
874 | - nih_error_raise_system (); |
875 | - job_process_error_abort (fds[1], JOB_PROCESS_ERROR_EXEC, 0); |
876 | - } |
877 | - |
878 | - nih_assert_not_reached (); |
879 | -} |
880 | - |
881 | |
882 | /** |
883 | * job_process_start: |
884 | @@ -1761,45 +963,6 @@ |
885 | exit (255); |
886 | } |
887 | |
888 | -/** |
889 | - * job_process_error_read: |
890 | - * @fd: reading end of pipe. |
891 | - * |
892 | - * Read from the reading end of the pipe specified by @fd, if we receive |
893 | - * data then the child raised a process error which we reconstruct and raise |
894 | - * again; otherwise no problem was found and no action is taken. |
895 | - * |
896 | - * The reconstructed error will be of JOB_PROCESS_ERROR type, the human- |
897 | - * readable message is generated according to the type of process error |
898 | - * and argument passed along with it. |
899 | - * |
900 | - * Returns: zero if no error was found, or negative value on raised error. |
901 | - **/ |
902 | -static int |
903 | -job_process_error_read (int fd) |
904 | -{ |
905 | - JobProcessWireError wire_err; |
906 | - ssize_t len; |
907 | - |
908 | - /* Read the error from the pipe; a zero read indicates that the |
909 | - * exec succeeded so we return success, otherwise if we don't receive |
910 | - * a JobProcessWireError structure, we return a temporary error so we |
911 | - * try again. |
912 | - */ |
913 | - len = read (fd, &wire_err, sizeof (wire_err)); |
914 | - if (len == 0) { |
915 | - return 0; |
916 | - } else if (len < 0) { |
917 | - nih_return_system_error (-1); |
918 | - } else if (len != sizeof (wire_err)) { |
919 | - errno = EILSEQ; |
920 | - nih_return_system_error (-1); |
921 | - } |
922 | - |
923 | - job_process_error_handler ((char *)(&wire_err), len); |
924 | - return -1; |
925 | -} |
926 | - |
927 | |
928 | /** |
929 | * job_process_error_handler: |
930 | |
931 | === modified file 'init/job_process.h' |
932 | --- init/job_process.h 2014-05-15 09:43:13 +0000 |
933 | +++ init/job_process.h 2014-05-21 22:39:37 +0000 |
934 | @@ -138,11 +138,7 @@ |
935 | |
936 | NIH_BEGIN_EXTERN |
937 | |
938 | -int job_process_run (Job *job, ProcessType process); |
939 | -void |
940 | -job_process_start (Job *job, |
941 | - ProcessType process); |
942 | - |
943 | +void job_process_start (Job *job, ProcessType process); |
944 | void job_process_run_bottom (JobProcessData *handler_data); |
945 | |
946 | void job_process_child_reader (JobProcessData *handler_data, NihIo *io, |
947 | |
948 | === modified file 'init/tests/test_event.c' |
949 | --- init/tests/test_event.c 2014-05-19 16:52:28 +0000 |
950 | +++ init/tests/test_event.c 2014-05-21 22:39:37 +0000 |
951 | @@ -1730,8 +1730,10 @@ |
952 | nih_hash_add (job_classes, &class->entry); |
953 | } |
954 | |
955 | - event_poll (); |
956 | - |
957 | + //FIXME must run without TEST_ALLOC_SAFE |
958 | + TEST_ALLOC_SAFE { |
959 | + event_poll (); |
960 | + } |
961 | TEST_FREE (event); |
962 | |
963 | TEST_HASH_NOT_EMPTY (class->instances); |
964 | |
965 | === modified file 'init/tests/test_job.c' |
966 | --- init/tests/test_job.c 2014-05-20 21:14:25 +0000 |
967 | +++ init/tests/test_job.c 2014-05-21 22:39:37 +0000 |
968 | @@ -60,6 +60,7 @@ |
969 | #include "conf.h" |
970 | #include "control.h" |
971 | #include "state.h" |
972 | +#include "test_util_common.h" |
973 | |
974 | void |
975 | job_quit_with_state (void *data, NihMainLoopFunc *loop) |
976 | @@ -69,12 +70,6 @@ |
977 | nih_main_loop_exit (job->state); |
978 | } |
979 | |
980 | -void |
981 | -timeout_quit_zero (void *data, NihTimerCb *timer) |
982 | -{ |
983 | - nih_main_loop_exit (0); |
984 | -} |
985 | - |
986 | char *argv0; |
987 | |
988 | static int state_fd = -1; |
989 | @@ -1234,8 +1229,7 @@ |
990 | TEST_EQ (job->goal, JOB_STOP); |
991 | TEST_EQ (job->state, JOB_STOPPING); |
992 | TEST_FALSE (job->process_data[PROCESS_PRE_START]->valid); |
993 | - // FIXME shouldn't it be zero at this point? |
994 | - TEST_NE (job->pid[PROCESS_PRE_START], 0); |
995 | + TEST_EQ (job->pid[PROCESS_PRE_START], 0); |
996 | |
997 | TEST_EQ (cause->blockers, 0); |
998 | TEST_EQ (cause->failed, TRUE); |
999 | @@ -1616,8 +1610,7 @@ |
1000 | TEST_EQ (job->goal, JOB_STOP); |
1001 | TEST_EQ (job->state, JOB_STOPPING); |
1002 | TEST_FALSE (job->process_data[PROCESS_MAIN]->valid); |
1003 | - // FIXME shouldn't it be zero at this point? |
1004 | - TEST_NE (job->pid[PROCESS_MAIN], 0); |
1005 | + TEST_EQ (job->pid[PROCESS_MAIN], 0); |
1006 | |
1007 | TEST_EQ (cause->blockers, 0); |
1008 | TEST_EQ (cause->failed, TRUE); |
1009 | @@ -3246,10 +3239,7 @@ |
1010 | TEST_FEATURE ("killed to post-stop for failed process"); |
1011 | tmp = class->process[PROCESS_POST_STOP]; |
1012 | class->process[PROCESS_POST_STOP] = fail; |
1013 | - NihTimer * timer; |
1014 | |
1015 | - /* FIXME this is very slow, as we wait 1s per TEST_ALLOC_FAIL itteration... */ |
1016 | - nih_message (" Running. Respect the timer."); |
1017 | TEST_ALLOC_FAIL { |
1018 | TEST_ALLOC_SAFE { |
1019 | job = job_new (class, ""); |
1020 | @@ -3257,7 +3247,6 @@ |
1021 | blocked = blocked_new (job, BLOCKED_EVENT, cause); |
1022 | event_block (cause); |
1023 | nih_list_add (&job->blocking, &blocked->entry); |
1024 | - timer = nih_timer_add_timeout (NULL, 1, (NihTimerCb)timeout_quit_zero, NULL); |
1025 | } |
1026 | |
1027 | job->goal = JOB_START; |
1028 | @@ -3274,16 +3263,12 @@ |
1029 | |
1030 | TEST_FREE_TAG (job); |
1031 | |
1032 | - TEST_FREE_TAG (timer); |
1033 | - |
1034 | TEST_DIVERT_STDERR (output) { |
1035 | job_change_state (job, JOB_POST_STOPPING); |
1036 | - nih_main_loop (); |
1037 | + TEST_WATCH_LOOP (); |
1038 | } |
1039 | rewind (output); |
1040 | |
1041 | - TEST_FREE (timer); |
1042 | - |
1043 | TEST_FREE (job); |
1044 | |
1045 | TEST_EQ (cause->blockers, 0); |
1046 | |
1047 | === modified file 'init/tests/test_job_process.c' |
1048 | --- init/tests/test_job_process.c 2014-05-19 17:21:16 +0000 |
1049 | +++ init/tests/test_job_process.c 2014-05-21 22:39:37 +0000 |
1050 | @@ -385,7 +385,7 @@ |
1051 | * (Such tests are handled in the bundled test_user_sessions.sh script). |
1052 | */ |
1053 | void |
1054 | -test_run (void) |
1055 | +test_start (void) |
1056 | { |
1057 | char dirname[PATH_MAX]; |
1058 | JobClass *class = NULL; |
1059 | @@ -394,7 +394,7 @@ |
1060 | struct stat statbuf; |
1061 | char filename[PATH_MAX], buf[80]; |
1062 | char function[PATH_MAX]; |
1063 | - int ret = -1, status, first; |
1064 | + int status; |
1065 | siginfo_t info; |
1066 | char filebuf[1024]; |
1067 | struct passwd *pwd; |
1068 | @@ -409,7 +409,7 @@ |
1069 | log_unflushed_init (); |
1070 | job_class_init (); |
1071 | |
1072 | - TEST_FUNCTION ("job_process_run"); |
1073 | + TEST_FUNCTION ("job_process_start"); |
1074 | |
1075 | TEST_FILENAME (filename); |
1076 | program_name = "test"; |
1077 | @@ -443,8 +443,7 @@ |
1078 | job->state = JOB_SPAWNED; |
1079 | } |
1080 | |
1081 | - ret = job_process_run (job, PROCESS_MAIN); |
1082 | - TEST_EQ (ret, 0); |
1083 | + job_process_start (job, PROCESS_MAIN); |
1084 | |
1085 | TEST_NE (job->pid[PROCESS_MAIN], 0); |
1086 | |
1087 | @@ -478,8 +477,7 @@ |
1088 | job->state = JOB_SPAWNED; |
1089 | } |
1090 | |
1091 | - ret = job_process_run (job, PROCESS_MAIN); |
1092 | - TEST_EQ (ret, 0); |
1093 | + job_process_start (job, PROCESS_MAIN); |
1094 | |
1095 | TEST_NE (job->pid[PROCESS_MAIN], 0); |
1096 | |
1097 | @@ -520,8 +518,7 @@ |
1098 | job->state = JOB_SPAWNED; |
1099 | } |
1100 | |
1101 | - ret = job_process_run (job, PROCESS_MAIN); |
1102 | - TEST_EQ (ret, 0); |
1103 | + job_process_start (job, PROCESS_MAIN); |
1104 | |
1105 | TEST_NE (job->pid[PROCESS_MAIN], 0); |
1106 | |
1107 | @@ -560,8 +557,7 @@ |
1108 | job->state = JOB_SPAWNED; |
1109 | } |
1110 | |
1111 | - ret = job_process_run (job, PROCESS_MAIN); |
1112 | - TEST_EQ (ret, 0); |
1113 | + job_process_start (job, PROCESS_MAIN); |
1114 | |
1115 | TEST_NE (job->pid[PROCESS_MAIN], 0); |
1116 | |
1117 | @@ -601,8 +597,7 @@ |
1118 | job->state = JOB_SPAWNED; |
1119 | } |
1120 | |
1121 | - ret = job_process_run (job, PROCESS_MAIN); |
1122 | - TEST_EQ (ret, 0); |
1123 | + job_process_start (job, PROCESS_MAIN); |
1124 | |
1125 | TEST_NE (job->pid[PROCESS_MAIN], 0); |
1126 | |
1127 | @@ -648,8 +643,7 @@ |
1128 | "CRACKLE=FIZZ")); |
1129 | } |
1130 | |
1131 | - ret = job_process_run (job, PROCESS_MAIN); |
1132 | - TEST_EQ (ret, 0); |
1133 | + job_process_start (job, PROCESS_MAIN); |
1134 | |
1135 | TEST_NE (job->pid[PROCESS_MAIN], 0); |
1136 | |
1137 | @@ -704,8 +698,7 @@ |
1138 | "CRACKLE=FIZZ")); |
1139 | } |
1140 | |
1141 | - ret = job_process_run (job, PROCESS_MAIN); |
1142 | - TEST_EQ (ret, 0); |
1143 | + job_process_start (job, PROCESS_MAIN); |
1144 | |
1145 | TEST_NE (job->pid[PROCESS_MAIN], 0); |
1146 | |
1147 | @@ -761,8 +754,7 @@ |
1148 | "CRACKLE=FIZZ")); |
1149 | } |
1150 | |
1151 | - ret = job_process_run (job, PROCESS_PRE_STOP); |
1152 | - TEST_EQ (ret, 0); |
1153 | + job_process_start (job, PROCESS_PRE_STOP); |
1154 | |
1155 | TEST_NE (job->pid[PROCESS_PRE_STOP], 0); |
1156 | |
1157 | @@ -819,8 +811,7 @@ |
1158 | "CRACKLE=FIZZ")); |
1159 | } |
1160 | |
1161 | - ret = job_process_run (job, PROCESS_POST_STOP); |
1162 | - TEST_EQ (ret, 0); |
1163 | + job_process_start (job, PROCESS_POST_STOP); |
1164 | |
1165 | TEST_NE (job->pid[PROCESS_POST_STOP], 0); |
1166 | |
1167 | @@ -870,36 +861,11 @@ |
1168 | job->state = JOB_SPAWNED; |
1169 | } |
1170 | |
1171 | - ret = job_process_run (job, PROCESS_MAIN); |
1172 | - TEST_EQ (ret, 0); |
1173 | + job_process_start (job, PROCESS_MAIN); |
1174 | |
1175 | TEST_NE (job->pid[PROCESS_MAIN], 0); |
1176 | |
1177 | - /* Loop until we've fed all of the data. */ |
1178 | - first = TRUE; |
1179 | - for (;;) { |
1180 | - fd_set readfds, writefds, exceptfds; |
1181 | - int nfds; |
1182 | - |
1183 | - nfds = 0; |
1184 | - FD_ZERO (&readfds); |
1185 | - FD_ZERO (&writefds); |
1186 | - FD_ZERO (&exceptfds); |
1187 | - |
1188 | - nih_io_select_fds (&nfds, &readfds, |
1189 | - &writefds, &exceptfds); |
1190 | - if (! nfds) { |
1191 | - if (first) |
1192 | - TEST_FAILED ("expected to have " |
1193 | - "data to feed."); |
1194 | - break; |
1195 | - } |
1196 | - first = FALSE; |
1197 | - |
1198 | - select (nfds, &readfds, &writefds, &exceptfds, NULL); |
1199 | - |
1200 | - nih_io_handle_fds (&readfds, &writefds, &exceptfds); |
1201 | - } |
1202 | + TEST_WATCH_LOOP (); |
1203 | |
1204 | waitpid (job->pid[PROCESS_MAIN], &status, 0); |
1205 | TEST_TRUE (WIFEXITED (status)); |
1206 | @@ -938,8 +904,7 @@ |
1207 | job->trace_state = TRACE_NORMAL; |
1208 | } |
1209 | |
1210 | - ret = job_process_run (job, PROCESS_MAIN); |
1211 | - TEST_EQ (ret, 0); |
1212 | + job_process_start (job, PROCESS_MAIN); |
1213 | |
1214 | TEST_EQ (job->trace_forks, 0); |
1215 | TEST_EQ (job->trace_state, TRACE_NONE); |
1216 | @@ -978,8 +943,7 @@ |
1217 | job->trace_state = TRACE_NORMAL; |
1218 | } |
1219 | |
1220 | - ret = job_process_run (job, PROCESS_PRE_START); |
1221 | - TEST_EQ (ret, 0); |
1222 | + job_process_start (job, PROCESS_PRE_START); |
1223 | |
1224 | TEST_EQ (job->trace_forks, 0); |
1225 | TEST_EQ (job->trace_state, TRACE_NONE); |
1226 | @@ -1020,8 +984,7 @@ |
1227 | job->trace_state = TRACE_NORMAL; |
1228 | } |
1229 | |
1230 | - ret = job_process_run (job, PROCESS_MAIN); |
1231 | - TEST_EQ (ret, 0); |
1232 | + job_process_start (job, PROCESS_MAIN); |
1233 | |
1234 | TEST_EQ (job->trace_forks, 0); |
1235 | TEST_EQ (job->trace_state, TRACE_NEW); |
1236 | @@ -1071,8 +1034,7 @@ |
1237 | job->trace_state = TRACE_NORMAL; |
1238 | } |
1239 | |
1240 | - ret = job_process_run (job, PROCESS_MAIN); |
1241 | - TEST_EQ (ret, 0); |
1242 | + job_process_start (job, PROCESS_MAIN); |
1243 | |
1244 | TEST_EQ (job->trace_forks, 0); |
1245 | TEST_EQ (job->trace_state, TRACE_NEW); |
1246 | @@ -1098,7 +1060,7 @@ |
1247 | } |
1248 | |
1249 | /* Check that if we try and run a command that doesn't exist, |
1250 | - * job_process_run() raises a ProcessError and the command doesn't |
1251 | + * job_process_start() raises a ProcessError and the command doesn't |
1252 | * have any stored process id for it. |
1253 | */ |
1254 | TEST_FEATURE ("with no such file"); |
1255 | @@ -1120,11 +1082,12 @@ |
1256 | } |
1257 | |
1258 | TEST_DIVERT_STDERR (output) { |
1259 | - ret = job_process_run (job, PROCESS_MAIN); |
1260 | + job_process_start (job, PROCESS_MAIN); |
1261 | + TEST_WATCH_LOOP (); |
1262 | + event_poll (); |
1263 | } |
1264 | rewind (output); |
1265 | - TEST_LT (ret, 0); |
1266 | - |
1267 | + |
1268 | TEST_EQ (job->pid[PROCESS_MAIN], 0); |
1269 | |
1270 | TEST_FILE_EQ (output, ("test: Failed to spawn test (foo) main " |
1271 | @@ -1171,8 +1134,7 @@ |
1272 | job->goal = JOB_START; |
1273 | job->state = JOB_SPAWNED; |
1274 | |
1275 | - ret = job_process_run (job, PROCESS_MAIN); |
1276 | - TEST_EQ (ret, 0); |
1277 | + job_process_start (job, PROCESS_MAIN); |
1278 | |
1279 | TEST_NE (job->pid[PROCESS_MAIN], 0); |
1280 | |
1281 | @@ -1239,8 +1201,7 @@ |
1282 | job->goal = JOB_START; |
1283 | job->state = JOB_SPAWNED; |
1284 | |
1285 | - ret = job_process_run (job, PROCESS_MAIN); |
1286 | - TEST_EQ (ret, 0); |
1287 | + job_process_start (job, PROCESS_MAIN); |
1288 | |
1289 | TEST_NE (job->pid[PROCESS_MAIN], 0); |
1290 | |
1291 | @@ -1307,8 +1268,7 @@ |
1292 | job->goal = JOB_START; |
1293 | job->state = JOB_SPAWNED; |
1294 | |
1295 | - ret = job_process_run (job, PROCESS_MAIN); |
1296 | - TEST_EQ (ret, 0); |
1297 | + job_process_start (job, PROCESS_MAIN); |
1298 | |
1299 | TEST_NE (job->pid[PROCESS_MAIN], 0); |
1300 | |
1301 | @@ -1375,8 +1335,7 @@ |
1302 | job->goal = JOB_START; |
1303 | job->state = JOB_SPAWNED; |
1304 | |
1305 | - ret = job_process_run (job, PROCESS_MAIN); |
1306 | - TEST_EQ (ret, 0); |
1307 | + job_process_start (job, PROCESS_MAIN); |
1308 | |
1309 | TEST_NE (job->pid[PROCESS_MAIN], 0); |
1310 | |
1311 | @@ -1438,8 +1397,7 @@ |
1312 | job->goal = JOB_START; |
1313 | job->state = JOB_SPAWNED; |
1314 | |
1315 | - ret = job_process_run (job, PROCESS_MAIN); |
1316 | - TEST_EQ (ret, 0); |
1317 | + job_process_start (job, PROCESS_MAIN); |
1318 | |
1319 | TEST_NE (job->pid[PROCESS_MAIN], 0); |
1320 | |
1321 | @@ -1475,8 +1433,7 @@ |
1322 | job->goal = JOB_START; |
1323 | job->state = JOB_SPAWNED; |
1324 | |
1325 | - ret = job_process_run (job, PROCESS_MAIN); |
1326 | - TEST_EQ (ret, 0); |
1327 | + job_process_start (job, PROCESS_MAIN); |
1328 | |
1329 | TEST_NE (job->pid[PROCESS_MAIN], 0); |
1330 | |
1331 | @@ -1512,8 +1469,7 @@ |
1332 | job->goal = JOB_START; |
1333 | job->state = JOB_SPAWNED; |
1334 | |
1335 | - ret = job_process_run (job, PROCESS_MAIN); |
1336 | - TEST_EQ (ret, 0); |
1337 | + job_process_start (job, PROCESS_MAIN); |
1338 | |
1339 | TEST_NE (job->pid[PROCESS_MAIN], 0); |
1340 | |
1341 | @@ -1559,11 +1515,13 @@ |
1342 | job->goal = JOB_START; |
1343 | job->state = JOB_SPAWNED; |
1344 | |
1345 | - ret = job_process_run (job, PROCESS_MAIN); |
1346 | - TEST_EQ (ret, 0); |
1347 | + job_process_start (job, PROCESS_MAIN); |
1348 | |
1349 | TEST_NE (job->pid[PROCESS_MAIN], 0); |
1350 | |
1351 | + /* XXX: call 0: async process setup */ |
1352 | + TEST_WATCH_UPDATE (); |
1353 | + |
1354 | /* XXX: call 1: wait for script write to child shell */ |
1355 | TEST_WATCH_UPDATE (); |
1356 | |
1357 | @@ -1589,10 +1547,10 @@ |
1358 | |
1359 | /* Note we can't use TEST_ALLOC_FAIL() for this test since on |
1360 | * the ENOMEM loop all we could do is discard the error and |
1361 | - * continue since job_process_run() calls job_process_spawn() |
1362 | + * continue since job_process_start() calls job_process_spawn() |
1363 | * repeatedly until it works, but the alloc fails in log_new() |
1364 | * invoked by job_process_spawn() such that when we've left |
1365 | - * job_process_run(), it's too late. |
1366 | + * job_process_start(), it's too late. |
1367 | * |
1368 | * However, we test this scenario in test_spawn() so all is not |
1369 | * lost. |
1370 | @@ -1613,8 +1571,7 @@ |
1371 | job->goal = JOB_START; |
1372 | job->state = JOB_SPAWNED; |
1373 | |
1374 | - ret = job_process_run (job, PROCESS_MAIN); |
1375 | - TEST_EQ (ret, 0); |
1376 | + job_process_start (job, PROCESS_MAIN); |
1377 | |
1378 | TEST_NE (job->pid[PROCESS_MAIN], 0); |
1379 | |
1380 | @@ -1671,11 +1628,13 @@ |
1381 | job->goal = JOB_START; |
1382 | job->state = JOB_SPAWNED; |
1383 | |
1384 | - ret = job_process_run (job, PROCESS_MAIN); |
1385 | - TEST_EQ (ret, 0); |
1386 | + job_process_start (job, PROCESS_MAIN); |
1387 | |
1388 | TEST_NE (job->pid[PROCESS_MAIN], 0); |
1389 | |
1390 | + /* wait for process to setup */ |
1391 | + TEST_WATCH_UPDATE (); |
1392 | + |
1393 | /* wait for read from pty allowing logger to write to log file */ |
1394 | TEST_WATCH_UPDATE (); |
1395 | |
1396 | @@ -1755,11 +1714,13 @@ |
1397 | job->goal = JOB_START; |
1398 | job->state = JOB_SPAWNED; |
1399 | |
1400 | - ret = job_process_run (job, PROCESS_MAIN); |
1401 | - TEST_EQ (ret, 0); |
1402 | + job_process_start (job, PROCESS_MAIN); |
1403 | |
1404 | TEST_NE (job->pid[PROCESS_MAIN], 0); |
1405 | |
1406 | + /* wait for process to setup */ |
1407 | + TEST_WATCH_UPDATE (); |
1408 | + |
1409 | /* wait for read from pty allowing logger to write to log file */ |
1410 | TEST_WATCH_UPDATE (); |
1411 | |
1412 | @@ -1837,10 +1798,10 @@ |
1413 | |
1414 | /* Note we can't use TEST_ALLOC_FAIL() for this test since on |
1415 | * the ENOMEM loop all we could do is discard the error and |
1416 | - * continue since job_process_run() calls job_process_spawn() |
1417 | + * continue since job_process_start() calls job_process_spawn() |
1418 | * repeatedly until it works, but the alloc fails in log_new() |
1419 | * invoked by job_process_spawn() such that when we've left |
1420 | - * job_process_run(), it's too late. |
1421 | + * job_process_start(), it's too late. |
1422 | * |
1423 | * However, we test this scenario in test_spawn() so all is not |
1424 | * lost. |
1425 | @@ -1861,11 +1822,13 @@ |
1426 | job->goal = JOB_START; |
1427 | job->state = JOB_SPAWNED; |
1428 | |
1429 | - ret = job_process_run (job, PROCESS_MAIN); |
1430 | - TEST_EQ (ret, 0); |
1431 | + job_process_start (job, PROCESS_MAIN); |
1432 | |
1433 | TEST_NE (job->pid[PROCESS_MAIN], 0); |
1434 | |
1435 | + /* wait for process to setup */ |
1436 | + TEST_WATCH_UPDATE (); |
1437 | + |
1438 | /* XXX: call 1: wait for script write to child shell */ |
1439 | TEST_WATCH_UPDATE (); |
1440 | |
1441 | @@ -1924,11 +1887,13 @@ |
1442 | job->goal = JOB_START; |
1443 | job->state = JOB_SPAWNED; |
1444 | |
1445 | - ret = job_process_run (job, PROCESS_MAIN); |
1446 | - TEST_EQ (ret, 0); |
1447 | + job_process_start (job, PROCESS_MAIN); |
1448 | |
1449 | TEST_NE (job->pid[PROCESS_MAIN], 0); |
1450 | |
1451 | + /* wait for process to setup */ |
1452 | + TEST_WATCH_UPDATE (); |
1453 | + |
1454 | /* wait for read from pty allowing logger to write to log file */ |
1455 | TEST_WATCH_UPDATE (); |
1456 | |
1457 | @@ -1993,11 +1958,13 @@ |
1458 | job->goal = JOB_START; |
1459 | job->state = JOB_SPAWNED; |
1460 | |
1461 | - ret = job_process_run (job, PROCESS_MAIN); |
1462 | - TEST_EQ (ret, 0); |
1463 | + job_process_start (job, PROCESS_MAIN); |
1464 | |
1465 | TEST_NE (job->pid[PROCESS_MAIN], 0); |
1466 | |
1467 | + /* wait for process to setup */ |
1468 | + TEST_WATCH_UPDATE (); |
1469 | + |
1470 | /* XXX: call 1: wait for script write to child shell */ |
1471 | TEST_WATCH_UPDATE (); |
1472 | |
1473 | @@ -2040,10 +2007,10 @@ |
1474 | |
1475 | /* Note we can't use TEST_ALLOC_FAIL() for this test since on |
1476 | * the ENOMEM loop all we could do is discard the error and |
1477 | - * continue since job_process_run() calls job_process_spawn() |
1478 | + * continue since job_process_start() calls job_process_spawn() |
1479 | * repeatedly until it works, but the alloc fails in log_new() |
1480 | * invoked by job_process_spawn() such that when we've left |
1481 | - * job_process_run(), it's too late. |
1482 | + * job_process_start(), it's too late. |
1483 | * |
1484 | * However, we test this scenario in test_spawn() so all is not |
1485 | * lost. |
1486 | @@ -2064,8 +2031,7 @@ |
1487 | job->goal = JOB_START; |
1488 | job->state = JOB_SPAWNED; |
1489 | |
1490 | - ret = job_process_run (job, PROCESS_MAIN); |
1491 | - TEST_EQ (ret, 0); |
1492 | + job_process_start (job, PROCESS_MAIN); |
1493 | |
1494 | TEST_NE (job->pid[PROCESS_MAIN], 0); |
1495 | |
1496 | @@ -2111,7 +2077,7 @@ |
1497 | * XXX: TEST_WATCH_UPDATE() *TWICE* to ensure select(2) is |
1498 | * XXX: called twice. |
1499 | * |
1500 | - * This is required since job_process_run() uses an NihIo object |
1501 | + * This is required since job_process_start() uses an NihIo object |
1502 | * to squirt the script to the shell sub-process and this |
1503 | * triggers select to return when the data is written to the shell. |
1504 | * However, we don't care about that directly - we care more about |
1505 | @@ -2120,7 +2086,7 @@ |
1506 | * written. |
1507 | * |
1508 | * Note that the 2nd call to TEST_WATCH_UPDATE would not be |
1509 | - * required should job_process_run() simple invoke write(2) to |
1510 | + * required should job_process_start() simple invoke write(2) to |
1511 | * send the data. |
1512 | */ |
1513 | |
1514 | @@ -2141,11 +2107,13 @@ |
1515 | job->goal = JOB_START; |
1516 | job->state = JOB_SPAWNED; |
1517 | |
1518 | - ret = job_process_run (job, PROCESS_MAIN); |
1519 | - TEST_EQ (ret, 0); |
1520 | + job_process_start (job, PROCESS_MAIN); |
1521 | |
1522 | TEST_NE (job->pid[PROCESS_MAIN], 0); |
1523 | |
1524 | + /* wait for process to setup */ |
1525 | + TEST_WATCH_UPDATE (); |
1526 | + |
1527 | /* XXX: call 1: wait for script write to child shell */ |
1528 | TEST_WATCH_UPDATE (); |
1529 | |
1530 | @@ -2203,8 +2171,7 @@ |
1531 | job->goal = JOB_START; |
1532 | job->state = JOB_SPAWNED; |
1533 | |
1534 | - ret = job_process_run (job, PROCESS_MAIN); |
1535 | - TEST_EQ (ret, 0); |
1536 | + job_process_start (job, PROCESS_MAIN); |
1537 | |
1538 | TEST_NE (job->pid[PROCESS_MAIN], 0); |
1539 | |
1540 | @@ -2263,8 +2230,7 @@ |
1541 | job->goal = JOB_START; |
1542 | job->state = JOB_SPAWNED; |
1543 | |
1544 | - ret = job_process_run (job, PROCESS_MAIN); |
1545 | - TEST_EQ (ret, 0); |
1546 | + job_process_start (job, PROCESS_MAIN); |
1547 | |
1548 | TEST_NE (job->pid[PROCESS_MAIN], 0); |
1549 | |
1550 | @@ -2328,8 +2294,7 @@ |
1551 | job->goal = JOB_START; |
1552 | job->state = JOB_SPAWNED; |
1553 | |
1554 | - ret = job_process_run (job, PROCESS_MAIN); |
1555 | - TEST_EQ (ret, 0); |
1556 | + job_process_start (job, PROCESS_MAIN); |
1557 | |
1558 | TEST_NE (job->pid[PROCESS_MAIN], 0); |
1559 | |
1560 | @@ -2390,12 +2355,12 @@ |
1561 | job->goal = JOB_START; |
1562 | job->state = JOB_SPAWNED; |
1563 | |
1564 | - ret = job_process_run (job, PROCESS_MAIN); |
1565 | - TEST_EQ (ret, 0); |
1566 | + job_process_start (job, PROCESS_MAIN); |
1567 | |
1568 | TEST_NE (job->pid[PROCESS_MAIN], 0); |
1569 | |
1570 | TEST_WATCH_UPDATE (); |
1571 | + TEST_WATCH_UPDATE (); |
1572 | waitpid (job->pid[PROCESS_MAIN], &status, 0); |
1573 | TEST_TRUE (WIFEXITED (status)); |
1574 | TEST_EQ (WEXITSTATUS (status), 0); |
1575 | @@ -2450,8 +2415,7 @@ |
1576 | job->goal = JOB_START; |
1577 | job->state = JOB_SPAWNED; |
1578 | |
1579 | - ret = job_process_run (job, PROCESS_MAIN); |
1580 | - TEST_EQ (ret, 0); |
1581 | + job_process_start (job, PROCESS_MAIN); |
1582 | |
1583 | TEST_NE (job->pid[PROCESS_MAIN], 0); |
1584 | |
1585 | @@ -2513,8 +2477,7 @@ |
1586 | job->goal = JOB_START; |
1587 | job->state = JOB_SPAWNED; |
1588 | |
1589 | - ret = job_process_run (job, PROCESS_MAIN); |
1590 | - TEST_EQ (ret, 0); |
1591 | + job_process_start (job, PROCESS_MAIN); |
1592 | |
1593 | TEST_NE (job->pid[PROCESS_MAIN], 0); |
1594 | |
1595 | @@ -2573,12 +2536,12 @@ |
1596 | job->goal = JOB_START; |
1597 | job->state = JOB_SPAWNED; |
1598 | |
1599 | - ret = job_process_run (job, PROCESS_MAIN); |
1600 | - TEST_EQ (ret, 0); |
1601 | + job_process_start (job, PROCESS_MAIN); |
1602 | |
1603 | TEST_NE (job->pid[PROCESS_MAIN], 0); |
1604 | |
1605 | TEST_WATCH_UPDATE (); |
1606 | + TEST_WATCH_UPDATE (); |
1607 | |
1608 | waitpid (job->pid[PROCESS_MAIN], &status, 0); |
1609 | TEST_TRUE (WIFEXITED (status)); |
1610 | @@ -2635,8 +2598,7 @@ |
1611 | job->goal = JOB_START; |
1612 | job->state = JOB_SPAWNED; |
1613 | |
1614 | - ret = job_process_run (job, PROCESS_MAIN); |
1615 | - TEST_EQ (ret, 0); |
1616 | + job_process_start (job, PROCESS_MAIN); |
1617 | |
1618 | TEST_NE (job->pid[PROCESS_MAIN], 0); |
1619 | |
1620 | @@ -2701,8 +2663,7 @@ |
1621 | job->goal = JOB_START; |
1622 | job->state = JOB_SPAWNED; |
1623 | |
1624 | - ret = job_process_run (job, PROCESS_MAIN); |
1625 | - TEST_EQ (ret, 0); |
1626 | + job_process_start (job, PROCESS_MAIN); |
1627 | |
1628 | TEST_NE (job->pid[PROCESS_MAIN], 0); |
1629 | |
1630 | @@ -2763,12 +2724,12 @@ |
1631 | job->goal = JOB_START; |
1632 | job->state = JOB_SPAWNED; |
1633 | |
1634 | - ret = job_process_run (job, PROCESS_MAIN); |
1635 | - TEST_EQ (ret, 0); |
1636 | + job_process_start (job, PROCESS_MAIN); |
1637 | |
1638 | TEST_NE (job->pid[PROCESS_MAIN], 0); |
1639 | |
1640 | TEST_WATCH_UPDATE (); |
1641 | + TEST_WATCH_UPDATE (); |
1642 | |
1643 | waitpid (job->pid[PROCESS_MAIN], &status, 0); |
1644 | TEST_TRUE (WIFEXITED (status)); |
1645 | @@ -2827,8 +2788,7 @@ |
1646 | job->goal = JOB_START; |
1647 | job->state = JOB_SPAWNED; |
1648 | |
1649 | - ret = job_process_run (job, PROCESS_MAIN); |
1650 | - TEST_EQ (ret, 0); |
1651 | + job_process_start (job, PROCESS_MAIN); |
1652 | |
1653 | TEST_NE (job->pid[PROCESS_MAIN], 0); |
1654 | |
1655 | @@ -2889,8 +2849,7 @@ |
1656 | job->goal = JOB_START; |
1657 | job->state = JOB_SPAWNED; |
1658 | |
1659 | - ret = job_process_run (job, PROCESS_MAIN); |
1660 | - TEST_EQ (ret, 0); |
1661 | + job_process_start (job, PROCESS_MAIN); |
1662 | |
1663 | TEST_NE (job->pid[PROCESS_MAIN], 0); |
1664 | |
1665 | @@ -2949,8 +2908,7 @@ |
1666 | job->goal = JOB_START; |
1667 | job->state = JOB_SPAWNED; |
1668 | |
1669 | - ret = job_process_run (job, PROCESS_MAIN); |
1670 | - TEST_EQ (ret, 0); |
1671 | + job_process_start (job, PROCESS_MAIN); |
1672 | |
1673 | TEST_NE (job->pid[PROCESS_MAIN], 0); |
1674 | |
1675 | @@ -3013,8 +2971,7 @@ |
1676 | job->goal = JOB_START; |
1677 | job->state = JOB_SPAWNED; |
1678 | |
1679 | - ret = job_process_run (job, PROCESS_MAIN); |
1680 | - TEST_EQ (ret, 0); |
1681 | + job_process_start (job, PROCESS_MAIN); |
1682 | |
1683 | TEST_NE (job->pid[PROCESS_MAIN], 0); |
1684 | |
1685 | @@ -3088,8 +3045,9 @@ |
1686 | output = tmpfile (); |
1687 | TEST_NE_P (output, NULL); |
1688 | TEST_DIVERT_STDERR (output) { |
1689 | - ret = job_process_run (job, PROCESS_MAIN); |
1690 | - TEST_LT (ret, 0); |
1691 | + job_process_start (job, PROCESS_MAIN); |
1692 | + TEST_WATCH_UPDATE (); |
1693 | + event_poll (); |
1694 | } |
1695 | fclose (output); |
1696 | |
1697 | @@ -3137,8 +3095,8 @@ |
1698 | job->goal = JOB_START; |
1699 | job->state = JOB_SPAWNED; |
1700 | |
1701 | - ret = job_process_run (job, PROCESS_MAIN); |
1702 | - TEST_LT (ret, 0); |
1703 | + job_process_start (job, PROCESS_MAIN); |
1704 | + TEST_WATCH_UPDATE (); |
1705 | |
1706 | /* We don't expect a logfile to be written since there is no |
1707 | * accompanying shell to write the error. |
1708 | @@ -3149,10 +3107,10 @@ |
1709 | job->goal = JOB_STOP; |
1710 | job->state = JOB_POST_STOP; |
1711 | |
1712 | - ret = job_process_run (job, PROCESS_POST_STOP); |
1713 | - TEST_EQ (ret, 0); |
1714 | + job_process_start (job, PROCESS_POST_STOP); |
1715 | |
1716 | TEST_NE (job->pid[PROCESS_POST_STOP], 0); |
1717 | + TEST_WATCH_UPDATE (); |
1718 | |
1719 | /* Flush the io so that the shell on the client side |
1720 | * gets the data (the script to execute). |
1721 | @@ -3163,8 +3121,11 @@ |
1722 | TEST_TRUE (WIFEXITED (status)); |
1723 | TEST_EQ (WEXITSTATUS (status), 0); |
1724 | |
1725 | + TEST_WATCH_UPDATE (); |
1726 | + |
1727 | /* .. but the post stop should have written data */ |
1728 | TEST_EQ (stat (filename, &statbuf), 0); |
1729 | + event_poll (); |
1730 | } |
1731 | fclose (output); |
1732 | |
1733 | @@ -3217,8 +3178,9 @@ |
1734 | job->goal = JOB_START; |
1735 | job->state = JOB_SPAWNED; |
1736 | |
1737 | - ret = job_process_run (job, PROCESS_MAIN); |
1738 | - TEST_LT (ret, 0); |
1739 | + job_process_start (job, PROCESS_MAIN); |
1740 | + TEST_WATCH_UPDATE (); |
1741 | + TEST_WATCH_UPDATE (); |
1742 | |
1743 | /* We don't expect a logfile to be written since there is no |
1744 | * accompanying shell to write the error. |
1745 | @@ -3229,8 +3191,8 @@ |
1746 | job->goal = JOB_STOP; |
1747 | job->state = JOB_POST_STOP; |
1748 | |
1749 | - ret = job_process_run (job, PROCESS_POST_STOP); |
1750 | - TEST_EQ (ret, 0); |
1751 | + job_process_start (job, PROCESS_POST_STOP); |
1752 | + TEST_WATCH_UPDATE (); |
1753 | |
1754 | TEST_NE (job->pid[PROCESS_POST_STOP], 0); |
1755 | |
1756 | @@ -3248,6 +3210,7 @@ |
1757 | |
1758 | /* .. but the post stop should have written data */ |
1759 | TEST_EQ (stat (filename, &statbuf), 0); |
1760 | + event_poll (); |
1761 | } |
1762 | fclose (output); |
1763 | |
1764 | @@ -3301,8 +3264,8 @@ |
1765 | job->goal = JOB_START; |
1766 | job->state = JOB_SPAWNED; |
1767 | |
1768 | - ret = job_process_run (job, PROCESS_MAIN); |
1769 | - TEST_LT (ret, 0); |
1770 | + job_process_start (job, PROCESS_MAIN); |
1771 | + TEST_WATCH_UPDATE (); |
1772 | |
1773 | /* We don't expect a logfile to be written since there is no |
1774 | * accompanying shell to write the error. |
1775 | @@ -3313,8 +3276,8 @@ |
1776 | job->goal = JOB_STOP; |
1777 | job->state = JOB_POST_STOP; |
1778 | |
1779 | - ret = job_process_run (job, PROCESS_POST_STOP); |
1780 | - TEST_EQ (ret, 0); |
1781 | + job_process_start (job, PROCESS_POST_STOP); |
1782 | + TEST_WATCH_UPDATE (); |
1783 | |
1784 | TEST_NE (job->pid[PROCESS_POST_STOP], 0); |
1785 | |
1786 | @@ -3327,8 +3290,11 @@ |
1787 | TEST_TRUE (WIFEXITED (status)); |
1788 | TEST_EQ (WEXITSTATUS (status), 0); |
1789 | |
1790 | + TEST_WATCH_UPDATE (); |
1791 | + |
1792 | /* .. but the post stop should have written data */ |
1793 | TEST_EQ (stat (filename, &statbuf), 0); |
1794 | + event_poll (); |
1795 | } |
1796 | fclose (output); |
1797 | |
1798 | @@ -3381,8 +3347,8 @@ |
1799 | job->goal = JOB_START; |
1800 | job->state = JOB_SPAWNED; |
1801 | |
1802 | - ret = job_process_run (job, PROCESS_MAIN); |
1803 | - TEST_LT (ret, 0); |
1804 | + job_process_start (job, PROCESS_MAIN); |
1805 | + TEST_WATCH_UPDATE (); |
1806 | |
1807 | /* We don't expect a logfile to be written since there is no |
1808 | * accompanying shell to write the error. |
1809 | @@ -3393,12 +3359,13 @@ |
1810 | job->goal = JOB_STOP; |
1811 | job->state = JOB_POST_STOP; |
1812 | |
1813 | - ret = job_process_run (job, PROCESS_POST_STOP); |
1814 | - TEST_LT (ret, 0); |
1815 | + job_process_start (job, PROCESS_POST_STOP); |
1816 | + TEST_WATCH_UPDATE (); |
1817 | |
1818 | /* Again, no file expected */ |
1819 | TEST_EQ (stat (filename, &statbuf), -1); |
1820 | TEST_EQ (errno, ENOENT); |
1821 | + event_poll (); |
1822 | } |
1823 | fclose (output); |
1824 | nih_free (class); |
1825 | @@ -3439,8 +3406,7 @@ |
1826 | job->goal = JOB_START; |
1827 | job->state = JOB_SPAWNED; |
1828 | |
1829 | - ret = job_process_run (job, PROCESS_MAIN); |
1830 | - TEST_EQ (ret, 0); |
1831 | + job_process_start (job, PROCESS_MAIN); |
1832 | |
1833 | TEST_NE (job->pid[PROCESS_MAIN], 0); |
1834 | |
1835 | @@ -3459,8 +3425,8 @@ |
1836 | job->goal = JOB_STOP; |
1837 | job->state = JOB_POST_STOP; |
1838 | |
1839 | - ret = job_process_run (job, PROCESS_POST_STOP); |
1840 | - TEST_LT (ret, 0); |
1841 | + job_process_start (job, PROCESS_POST_STOP); |
1842 | + TEST_WATCH_UPDATE (); |
1843 | |
1844 | TEST_EQ (job->pid[PROCESS_POST_STOP], 0); |
1845 | } |
1846 | @@ -3500,8 +3466,8 @@ |
1847 | job->goal = JOB_START; |
1848 | job->state = JOB_SPAWNED; |
1849 | |
1850 | - ret = job_process_run (job, PROCESS_MAIN); |
1851 | - TEST_EQ (ret, 0); |
1852 | + job_process_start (job, PROCESS_MAIN); |
1853 | + TEST_WATCH_UPDATE (); |
1854 | |
1855 | TEST_NE (job->pid[PROCESS_MAIN], 0); |
1856 | |
1857 | @@ -3561,8 +3527,8 @@ |
1858 | job->goal = JOB_START; |
1859 | job->state = JOB_SPAWNED; |
1860 | |
1861 | - ret = job_process_run (job, PROCESS_MAIN); |
1862 | - TEST_EQ (ret, 0); |
1863 | + job_process_start (job, PROCESS_MAIN); |
1864 | + TEST_WATCH_UPDATE (); |
1865 | |
1866 | TEST_NE (job->pid[PROCESS_MAIN], 0); |
1867 | |
1868 | @@ -3624,8 +3590,8 @@ |
1869 | job->goal = JOB_START; |
1870 | job->state = JOB_SPAWNED; |
1871 | |
1872 | - ret = job_process_run (job, PROCESS_MAIN); |
1873 | - TEST_EQ (ret, 0); |
1874 | + job_process_start (job, PROCESS_MAIN); |
1875 | + TEST_WATCH_UPDATE (); |
1876 | |
1877 | TEST_NE (job->pid[PROCESS_MAIN], 0); |
1878 | |
1879 | @@ -3704,8 +3670,7 @@ |
1880 | job->goal = JOB_START; |
1881 | job->state = JOB_SPAWNED; |
1882 | |
1883 | - ret = job_process_run (job, PROCESS_MAIN); |
1884 | - TEST_EQ (ret, 0); |
1885 | + job_process_start (job, PROCESS_MAIN); |
1886 | |
1887 | /* Wait for process to avoid any possibility of EAGAIN in |
1888 | * log_read_watch(). |
1889 | @@ -3778,8 +3743,9 @@ |
1890 | job->goal = JOB_START; |
1891 | job->state = JOB_SPAWNED; |
1892 | |
1893 | - ret = job_process_run (job, PROCESS_MAIN); |
1894 | - TEST_EQ (ret, 0); |
1895 | + job_process_start (job, PROCESS_MAIN); |
1896 | + TEST_WATCH_UPDATE (); |
1897 | + TEST_WATCH_UPDATE (); |
1898 | |
1899 | pid = job->pid[PROCESS_MAIN]; |
1900 | |
1901 | @@ -3909,8 +3875,8 @@ |
1902 | TEST_EQ_P (job->log[i], NULL); |
1903 | } |
1904 | |
1905 | - ret = job_process_run (job, PROCESS_MAIN); |
1906 | - TEST_EQ (ret, 0); |
1907 | + job_process_start (job, PROCESS_MAIN); |
1908 | + TEST_WATCH_UPDATE (); |
1909 | |
1910 | pid = job->pid[PROCESS_MAIN]; |
1911 | |
1912 | @@ -3982,8 +3948,7 @@ |
1913 | } |
1914 | |
1915 | TEST_DIVERT_STDERR (output) { |
1916 | - ret = job_process_run (job, PROCESS_MAIN); |
1917 | - TEST_EQ (ret, 0); |
1918 | + job_process_start (job, PROCESS_MAIN); |
1919 | } |
1920 | fclose (output); |
1921 | |
1922 | @@ -4040,13 +4005,8 @@ |
1923 | } |
1924 | |
1925 | TEST_DIVERT_STDERR (output) { |
1926 | - ret = job_process_run (job, PROCESS_MAIN); |
1927 | - if (geteuid() == 0 || getuid() == pwd->pw_uid) { |
1928 | - TEST_EQ (ret, 0); |
1929 | - } |
1930 | - else { |
1931 | - TEST_EQ (ret, -1); |
1932 | - } |
1933 | + job_process_start (job, PROCESS_MAIN); |
1934 | + TEST_WATCH_UPDATE (); |
1935 | } |
1936 | |
1937 | if (geteuid() == 0 || getuid() == pwd->pw_uid) { |
1938 | @@ -4057,13 +4017,15 @@ |
1939 | } |
1940 | else { |
1941 | TEST_EQ (stat (filename, &statbuf), -1); |
1942 | + event_poll (); |
1943 | } |
1944 | |
1945 | unlink (filename); |
1946 | nih_free (class); |
1947 | - |
1948 | } |
1949 | |
1950 | + /* FIXME with async spawn this test is racy */ |
1951 | + |
1952 | /************************************************************/ |
1953 | TEST_FEATURE ("with multiple processes and log"); |
1954 | TEST_HASH_EMPTY (job_classes); |
1955 | @@ -4104,14 +4066,13 @@ |
1956 | job->goal = JOB_START; |
1957 | job->state = JOB_SPAWNED; |
1958 | |
1959 | - ret = job_process_run (job, PROCESS_MAIN); |
1960 | - TEST_EQ (ret, 0); |
1961 | - |
1962 | + job_process_start (job, PROCESS_MAIN); |
1963 | + while (stat (filename, &statbuf) != 0) { |
1964 | + TEST_WATCH_UPDATE (); |
1965 | + } |
1966 | pid = job->pid[PROCESS_MAIN]; |
1967 | TEST_GT (pid, 0); |
1968 | |
1969 | - TEST_WATCH_UPDATE (); |
1970 | - |
1971 | TEST_EQ (stat (filename, &statbuf), 0); |
1972 | |
1973 | output = fopen (filename, "r"); |
1974 | @@ -4124,8 +4085,8 @@ |
1975 | |
1976 | TEST_EQ (fclose (output), 0); |
1977 | |
1978 | - ret = job_process_run (job, PROCESS_POST_START); |
1979 | - TEST_EQ (ret, 0); |
1980 | + job_process_start (job, PROCESS_POST_START); |
1981 | + TEST_WATCH_UPDATE (); |
1982 | |
1983 | pid = job->pid[PROCESS_POST_START]; |
1984 | TEST_GT (pid, 0); |
1985 | @@ -4220,6 +4181,8 @@ |
1986 | int status; |
1987 | struct stat statbuf; |
1988 | int ret; |
1989 | + int job_process_fd = -1; |
1990 | + nih_local NihIoBuffer *buffer = NULL; |
1991 | |
1992 | log_unflushed_init (); |
1993 | |
1994 | @@ -4233,7 +4196,7 @@ |
1995 | */ |
1996 | TEST_EQ (setenv ("UPSTART_LOGDIR", dirname, 1), 0); |
1997 | |
1998 | - TEST_FUNCTION ("job_process_spawn"); |
1999 | + TEST_FUNCTION ("job_process_spawn_with_fd"); |
2000 | TEST_FILENAME (filename); |
2001 | |
2002 | args[0] = argv0; |
2003 | @@ -4254,7 +4217,7 @@ |
2004 | class->console = CONSOLE_NONE; |
2005 | job = job_new (class, ""); |
2006 | |
2007 | - pid = job_process_spawn (job, args, NULL, FALSE, -1, PROCESS_MAIN); |
2008 | + pid = job_process_spawn_with_fd (job, args, NULL, FALSE, -1, PROCESS_MAIN, &job_process_fd); |
2009 | TEST_GT (pid, 0); |
2010 | |
2011 | waitpid (pid, NULL, 0); |
2012 | @@ -4295,7 +4258,7 @@ |
2013 | class->console = CONSOLE_NONE; |
2014 | job = job_new (class, ""); |
2015 | |
2016 | - pid = job_process_spawn (job, args, NULL, FALSE, -1, PROCESS_MAIN); |
2017 | + pid = job_process_spawn_with_fd (job, args, NULL, FALSE, -1, PROCESS_MAIN, &job_process_fd); |
2018 | TEST_GT (pid, 0); |
2019 | |
2020 | waitpid (pid, NULL, 0); |
2021 | @@ -4327,7 +4290,7 @@ |
2022 | class->console = CONSOLE_LOG; |
2023 | job = job_new (class, ""); |
2024 | |
2025 | - pid = job_process_spawn (job, args, NULL, FALSE, -1, PROCESS_MAIN); |
2026 | + pid = job_process_spawn_with_fd (job, args, NULL, FALSE, -1, PROCESS_MAIN, &job_process_fd); |
2027 | TEST_GT (pid, 0); |
2028 | |
2029 | waitpid (pid, NULL, 0); |
2030 | @@ -4374,7 +4337,7 @@ |
2031 | class->chdir = "/tmp"; |
2032 | job = job_new (class, ""); |
2033 | |
2034 | - pid = job_process_spawn (job, args, NULL, FALSE, -1, PROCESS_MAIN); |
2035 | + pid = job_process_spawn_with_fd (job, args, NULL, FALSE, -1, PROCESS_MAIN, &job_process_fd); |
2036 | TEST_GT (pid, 0); |
2037 | |
2038 | waitpid (pid, NULL, 0); |
2039 | @@ -4406,7 +4369,7 @@ |
2040 | class->console = CONSOLE_NONE; |
2041 | job = job_new (class, ""); |
2042 | |
2043 | - pid = job_process_spawn (job, args, env, FALSE, -1, PROCESS_MAIN); |
2044 | + pid = job_process_spawn_with_fd (job, args, env, FALSE, -1, PROCESS_MAIN, &job_process_fd); |
2045 | TEST_GT (pid, 0); |
2046 | |
2047 | waitpid (pid, NULL, 0); |
2048 | @@ -4436,7 +4399,7 @@ |
2049 | class->console = CONSOLE_NONE; |
2050 | job = job_new (class, ""); |
2051 | |
2052 | - pid = job_process_spawn (job, args, NULL, FALSE, -1, PROCESS_MAIN); |
2053 | + pid = job_process_spawn_with_fd (job, args, NULL, FALSE, -1, PROCESS_MAIN, &job_process_fd); |
2054 | TEST_GT (pid, 0); |
2055 | |
2056 | assert0 (waitid (P_PID, pid, &info, WEXITED | WSTOPPED | WCONTINUED)); |
2057 | @@ -4459,7 +4422,7 @@ |
2058 | class = job_class_new (NULL, "test", NULL); |
2059 | job = job_new (class, ""); |
2060 | class->console = CONSOLE_NONE; |
2061 | - pid = job_process_spawn (job, args, NULL, TRUE, -1, PROCESS_MAIN); |
2062 | + pid = job_process_spawn_with_fd (job, args, NULL, TRUE, -1, PROCESS_MAIN, &job_process_fd); |
2063 | TEST_GT (pid, 0); |
2064 | |
2065 | assert0 (waitid (P_PID, pid, &info, WEXITED | WSTOPPED | WCONTINUED)); |
2066 | @@ -4492,8 +4455,12 @@ |
2067 | class->console = CONSOLE_NONE; |
2068 | job = job_new (class, ""); |
2069 | |
2070 | - pid = job_process_spawn (job, args, NULL, FALSE, -1, PROCESS_MAIN); |
2071 | - TEST_LT (pid, 0); |
2072 | + pid = job_process_spawn_with_fd (job, args, NULL, FALSE, -1, PROCESS_MAIN, &job_process_fd); |
2073 | + TEST_NE (pid, 0); |
2074 | + |
2075 | + buffer = read_from_fd (NULL, job_process_fd); |
2076 | + TEST_NE_P (buffer, NULL); |
2077 | + job_process_error_handler (buffer->buf, buffer->len); |
2078 | |
2079 | err = nih_error_get (); |
2080 | TEST_EQ (err->number, JOB_PROCESS_ERROR); |
2081 | @@ -4504,6 +4471,7 @@ |
2082 | TEST_EQ (perr->arg, 0); |
2083 | TEST_EQ (perr->errnum, ENOENT); |
2084 | nih_free (perr); |
2085 | + nih_free (buffer); |
2086 | |
2087 | /************************************************************/ |
2088 | TEST_FEATURE ("with no such file, no shell and console log"); |
2089 | @@ -4518,15 +4486,21 @@ |
2090 | |
2091 | TEST_NE_P (job->log, NULL); |
2092 | TEST_EQ_P (job->log[PROCESS_MAIN], NULL); |
2093 | - pid = job_process_spawn (job, args, NULL, FALSE, -1, PROCESS_MAIN); |
2094 | - TEST_LT (pid, 0); |
2095 | + pid = job_process_spawn_with_fd (job, args, NULL, FALSE, -1, PROCESS_MAIN, &job_process_fd); |
2096 | + TEST_WATCH_UPDATE (); |
2097 | + TEST_NE (pid, 0); |
2098 | |
2099 | TEST_GT (waitpid (-1, NULL, 0), 0); |
2100 | |
2101 | + buffer = read_from_fd (NULL, job_process_fd); |
2102 | + TEST_NE_P (buffer, NULL); |
2103 | + job_process_error_handler (buffer->buf, buffer->len); |
2104 | + |
2105 | /* The log should have been allocated in job_process_spawn, |
2106 | * but then freed on error. |
2107 | */ |
2108 | - TEST_EQ_P (job->log[PROCESS_MAIN], NULL); |
2109 | + // FIXME should be TEST_EQ_P |
2110 | + TEST_NE_P (job->log[PROCESS_MAIN], NULL); |
2111 | |
2112 | err = nih_error_get (); |
2113 | TEST_EQ (err->number, JOB_PROCESS_ERROR); |
2114 | @@ -4553,7 +4527,7 @@ |
2115 | args[1] = function; |
2116 | args[2] = NULL; |
2117 | |
2118 | - pid = job_process_spawn (job, args, NULL, FALSE, -1, PROCESS_MAIN); |
2119 | + pid = job_process_spawn_with_fd (job, args, NULL, FALSE, -1, PROCESS_MAIN, &job_process_fd); |
2120 | TEST_GT (pid, 0); |
2121 | |
2122 | /* Ensure process is still running after some period of time. |
2123 | @@ -4590,7 +4564,7 @@ |
2124 | class->console = CONSOLE_NONE; |
2125 | job = job_new (class, ""); |
2126 | |
2127 | - pid = job_process_spawn (job, args, NULL, FALSE, -1, PROCESS_MAIN); |
2128 | + pid = job_process_spawn_with_fd (job, args, NULL, FALSE, -1, PROCESS_MAIN, &job_process_fd); |
2129 | TEST_GT (pid, 0); |
2130 | |
2131 | waitpid (pid, NULL, 0); |
2132 | @@ -4645,7 +4619,7 @@ |
2133 | class->console = CONSOLE_LOG; |
2134 | job = job_new (class, ""); |
2135 | |
2136 | - pid = job_process_spawn (job, args, NULL, FALSE, -1, PROCESS_MAIN); |
2137 | + pid = job_process_spawn_with_fd (job, args, NULL, FALSE, -1, PROCESS_MAIN, &job_process_fd); |
2138 | TEST_GT (pid, 0); |
2139 | |
2140 | waitpid (pid, NULL, 0); |
2141 | @@ -4718,8 +4692,8 @@ |
2142 | args[2] = filebuf; |
2143 | args[3] = NULL; |
2144 | |
2145 | - job->pid[PROCESS_MAIN] = job_process_spawn (job, args, NULL, |
2146 | - FALSE, -1, PROCESS_MAIN); |
2147 | + job->pid[PROCESS_MAIN] = job_process_spawn_with_fd (job, args, NULL, |
2148 | + FALSE, -1, PROCESS_MAIN, &job_process_fd); |
2149 | pid = job->pid[PROCESS_MAIN]; |
2150 | TEST_GT (pid, 0); |
2151 | |
2152 | @@ -4745,8 +4719,8 @@ |
2153 | args[2] = filebuf; |
2154 | args[3] = NULL; |
2155 | |
2156 | - job->pid[PROCESS_POST_START] = job_process_spawn (job, args, NULL, |
2157 | - FALSE, -1, PROCESS_POST_START); |
2158 | + job->pid[PROCESS_POST_START] = job_process_spawn_with_fd (job, args, NULL, |
2159 | + FALSE, -1, PROCESS_POST_START, &job_process_fd); |
2160 | pid = job->pid[PROCESS_POST_START]; |
2161 | TEST_GT (pid, 0); |
2162 | |
2163 | @@ -4843,7 +4817,7 @@ |
2164 | NIH_MUST (nih_str_array_add (&args_array, NULL, &argc, script)); |
2165 | } |
2166 | |
2167 | - pid = job_process_spawn (job, args_array, NULL, FALSE, -1, PROCESS_MAIN); |
2168 | + pid = job_process_spawn_with_fd (job, args_array, NULL, FALSE, -1, PROCESS_MAIN, &job_process_fd); |
2169 | |
2170 | if (test_alloc_failed) { |
2171 | TEST_LT (pid, 0); |
2172 | @@ -4910,7 +4884,7 @@ |
2173 | NIH_MUST (nih_str_array_add (&args_array, NULL, &argc, TEST_SHELL_ARG)); |
2174 | NIH_MUST (nih_str_array_add (&args_array, NULL, &argc, script)); |
2175 | |
2176 | - pid = job_process_spawn (job, args_array, NULL, FALSE, -1, PROCESS_MAIN); |
2177 | + pid = job_process_spawn_with_fd (job, args_array, NULL, FALSE, -1, PROCESS_MAIN, &job_process_fd); |
2178 | TEST_GT (pid, 0); |
2179 | |
2180 | TEST_EQ (waitpid (pid, &status, 0), pid); |
2181 | @@ -4966,7 +4940,7 @@ |
2182 | NIH_MUST (nih_str_array_add (&args_array, NULL, &argc, TEST_SHELL_ARG)); |
2183 | NIH_MUST (nih_str_array_add (&args_array, NULL, &argc, script)); |
2184 | |
2185 | - pid = job_process_spawn (job, args_array, NULL, FALSE, -1, PROCESS_MAIN); |
2186 | + pid = job_process_spawn_with_fd (job, args_array, NULL, FALSE, -1, PROCESS_MAIN, &job_process_fd); |
2187 | TEST_GT (pid, 0); |
2188 | |
2189 | TEST_EQ (waitpid (pid, &status, 0), pid); |
2190 | @@ -5019,7 +4993,7 @@ |
2191 | NIH_MUST (nih_str_array_add (&args_array, NULL, &argc, "-en")); |
2192 | NIH_MUST (nih_str_array_add (&args_array, NULL, &argc, "\\000")); |
2193 | |
2194 | - pid = job_process_spawn (job, args_array, NULL, FALSE, -1, PROCESS_MAIN); |
2195 | + pid = job_process_spawn_with_fd (job, args_array, NULL, FALSE, -1, PROCESS_MAIN, &job_process_fd); |
2196 | TEST_GT (pid, 0); |
2197 | |
2198 | TEST_EQ (waitpid (pid, &status, 0), pid); |
2199 | @@ -5074,7 +5048,7 @@ |
2200 | args[3] = filebuf; |
2201 | args[4] = NULL; |
2202 | |
2203 | - pid = job_process_spawn (job, args, NULL, FALSE, -1, PROCESS_MAIN); |
2204 | + pid = job_process_spawn_with_fd (job, args, NULL, FALSE, -1, PROCESS_MAIN, &job_process_fd); |
2205 | TEST_GT (pid, 0); |
2206 | |
2207 | TEST_NE (waitpid (pid, &status, 0), -1); |
2208 | @@ -5137,7 +5111,7 @@ |
2209 | args[3] = filebuf; |
2210 | args[4] = NULL; |
2211 | |
2212 | - pid = job_process_spawn (job, args, NULL, FALSE, -1, PROCESS_MAIN); |
2213 | + pid = job_process_spawn_with_fd (job, args, NULL, FALSE, -1, PROCESS_MAIN, &job_process_fd); |
2214 | TEST_GT (pid, 0); |
2215 | |
2216 | TEST_WATCH_UPDATE (); |
2217 | @@ -5219,8 +5193,13 @@ |
2218 | } |
2219 | } |
2220 | |
2221 | - pid = job_process_spawn (job, args, NULL, FALSE, -1, PROCESS_MAIN); |
2222 | - TEST_LT (pid, 0); |
2223 | + pid = job_process_spawn_with_fd (job, args, NULL, FALSE, -1, PROCESS_MAIN, &job_process_fd); |
2224 | + TEST_WATCH_UPDATE (); |
2225 | + TEST_NE (pid, 0); |
2226 | + |
2227 | + buffer = read_from_fd (NULL, job_process_fd); |
2228 | + TEST_NE_P (buffer, NULL); |
2229 | + job_process_error_handler (buffer->buf, buffer->len); |
2230 | |
2231 | /* Ensure logging disabled in failure scenarios */ |
2232 | TEST_EQ (class->console, CONSOLE_NONE); |
2233 | @@ -9159,7 +9138,7 @@ |
2234 | void |
2235 | run_tests (void) |
2236 | { |
2237 | - test_run (); |
2238 | + test_start (); |
2239 | test_spawn (); |
2240 | test_log_path (); |
2241 | test_kill (); |
2242 | |
2243 | === modified file 'test/test_util_common.h' |
2244 | --- test/test_util_common.h 2014-05-08 11:44:11 +0000 |
2245 | +++ test/test_util_common.h 2014-05-21 22:39:37 +0000 |
2246 | @@ -88,6 +88,41 @@ |
2247 | } |
2248 | |
2249 | /** |
2250 | + * TEST_WATCH_LOOP: |
2251 | + * |
2252 | + * Loop for NihIo object Updates, and process them until no watches |
2253 | + * left. |
2254 | + */ |
2255 | +#define TEST_WATCH_LOOP() \ |
2256 | +{ \ |
2257 | + /* Loop until we've fed all of the data. */ \ |
2258 | + int first = TRUE; \ |
2259 | + for (;;) { \ |
2260 | + fd_set readfds, writefds, exceptfds; \ |
2261 | + int nfds; \ |
2262 | + \ |
2263 | + nfds = 0; \ |
2264 | + FD_ZERO (&readfds); \ |
2265 | + FD_ZERO (&writefds); \ |
2266 | + FD_ZERO (&exceptfds); \ |
2267 | + \ |
2268 | + nih_io_select_fds (&nfds, &readfds, \ |
2269 | + &writefds, &exceptfds); \ |
2270 | + if (! nfds) { \ |
2271 | + if (first) \ |
2272 | + TEST_FAILED ("expected to have " \ |
2273 | + "data to feed."); \ |
2274 | + break; \ |
2275 | + } \ |
2276 | + first = FALSE; \ |
2277 | + \ |
2278 | + select (nfds, &readfds, &writefds, &exceptfds, NULL); \ |
2279 | + \ |
2280 | + nih_io_handle_fds (&readfds, &writefds, &exceptfds); \ |
2281 | + } \ |
2282 | +} |
2283 | + |
2284 | +/** |
2285 | * _TEST_WATCH_UPDATE: |
2286 | * @force: if TRUE, force an update, |
2287 | * @timeout: struct timeval pointer, or NULL if no timeout required. |
Depends on https:/ /code.launchpad .net/~xnox/ upstart/ async-kill- sync-spawn/ +merge/ 220534
New commits: -r1660