summaryrefslogtreecommitdiffstats
path: root/init
diff options
context:
space:
mode:
authorJean-Baptiste Queru <jbq@google.com>2009-07-25 18:07:41 -0700
committerJean-Baptiste Queru <jbq@google.com>2009-07-25 18:07:41 -0700
commit96d58f4f521ee4c1fef58efe5c009f1ea523d67c (patch)
tree75aa0cdbbcb6e35a93c43550c724bc4dba13dbea /init
parentdc9d52f35d6d590863b358997bf25605cf72be5f (diff)
parent3d9b265b7d34d886a2f44e486c25e402d7df791b (diff)
downloadsystem_core-96d58f4f521ee4c1fef58efe5c009f1ea523d67c.zip
system_core-96d58f4f521ee4c1fef58efe5c009f1ea523d67c.tar.gz
system_core-96d58f4f521ee4c1fef58efe5c009f1ea523d67c.tar.bz2
Merge korg/donut into korg/master
Diffstat (limited to 'init')
-rw-r--r--init/builtins.c6
-rw-r--r--init/devices.c9
-rw-r--r--init/init.c57
-rw-r--r--init/init.h15
-rw-r--r--init/parser.c10
-rw-r--r--init/property_service.c9
6 files changed, 79 insertions, 27 deletions
diff --git a/init/builtins.c b/init/builtins.c
index bcdfee1..93ce6e8 100644
--- a/init/builtins.c
+++ b/init/builtins.c
@@ -127,7 +127,7 @@ done:
static void service_start_if_not_disabled(struct service *svc)
{
if (!(svc->flags & SVC_DISABLED)) {
- service_start(svc);
+ service_start(svc, NULL);
}
}
@@ -372,7 +372,7 @@ int do_start(int nargs, char **args)
struct service *svc;
svc = service_find_by_name(args[1]);
if (svc) {
- service_start(svc);
+ service_start(svc, NULL);
}
return 0;
}
@@ -393,7 +393,7 @@ int do_restart(int nargs, char **args)
svc = service_find_by_name(args[1]);
if (svc) {
service_stop(svc);
- service_start(svc);
+ service_start(svc, NULL);
}
return 0;
}
diff --git a/init/devices.c b/init/devices.c
index e0b1f1f..60f9b9c 100644
--- a/init/devices.c
+++ b/init/devices.c
@@ -115,6 +115,7 @@ static struct perms_ devperms[] = {
{ "/dev/oncrpc/", 0660, AID_ROOT, AID_SYSTEM, 1 },
{ "/dev/adsp/", 0660, AID_SYSTEM, AID_AUDIO, 1 },
{ "/dev/mt9t013", 0660, AID_SYSTEM, AID_SYSTEM, 0 },
+ { "/dev/msm_camera/", 0660, AID_SYSTEM, AID_SYSTEM, 1 },
{ "/dev/akm8976_daemon",0640, AID_COMPASS, AID_SYSTEM, 0 },
{ "/dev/akm8976_aot", 0640, AID_COMPASS, AID_SYSTEM, 0 },
{ "/dev/akm8976_pffd", 0640, AID_COMPASS, AID_SYSTEM, 0 },
@@ -126,10 +127,13 @@ static struct perms_ devperms[] = {
{ "/dev/msm_audpre", 0660, AID_SYSTEM, AID_AUDIO, 0 },
{ "/dev/htc-acoustic", 0660, AID_SYSTEM, AID_AUDIO, 0 },
{ "/dev/smd0", 0640, AID_RADIO, AID_RADIO, 0 },
+ { "/dev/qemu_trace", 0666, AID_SYSTEM, AID_SYSTEM, 0 },
{ "/dev/qmi", 0640, AID_RADIO, AID_RADIO, 0 },
{ "/dev/qmi0", 0640, AID_RADIO, AID_RADIO, 0 },
{ "/dev/qmi1", 0640, AID_RADIO, AID_RADIO, 0 },
{ "/dev/qmi2", 0640, AID_RADIO, AID_RADIO, 0 },
+ { "/dev/ppp", 0660, AID_RADIO, AID_VPN, 0 },
+ { "/dev/tun", 0640, AID_VPN, AID_VPN, 0 },
{ NULL, 0, 0, 0, 0 },
};
@@ -380,7 +384,10 @@ static void handle_device_event(struct uevent *uevent)
} else if (!strncmp(uevent->subsystem, "adsp", 4)) {
base = "/dev/adsp/";
mkdir(base, 0755);
- } else if(!strncmp(uevent->subsystem, "input", 5)) {
+ } else if (!strncmp(uevent->subsystem, "msm_camera", 10)) {
+ base = "/dev/msm_camera/";
+ mkdir(base, 0755);
+ } else if(!strncmp(uevent->subsystem, "input", 5)) {
base = "/dev/input/";
mkdir(base, 0755);
} else if(!strncmp(uevent->subsystem, "mtd", 3)) {
diff --git a/init/init.c b/init/init.c
index 1630155..dfc858a 100644
--- a/init/init.c
+++ b/init/init.c
@@ -156,7 +156,7 @@ static void publish_socket(const char *name, int fd)
fcntl(fd, F_SETFD, 0);
}
-void service_start(struct service *svc)
+void service_start(struct service *svc, const char *dynamic_args)
{
struct stat s;
pid_t pid;
@@ -192,6 +192,13 @@ void service_start(struct service *svc)
return;
}
+ if ((!(svc->flags & SVC_ONESHOT)) && dynamic_args) {
+ ERROR("service '%s' must be one-shot to use dynamic args, disabling\n",
+ svc->args[0]);
+ svc->flags |= SVC_DISABLED;
+ return;
+ }
+
NOTICE("starting '%s'\n", svc->name);
pid = fork();
@@ -248,8 +255,27 @@ void service_start(struct service *svc)
setuid(svc->uid);
}
- if (execve(svc->args[0], (char**) svc->args, (char**) ENV) < 0) {
- ERROR("cannot execve('%s'): %s\n", svc->args[0], strerror(errno));
+ if (!dynamic_args)
+ if (execve(svc->args[0], (char**) svc->args, (char**) ENV) < 0)
+ ERROR("cannot execve('%s'): %s\n", svc->args[0], strerror(errno));
+ else {
+ char *arg_ptrs[SVC_MAXARGS+1];
+ int arg_idx = svc->nargs;
+ char *tmp = strdup(dynamic_args);
+ char *next = tmp;
+ char *bword;
+
+ /* Copy the static arguments */
+ memcpy(arg_ptrs, svc->args, (svc->nargs * sizeof(char *)));
+
+ while((bword = strsep(&next, " "))) {
+ arg_ptrs[arg_idx++] = bword;
+ if (arg_idx == SVC_MAXARGS)
+ break;
+ }
+ arg_ptrs[arg_idx] = '\0';
+ if (execve(svc->args[0], (char**) arg_ptrs, (char**) ENV) < 0)
+ ERROR("cannot execve('%s'): %s\n", svc->args[0], strerror(errno));
}
_exit(127);
}
@@ -381,7 +407,7 @@ static void restart_service_if_needed(struct service *svc)
if (next_start_time <= gettime()) {
svc->flags &= (~SVC_RESTARTING);
- service_start(svc);
+ service_start(svc, NULL);
return;
}
@@ -407,13 +433,28 @@ static void sigchld_handler(int s)
static void msg_start(const char *name)
{
- struct service *svc = service_find_by_name(name);
+ struct service *svc;
+ char *tmp = NULL;
+ char *args = NULL;
+
+ if (!strchr(name, ':'))
+ svc = service_find_by_name(name);
+ else {
+ tmp = strdup(name);
+ args = strchr(tmp, ':');
+ *args = '\0';
+ args++;
+
+ svc = service_find_by_name(tmp);
+ }
if (svc) {
- service_start(svc);
+ service_start(svc, args);
} else {
ERROR("no such service '%s'\n", name);
}
+ if (tmp)
+ free(tmp);
}
static void msg_stop(const char *name)
@@ -423,7 +464,7 @@ static void msg_stop(const char *name)
if (svc) {
service_stop(svc);
} else {
- ERROR("no such service '%s'\n");
+ ERROR("no such service '%s'\n", name);
}
}
@@ -739,7 +780,7 @@ void handle_keychord(int fd)
svc = service_find_by_keychord(id);
if (svc) {
INFO("starting service %s from keychord\n", svc->name);
- service_start(svc);
+ service_start(svc, NULL);
} else {
ERROR("service for keychord %d not found\n", id);
}
diff --git a/init/init.h b/init/init.h
index b686869..f306b7b 100644
--- a/init/init.h
+++ b/init/init.h
@@ -29,7 +29,8 @@ void *read_file(const char *fn, unsigned *_sz);
void log_init(void);
void log_set_level(int level);
void log_close(void);
-void log_write(int level, const char *fmt, ...);
+void log_write(int level, const char *fmt, ...)
+ __attribute__ ((format(printf, 2, 3)));
#define ERROR(x...) log_write(3, "<3>init: " x)
#define NOTICE(x...) log_write(5, "<5>init: " x)
@@ -115,6 +116,8 @@ struct svcenvinfo {
#define NR_SVC_SUPP_GIDS 6 /* six supplementary groups */
+#define SVC_MAXARGS 64
+
struct service {
/* list of all services */
struct listnode slist;
@@ -136,15 +139,17 @@ struct service {
struct socketinfo *sockets;
struct svcenvinfo *envvars;
- int nargs;
- char *args[1];
struct action onrestart; /* Actions to execute on restart. */
/* keycodes for triggering this service via /dev/keychord */
int *keycodes;
int nkeycodes;
int keychord_id;
-};
+
+ int nargs;
+ /* "MUST BE AT THE END OF THE STRUCT" */
+ char *args[1];
+}; /* ^-------'args' MUST be at the end of this struct! */
int parse_config_file(const char *fn);
@@ -157,7 +162,7 @@ void service_for_each_class(const char *classname,
void service_for_each_flags(unsigned matchflags,
void (*func)(struct service *svc));
void service_stop(struct service *svc);
-void service_start(struct service *svc);
+void service_start(struct service *svc, const char *dynamic_args);
void property_changed(const char *name, const char *value);
struct action *action_remove_queue_head(void);
diff --git a/init/parser.c b/init/parser.c
index 6a22d24..33c1a68 100644
--- a/init/parser.c
+++ b/init/parser.c
@@ -60,8 +60,6 @@ void DUMP(void)
#endif
}
-#define MAXARGS 64
-
#define T_EOF 0
#define T_TEXT 1
#define T_NEWLINE 2
@@ -357,7 +355,7 @@ void parse_new_section(struct parse_state *state, int kw,
static void parse_config(const char *fn, char *s)
{
struct parse_state state;
- char *args[MAXARGS];
+ char *args[SVC_MAXARGS];
int nargs;
nargs = 0;
@@ -384,7 +382,7 @@ static void parse_config(const char *fn, char *s)
}
break;
case T_TEXT:
- if (nargs < MAXARGS) {
+ if (nargs < SVC_MAXARGS) {
args[nargs++] = state.text;
}
break;
@@ -536,7 +534,7 @@ void queue_all_property_triggers()
const char* name = act->name + strlen("property:");
const char* equals = strchr(name, '=');
if (equals) {
- char* prop_name[PROP_NAME_MAX + 1];
+ char prop_name[PROP_NAME_MAX + 1];
const char* value;
int length = equals - name;
if (length > PROP_NAME_MAX) {
@@ -546,7 +544,7 @@ void queue_all_property_triggers()
prop_name[length] = 0;
/* does the property exist, and match the trigger value? */
- value = property_get((const char *)&prop_name[0]);
+ value = property_get(prop_name);
if (value && !strcmp(equals + 1, value)) {
action_add_queue_tail(act);
}
diff --git a/init/property_service.c b/init/property_service.c
index 0bc6239..23a8821 100644
--- a/init/property_service.c
+++ b/init/property_service.c
@@ -67,6 +67,8 @@ struct {
{ "wlan.", AID_SYSTEM },
{ "dhcp.", AID_SYSTEM },
{ "dhcp.", AID_DHCP },
+ { "vpn.", AID_SYSTEM },
+ { "vpn.", AID_VPN },
{ "debug.", AID_SHELL },
{ "log.", AID_SHELL },
{ "service.adb.root", AID_SHELL },
@@ -296,7 +298,7 @@ int property_set(const char *name, const char *value)
__futex_wake(&pa->serial, INT32_MAX);
}
/* If name starts with "net." treat as a DNS property. */
- if (strncmp("net.", name, sizeof("net.") - 1) == 0) {
+ if (strncmp("net.", name, strlen("net.")) == 0) {
if (strcmp("net.change", name) == 0) {
return 0;
}
@@ -307,7 +309,7 @@ int property_set(const char *name, const char *value)
*/
property_set("net.change", name);
} else if (persistent_properties_loaded &&
- strncmp("persist.", name, sizeof("persist.") - 1) == 0) {
+ strncmp("persist.", name, strlen("persist.")) == 0) {
/*
* Don't write properties to disk until after we have read all default properties
* to prevent them from being overwritten by default values.
@@ -446,8 +448,7 @@ static void load_persistent_properties()
if (dir) {
while ((entry = readdir(dir)) != NULL) {
- if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, "..") ||
- strncmp("persist.", entry->d_name, sizeof("persist.") - 1))
+ if (strncmp("persist.", entry->d_name, strlen("persist.")))
continue;
#if HAVE_DIRENT_D_TYPE
if (entry->d_type != DT_REG)