/[baselayout]/trunk/src/runscript.c
Gentoo

Diff of /trunk/src/runscript.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 2638 Revision 2641
7 */ 7 */
8 8
9#define APPLET "runscript" 9#define APPLET "runscript"
10 10
11#include <sys/types.h> 11#include <sys/types.h>
12#include <sys/signal.h>
13#include <sys/stat.h> 12#include <sys/stat.h>
14#include <sys/wait.h> 13#include <sys/wait.h>
15#include <dlfcn.h> 14#include <dlfcn.h>
16#include <errno.h> 15#include <errno.h>
17#include <getopt.h> 16#include <getopt.h>
18#include <libgen.h> 17#include <libgen.h>
19#include <limits.h> 18#include <limits.h>
19#include <signal.h>
20#include <stdio.h> 20#include <stdio.h>
21#include <stdlib.h> 21#include <stdlib.h>
22#include <string.h> 22#include <string.h>
23#include <unistd.h> 23#include <unistd.h>
24 24
47static char *softlevel = NULL; 47static char *softlevel = NULL;
48static bool sighup = false; 48static bool sighup = false;
49static char *ibsave = NULL; 49static char *ibsave = NULL;
50static bool in_background = false; 50static bool in_background = false;
51static rc_hook_t hook_out = 0; 51static rc_hook_t hook_out = 0;
52static pid_t service_pid = 0;
52 53
53extern char **environ; 54extern char **environ;
54 55
55#ifdef __linux__ 56#ifdef __linux__
56static void (*selinux_run_init_old) (void); 57static void (*selinux_run_init_old) (void);
106 if (errno != ECHILD) 107 if (errno != ECHILD)
107 eerror ("waitpid: %s", strerror (errno)); 108 eerror ("waitpid: %s", strerror (errno));
108 return; 109 return;
109 } 110 }
110 } while (! WIFEXITED (status) && ! WIFSIGNALED (status)); 111 } while (! WIFEXITED (status) && ! WIFSIGNALED (status));
112 if (pid == service_pid)
113 service_pid = 0;
111 break; 114 break;
112 115
113 case SIGINT: 116 case SIGINT:
114 if (! signame[0]) 117 if (! signame[0])
115 snprintf (signame, sizeof (signame), "SIGINT"); 118 snprintf (signame, sizeof (signame), "SIGINT");
117 if (! signame[0]) 120 if (! signame[0])
118 snprintf (signame, sizeof (signame), "SIGTERM"); 121 snprintf (signame, sizeof (signame), "SIGTERM");
119 case SIGQUIT: 122 case SIGQUIT:
120 if (! signame[0]) 123 if (! signame[0])
121 snprintf (signame, sizeof (signame), "SIGQUIT"); 124 snprintf (signame, sizeof (signame), "SIGQUIT");
125 /* Send the signal to our children too */
126 if (service_pid > 0)
127 kill (service_pid, sig);
122 eerrorx ("%s: caught %s, aborting", applet, signame); 128 eerrorx ("%s: caught %s, aborting", applet, signame);
123 129
124 default: 130 default:
125 eerror ("%s: caught unknown signal %d", applet, sig); 131 eerror ("%s: caught unknown signal %d", applet, sig);
126 } 132 }
257 free (applet); 263 free (applet);
258} 264}
259 265
260static bool svc_exec (const char *service, const char *arg1, const char *arg2) 266static bool svc_exec (const char *service, const char *arg1, const char *arg2)
261{ 267{
262 int status = 0; 268 bool retval;
263 pid_t pid;
264 269
265 /* We need to disable our child signal handler now so we block 270 /* We need to disable our child signal handler now so we block
266 until our script returns. */ 271 until our script returns. */
267 signal (SIGCHLD, NULL); 272 signal (SIGCHLD, NULL);
268 273
269 pid = vfork(); 274 service_pid = vfork();
270 275
271 if (pid == -1) 276 if (service_pid == -1)
272 eerrorx ("%s: vfork: %s", service, strerror (errno)); 277 eerrorx ("%s: vfork: %s", service, strerror (errno));
273 if (pid == 0) { 278 if (service_pid == 0) {
274 if (rc_exists (RC_SVCDIR "runscript.sh")) { 279 if (rc_exists (RC_SVCDIR "runscript.sh")) {
275 execl (RC_SVCDIR "runscript.sh", service, service, arg1, arg2, 280 execl (RC_SVCDIR "runscript.sh", service, service, arg1, arg2,
276 (char *) NULL); 281 (char *) NULL);
277 eerror ("%s: exec `" RC_SVCDIR "runscript.sh': %s", 282 eerror ("%s: exec `" RC_SVCDIR "runscript.sh': %s",
278 service, strerror (errno)); 283 service, strerror (errno));
284 service, strerror (errno)); 289 service, strerror (errno));
285 _exit (EXIT_FAILURE); 290 _exit (EXIT_FAILURE);
286 } 291 }
287 } 292 }
288 293
289 do { 294 retval = rc_waitpid (service_pid) == 0 ? true : false;
290 if (waitpid (pid, &status, 0) < 0) {
291 if (errno != ECHILD)
292 eerror ("waitpid: %s", strerror (errno));
293 break;
294 }
295 } while (! WIFEXITED (status) && ! WIFSIGNALED (status));
296 295
296 service_pid = 0;
297 /* Done, so restore the signal handler */ 297 /* Done, so restore the signal handler */
298 signal (SIGCHLD, handle_signal); 298 signal (SIGCHLD, handle_signal);
299 299
300 if (WIFEXITED (status))
301 return (WEXITSTATUS (status) ? false : true);
302
303 return (false); 300 return (retval);
304} 301}
305 302
306static rc_service_state_t svc_status (const char *service) 303static rc_service_state_t svc_status (const char *service)
307{ 304{
308 char status[10]; 305 char status[10];
465 types = rc_strlist_add (types, "iuse"); 462 types = rc_strlist_add (types, "iuse");
466 if (! rc_runlevel_starting ()) { 463 if (! rc_runlevel_starting ()) {
467 services = rc_get_depends (deptree, types, svclist, 464 services = rc_get_depends (deptree, types, svclist,
468 softlevel, depoptions); 465 softlevel, depoptions);
469 STRLIST_FOREACH (services, svc, i) 466 STRLIST_FOREACH (services, svc, i)
470 if (rc_service_state (svc, rc_service_stopped)) 467 if (rc_service_state (svc, rc_service_stopped)) {
471 rc_start_service (svc); 468 pid_t pid = rc_start_service (svc);
469 if (! rc_is_env ("RC_PARALLEL_STARTUP", "yes"))
470 rc_waitpid (pid);
471 }
472 472
473 rc_strlist_free (services); 473 rc_strlist_free (services);
474 } 474 }
475 475
476 /* Now wait for them to start */ 476 /* Now wait for them to start */
667 { 667 {
668 rc_wait_service (svc); 668 rc_wait_service (svc);
669 if (rc_service_state (svc, rc_service_started) || 669 if (rc_service_state (svc, rc_service_started) ||
670 rc_service_state (svc, rc_service_inactive)) 670 rc_service_state (svc, rc_service_inactive))
671 { 671 {
672 rc_stop_service (svc); 672 pid_t pid = rc_stop_service (svc);
673 if (! rc_is_env ("RC_PARALLEL_STARTUP", "yes"))
674 rc_waitpid (pid);
673 tmplist = rc_strlist_add (tmplist, svc); 675 tmplist = rc_strlist_add (tmplist, svc);
674 } 676 }
675 } 677 }
676 } 678 }
677 rc_strlist_free (services); 679 rc_strlist_free (services);

Legend:
Removed from v.2638  
changed lines
  Added in v.2641

  ViewVC Help
Powered by ViewVC 1.1.20