Implement exec.
Change-Id: I20329bc9b378479d745b498d6a00eca0872cd5ab
diff --git a/init/signal_handler.cpp b/init/signal_handler.cpp
index c0898fb..c428b96 100644
--- a/init/signal_handler.cpp
+++ b/init/signal_handler.cpp
@@ -14,11 +14,11 @@
* limitations under the License.
*/
-#include <stdio.h>
#include <errno.h>
-#include <signal.h>
-#include <unistd.h>
#include <fcntl.h>
+#include <signal.h>
+#include <stdio.h>
+#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
@@ -27,34 +27,28 @@
#include <cutils/list.h>
#include "init.h"
-#include "util.h"
#include "log.h"
+#include "util.h"
static int signal_fd = -1;
static int signal_recv_fd = -1;
-static void sigchld_handler(int s)
-{
+static void sigchld_handler(int s) {
write(signal_fd, &s, 1);
}
#define CRITICAL_CRASH_THRESHOLD 4 /* if we crash >4 times ... */
-#define CRITICAL_CRASH_WINDOW (4*60) /* ... in 4 minutes, goto recovery*/
+#define CRITICAL_CRASH_WINDOW (4*60) /* ... in 4 minutes, goto recovery */
-static int wait_for_one_process(int block)
-{
+static int wait_for_one_process() {
int status;
- struct service *svc;
- struct socketinfo *si;
- time_t now;
- struct listnode *node;
- struct command *cmd;
-
- pid_t pid = TEMP_FAILURE_RETRY(waitpid(-1, &status, block ? 0 : WNOHANG));
- if (pid <= 0) return -1;
+ pid_t pid = TEMP_FAILURE_RETRY(waitpid(-1, &status, WNOHANG));
+ if (pid <= 0) {
+ return -1;
+ }
INFO("waitpid returned pid %d, status = %08x\n", pid, status);
- svc = service_find_by_pid(pid);
+ service* svc = service_find_by_pid(pid);
if (!svc) {
if (WIFEXITED(status)) {
ERROR("untracked pid %d exited with status %d\n", pid, WEXITSTATUS(status));
@@ -68,36 +62,47 @@
return 0;
}
+ // TODO: all the code from here down should be a member function on service.
+
NOTICE("process '%s', pid %d exited\n", svc->name, pid);
if (!(svc->flags & SVC_ONESHOT) || (svc->flags & SVC_RESTART)) {
- kill(-pid, SIGKILL);
NOTICE("process '%s' killing any children in process group\n", svc->name);
+ kill(-pid, SIGKILL);
}
- /* remove any sockets we may have created */
- for (si = svc->sockets; si; si = si->next) {
+ // Remove any sockets we may have created.
+ for (socketinfo* si = svc->sockets; si; si = si->next) {
char tmp[128];
snprintf(tmp, sizeof(tmp), ANDROID_SOCKET_DIR"/%s", si->name);
unlink(tmp);
}
+ if (svc->flags & SVC_EXEC) {
+ INFO("SVC_EXEC pid %d finished...\n", svc->pid);
+ waiting_for_exec = false;
+ list_remove(&svc->slist);
+ free(svc->name);
+ free(svc);
+ return 0;
+ }
+
svc->pid = 0;
svc->flags &= (~SVC_RUNNING);
- /* oneshot processes go into the disabled state on exit,
- * except when manually restarted. */
+ // Oneshot processes go into the disabled state on exit,
+ // except when manually restarted.
if ((svc->flags & SVC_ONESHOT) && !(svc->flags & SVC_RESTART)) {
svc->flags |= SVC_DISABLED;
}
- /* disabled and reset processes do not get restarted automatically */
- if (svc->flags & (SVC_DISABLED | SVC_RESET) ) {
- notify_service_state(svc->name, "stopped");
+ // Disabled and reset processes do not get restarted automatically.
+ if (svc->flags & (SVC_DISABLED | SVC_RESET)) {
+ svc->NotifyStateChange("stopped");
return 0;
}
- now = gettime();
+ time_t now = gettime();
if ((svc->flags & SVC_CRITICAL) && !(svc->flags & SVC_RESTART)) {
if (svc->time_crashed + CRITICAL_CRASH_WINDOW >= now) {
if (++svc->nr_crashed > CRITICAL_CRASH_THRESHOLD) {
@@ -116,36 +121,33 @@
svc->flags &= (~SVC_RESTART);
svc->flags |= SVC_RESTARTING;
- /* Execute all onrestart commands for this service. */
+ // Execute all onrestart commands for this service.
+ struct listnode* node;
list_for_each(node, &svc->onrestart.commands) {
- cmd = node_to_item(node, struct command, clist);
+ command* cmd = node_to_item(node, struct command, clist);
cmd->func(cmd->nargs, cmd->args);
}
- notify_service_state(svc->name, "restarting");
+ svc->NotifyStateChange("restarting");
return 0;
}
-void handle_signal(void)
-{
+void handle_signal() {
+ // We got a SIGCHLD - reap and restart as needed.
char tmp[32];
-
- /* we got a SIGCHLD - reap and restart as needed */
read(signal_recv_fd, tmp, sizeof(tmp));
- while (!wait_for_one_process(0))
- ;
+ while (!wait_for_one_process()) {
+ }
}
-void signal_init(void)
-{
- int s[2];
-
+void signal_init() {
struct sigaction act;
memset(&act, 0, sizeof(act));
act.sa_handler = sigchld_handler;
act.sa_flags = SA_NOCLDSTOP;
sigaction(SIGCHLD, &act, 0);
- /* create a signalling mechanism for the sigchld handler */
+ // Create a signalling mechanism for the sigchld handler.
+ int s[2];
if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0, s) == 0) {
signal_fd = s[0];
signal_recv_fd = s[1];
@@ -154,7 +156,6 @@
handle_signal();
}
-int get_signal_fd()
-{
+int get_signal_fd() {
return signal_recv_fd;
}