We should check for NULL here.
This commit is contained in:
parent
4c14666423
commit
b2f7606b23
@ -506,7 +506,7 @@ bool rc_service_daemons_crashed(const char *service)
|
|||||||
char *p;
|
char *p;
|
||||||
char *token;
|
char *token;
|
||||||
bool retval = false;
|
bool retval = false;
|
||||||
RC_STRINGLIST *list;
|
RC_STRINGLIST *list = NULL;
|
||||||
RC_STRING *s;
|
RC_STRING *s;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
@ -526,8 +526,6 @@ bool rc_service_daemons_crashed(const char *service)
|
|||||||
if (! fp)
|
if (! fp)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
list = rc_stringlist_new();
|
|
||||||
|
|
||||||
while ((line = rc_getline(fp))) {
|
while ((line = rc_getline(fp))) {
|
||||||
p = line;
|
p = line;
|
||||||
if ((token = strsep(&p, "=")) == NULL || ! p) {
|
if ((token = strsep(&p, "=")) == NULL || ! p) {
|
||||||
@ -541,6 +539,8 @@ bool rc_service_daemons_crashed(const char *service)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (strncmp(token, "argv_", 5) == 0) {
|
if (strncmp(token, "argv_", 5) == 0) {
|
||||||
|
if (! list)
|
||||||
|
list = rc_stringlist_new();
|
||||||
rc_stringlist_add(list, p);
|
rc_stringlist_add(list, p);
|
||||||
} else if (strcmp(token, "exec") == 0) {
|
} else if (strcmp(token, "exec") == 0) {
|
||||||
if (exec)
|
if (exec)
|
||||||
@ -551,9 +551,9 @@ bool rc_service_daemons_crashed(const char *service)
|
|||||||
free(name);
|
free(name);
|
||||||
name = xstrdup(p);
|
name = xstrdup(p);
|
||||||
} else if (strcmp(token, "pidfile") == 0) {
|
} else if (strcmp(token, "pidfile") == 0) {
|
||||||
if (pidfile)
|
|
||||||
free(pidfile);
|
|
||||||
pidfile = xstrdup(p);
|
pidfile = xstrdup(p);
|
||||||
|
free(line);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
free(line);
|
free(line);
|
||||||
}
|
}
|
||||||
@ -561,73 +561,68 @@ bool rc_service_daemons_crashed(const char *service)
|
|||||||
|
|
||||||
pid = 0;
|
pid = 0;
|
||||||
if (pidfile) {
|
if (pidfile) {
|
||||||
if (! exists(pidfile)) {
|
retval = true;
|
||||||
retval = true;
|
if ((fp = fopen(pidfile, "r"))) {
|
||||||
break;
|
if (fscanf(fp, "%d", &pid) == 1)
|
||||||
}
|
retval = false;
|
||||||
|
|
||||||
if ((fp = fopen(pidfile, "r")) == NULL) {
|
|
||||||
retval = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fscanf(fp, "%d", &pid) != 1) {
|
|
||||||
fclose (fp);
|
fclose (fp);
|
||||||
retval = true;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(fp);
|
|
||||||
free(pidfile);
|
free(pidfile);
|
||||||
pidfile = NULL;
|
pidfile = NULL;
|
||||||
|
|
||||||
/* We have the pid, so no need to match on name */
|
/* We have the pid, so no need to match on name */
|
||||||
rc_stringlist_free(list);
|
|
||||||
list = NULL;
|
|
||||||
free (exec);
|
|
||||||
exec = NULL;
|
|
||||||
free (name);
|
free (name);
|
||||||
name = NULL;
|
name = NULL;
|
||||||
} else {
|
} else {
|
||||||
if (exec && ! TAILQ_FIRST(list)) {
|
if (exec) {
|
||||||
rc_stringlist_add(list, exec);
|
if (! list)
|
||||||
}
|
list = rc_stringlist_new();
|
||||||
free(exec);
|
if (! TAILQ_FIRST(list))
|
||||||
exec = NULL;
|
rc_stringlist_add(list, exec);
|
||||||
|
|
||||||
/* We need to flatten our linked list into an array */
|
free(exec);
|
||||||
i = 0;
|
exec = NULL;
|
||||||
TAILQ_FOREACH(s, list, entries)
|
}
|
||||||
i++;
|
|
||||||
argv = xmalloc(sizeof(char *) * (i + 1));
|
if (list) {
|
||||||
i = 0;
|
/* We need to flatten our linked list into an array */
|
||||||
TAILQ_FOREACH(s, list, entries)
|
i = 0;
|
||||||
argv[i++] = s->value;
|
TAILQ_FOREACH(s, list, entries)
|
||||||
argv[i] = '\0';
|
i++;
|
||||||
|
argv = xmalloc(sizeof(char *) * (i + 1));
|
||||||
|
i = 0;
|
||||||
|
TAILQ_FOREACH(s, list, entries)
|
||||||
|
argv[i++] = s->value;
|
||||||
|
argv[i] = '\0';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((pids = rc_find_pids((const char *const *)argv,
|
if (! retval) {
|
||||||
name, 0, pid)) == NULL)
|
if ((pids = rc_find_pids((const char *const *)argv,
|
||||||
{
|
name, 0, pid)))
|
||||||
p1 = LIST_FIRST(pids);
|
{
|
||||||
while (p1) {
|
p1 = LIST_FIRST(pids);
|
||||||
p2 = LIST_NEXT(p1, entries);
|
while (p1) {
|
||||||
free(p1);
|
p2 = LIST_NEXT(p1, entries);
|
||||||
p1 = p2;
|
free(p1);
|
||||||
}
|
p1 = p2;
|
||||||
free(pids);
|
}
|
||||||
retval = true;
|
free(pids);
|
||||||
|
} else
|
||||||
|
retval = true;
|
||||||
}
|
}
|
||||||
|
rc_stringlist_free(list);
|
||||||
|
list = NULL;
|
||||||
free(argv);
|
free(argv);
|
||||||
argv = NULL;
|
argv = NULL;
|
||||||
rc_stringlist_free(list);
|
free(exec);
|
||||||
|
exec = NULL;
|
||||||
free(name);
|
free(name);
|
||||||
name = NULL;
|
name = NULL;
|
||||||
if (retval)
|
if (retval)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(dirpath);
|
|
||||||
closedir(dp);
|
closedir(dp);
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
|
@ -185,6 +185,8 @@ int rc_status (int argc, char **argv)
|
|||||||
TAILQ_FOREACH(l, levels, entries) {
|
TAILQ_FOREACH(l, levels, entries) {
|
||||||
print_level(l->value);
|
print_level(l->value);
|
||||||
services = rc_services_in_runlevel(l->value);
|
services = rc_services_in_runlevel(l->value);
|
||||||
|
if (! services)
|
||||||
|
continue;
|
||||||
if (deptree) {
|
if (deptree) {
|
||||||
if (! types) {
|
if (! types) {
|
||||||
types = rc_stringlist_new();
|
types = rc_stringlist_new();
|
||||||
|
16
src/rc/rc.c
16
src/rc/rc.c
@ -778,7 +778,7 @@ static void do_stop_services(const char *newlevel, bool going_down, bool paralle
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* We always stop the service when in these runlevels */
|
/* We always stop the service when in these runlevels */
|
||||||
if (going_down) {
|
if (going_down || ! start_services) {
|
||||||
pid = rc_service_stop(service->value);
|
pid = rc_service_stop(service->value);
|
||||||
if (pid > 0 && ! parallel)
|
if (pid > 0 && ! parallel)
|
||||||
rc_waitpid(pid);
|
rc_waitpid(pid);
|
||||||
@ -1097,18 +1097,20 @@ int main(int argc, char **argv)
|
|||||||
} else
|
} else
|
||||||
stop_services = tmplist;
|
stop_services = tmplist;
|
||||||
}
|
}
|
||||||
rc_stringlist_sort(&stop_services);
|
if (stop_services)
|
||||||
|
rc_stringlist_sort(&stop_services);
|
||||||
|
|
||||||
types_nua = rc_stringlist_new();
|
types_nua = rc_stringlist_new();
|
||||||
rc_stringlist_add(types_nua, "ineed");
|
rc_stringlist_add(types_nua, "ineed");
|
||||||
rc_stringlist_add(types_nua, "iuse");
|
rc_stringlist_add(types_nua, "iuse");
|
||||||
rc_stringlist_add(types_nua, "iafter");
|
rc_stringlist_add(types_nua, "iafter");
|
||||||
|
|
||||||
tmplist = rc_deptree_depends(deptree, types_nua, stop_services,
|
if (stop_services) {
|
||||||
runlevel, depoptions | RC_DEP_STOP);
|
tmplist = rc_deptree_depends(deptree, types_nua, stop_services,
|
||||||
rc_stringlist_free(stop_services);
|
runlevel, depoptions | RC_DEP_STOP);
|
||||||
stop_services = tmplist;
|
rc_stringlist_free(stop_services);
|
||||||
|
stop_services = tmplist;
|
||||||
|
}
|
||||||
|
|
||||||
/* Load our list of coldplugged services */
|
/* Load our list of coldplugged services */
|
||||||
coldplugged_services = rc_services_in_state(RC_SERVICE_COLDPLUGGED);
|
coldplugged_services = rc_services_in_state(RC_SERVICE_COLDPLUGGED);
|
||||||
|
@ -694,14 +694,14 @@ static void svc_start(bool deps)
|
|||||||
depoptions |= RC_DEP_STRICT;
|
depoptions |= RC_DEP_STRICT;
|
||||||
|
|
||||||
if (deps) {
|
if (deps) {
|
||||||
if (! deptree && ((deptree = _rc_deptree_load (NULL)) == NULL))
|
if (! deptree && ((deptree = _rc_deptree_load(NULL)) == NULL))
|
||||||
eerrorx("failed to load deptree");
|
eerrorx("failed to load deptree");
|
||||||
|
|
||||||
if (! types_b)
|
if (! types_b)
|
||||||
setup_types();
|
setup_types();
|
||||||
|
|
||||||
services = rc_deptree_depends(deptree, types_b, applet_list,
|
services = rc_deptree_depends(deptree, types_b, applet_list,
|
||||||
runlevel, 0);
|
runlevel, 0);
|
||||||
if (services && TAILQ_FIRST(services)) {
|
if (services && TAILQ_FIRST(services)) {
|
||||||
eerrorn("ERROR: `%s' needs ", applet);
|
eerrorn("ERROR: `%s' needs ", applet);
|
||||||
first = true;
|
first = true;
|
||||||
@ -718,9 +718,9 @@ static void svc_start(bool deps)
|
|||||||
services = NULL;
|
services = NULL;
|
||||||
|
|
||||||
need_services = rc_deptree_depends(deptree, types_n, applet_list,
|
need_services = rc_deptree_depends(deptree, types_n, applet_list,
|
||||||
runlevel, depoptions);
|
runlevel, depoptions);
|
||||||
use_services = rc_deptree_depends(deptree, types_nu, applet_list,
|
use_services = rc_deptree_depends(deptree, types_nu, applet_list,
|
||||||
runlevel, depoptions);
|
runlevel, depoptions);
|
||||||
|
|
||||||
if (! rc_runlevel_starting() && use_services)
|
if (! rc_runlevel_starting() && use_services)
|
||||||
TAILQ_FOREACH(svc, use_services, entries)
|
TAILQ_FOREACH(svc, use_services, entries)
|
||||||
@ -732,88 +732,90 @@ static void svc_start(bool deps)
|
|||||||
|
|
||||||
/* Now wait for them to start */
|
/* Now wait for them to start */
|
||||||
services = rc_deptree_depends(deptree, types_nua, applet_list,
|
services = rc_deptree_depends(deptree, types_nua, applet_list,
|
||||||
runlevel, depoptions);
|
runlevel, depoptions);
|
||||||
|
|
||||||
/* We use tmplist to hold our scheduled by list */
|
if (services) {
|
||||||
tmplist = NULL;
|
/* We use tmplist to hold our scheduled by list */
|
||||||
TAILQ_FOREACH(svc, services, entries) {
|
tmplist = NULL;
|
||||||
RC_SERVICE svcs = rc_service_state(svc->value);
|
TAILQ_FOREACH(svc, services, entries) {
|
||||||
if (svcs & RC_SERVICE_STARTED)
|
RC_SERVICE svcs = rc_service_state(svc->value);
|
||||||
continue;
|
if (svcs & RC_SERVICE_STARTED)
|
||||||
|
|
||||||
/* Don't wait for services which went inactive but are now in
|
|
||||||
* starting state which we are after */
|
|
||||||
if (svcs & RC_SERVICE_STARTING &&
|
|
||||||
svcs & RC_SERVICE_WASINACTIVE) {
|
|
||||||
TAILQ_FOREACH(svc2, use_services, entries) {
|
|
||||||
if (strcmp (svc->value, svc2->value) == 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (! svc2)
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
if (! svc_wait(svc->value))
|
/* Don't wait for services which went inactive but are now in
|
||||||
eerror ("%s: timed out waiting for %s",
|
* starting state which we are after */
|
||||||
applet, svc->value);
|
if (svcs & RC_SERVICE_STARTING &&
|
||||||
if (! need_services)
|
svcs & RC_SERVICE_WASINACTIVE) {
|
||||||
continue;
|
TAILQ_FOREACH(svc2, use_services, entries) {
|
||||||
if ((svcs = rc_service_state(svc->value)) & RC_SERVICE_STARTED)
|
if (strcmp (svc->value, svc2->value) == 0)
|
||||||
continue;
|
break;
|
||||||
TAILQ_FOREACH(svc2, need_services, entries) {
|
}
|
||||||
if (strcmp (svc->value, svc2->value) == 0) {
|
if (! svc2)
|
||||||
if (svcs & RC_SERVICE_INACTIVE ||
|
continue;
|
||||||
svcs & RC_SERVICE_WASINACTIVE)
|
}
|
||||||
{
|
|
||||||
if (! tmplist)
|
if (! svc_wait(svc->value))
|
||||||
tmplist = rc_stringlist_new();
|
eerror ("%s: timed out waiting for %s",
|
||||||
rc_stringlist_add(tmplist, svc->value);
|
|
||||||
} else
|
|
||||||
eerrorx("ERROR: cannot start %s as"
|
|
||||||
" %s would not start",
|
|
||||||
applet, svc->value);
|
applet, svc->value);
|
||||||
|
if (! need_services)
|
||||||
|
continue;
|
||||||
|
if ((svcs = rc_service_state(svc->value)) & RC_SERVICE_STARTED)
|
||||||
|
continue;
|
||||||
|
TAILQ_FOREACH(svc2, need_services, entries) {
|
||||||
|
if (strcmp (svc->value, svc2->value) == 0) {
|
||||||
|
if (svcs & RC_SERVICE_INACTIVE ||
|
||||||
|
svcs & RC_SERVICE_WASINACTIVE)
|
||||||
|
{
|
||||||
|
if (! tmplist)
|
||||||
|
tmplist = rc_stringlist_new();
|
||||||
|
rc_stringlist_add(tmplist, svc->value);
|
||||||
|
} else
|
||||||
|
eerrorx("ERROR: cannot start %s as"
|
||||||
|
" %s would not start",
|
||||||
|
applet, svc->value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (tmplist && TAILQ_FIRST(tmplist)) {
|
if (tmplist && TAILQ_FIRST(tmplist)) {
|
||||||
/* Set the state now, then unlink our exclusive so that
|
/* Set the state now, then unlink our exclusive so that
|
||||||
our scheduled list is preserved */
|
our scheduled list is preserved */
|
||||||
rc_service_mark(service, RC_SERVICE_STOPPED);
|
rc_service_mark(service, RC_SERVICE_STOPPED);
|
||||||
unlink_mtime_test();
|
unlink_mtime_test();
|
||||||
|
|
||||||
rc_stringlist_free(use_services);
|
|
||||||
use_services = NULL;
|
|
||||||
len = 0;
|
|
||||||
n = 0;
|
|
||||||
TAILQ_FOREACH(svc, tmplist, entries) {
|
|
||||||
rc_service_schedule_start(svc->value, service);
|
|
||||||
use_services = rc_deptree_depend(deptree, "iprovide",
|
|
||||||
svc->value);
|
|
||||||
TAILQ_FOREACH (svc2, use_services, entries)
|
|
||||||
rc_service_schedule_start(svc2->value, service);
|
|
||||||
rc_stringlist_free(use_services);
|
rc_stringlist_free(use_services);
|
||||||
use_services = NULL;
|
use_services = NULL;
|
||||||
len += strlen(svc->value) + 2;
|
len = 0;
|
||||||
n++;
|
n = 0;
|
||||||
|
TAILQ_FOREACH(svc, tmplist, entries) {
|
||||||
|
rc_service_schedule_start(svc->value, service);
|
||||||
|
use_services = rc_deptree_depend(deptree, "iprovide",
|
||||||
|
svc->value);
|
||||||
|
TAILQ_FOREACH (svc2, use_services, entries)
|
||||||
|
rc_service_schedule_start(svc2->value, service);
|
||||||
|
rc_stringlist_free(use_services);
|
||||||
|
use_services = NULL;
|
||||||
|
len += strlen(svc->value) + 2;
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
|
||||||
|
len += 5;
|
||||||
|
tmp = p = xmalloc(sizeof(char) * len);
|
||||||
|
TAILQ_FOREACH(svc, tmplist, entries) {
|
||||||
|
if (p != tmp)
|
||||||
|
p += snprintf(p, len, ", ");
|
||||||
|
p += snprintf(p, len, "%s", svc->value);
|
||||||
|
}
|
||||||
|
free(tmp);
|
||||||
|
rc_stringlist_free(tmplist);
|
||||||
|
tmplist = NULL;
|
||||||
|
ewarnx("WARNING: %s is scheduled to start when %s has started",
|
||||||
|
applet, tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
len += 5;
|
rc_stringlist_free(services);
|
||||||
tmp = p = xmalloc(sizeof(char) * len);
|
services = NULL;
|
||||||
TAILQ_FOREACH(svc, tmplist, entries) {
|
|
||||||
if (p != tmp)
|
|
||||||
p += snprintf(p, len, ", ");
|
|
||||||
p += snprintf(p, len, "%s", svc->value);
|
|
||||||
}
|
|
||||||
free(tmp);
|
|
||||||
rc_stringlist_free(tmplist);
|
|
||||||
tmplist = NULL;
|
|
||||||
ewarnx("WARNING: %s is scheduled to start when %s has started",
|
|
||||||
applet, tmp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rc_stringlist_free(services);
|
|
||||||
services = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ibsave)
|
if (ibsave)
|
||||||
|
Loading…
Reference in New Issue
Block a user