diff options
Diffstat (limited to 'init')
| -rw-r--r-- | init/builtins.c | 38 | ||||
| -rw-r--r-- | init/init_parser.c | 2 | ||||
| -rw-r--r-- | init/keywords.h | 2 | ||||
| -rw-r--r--[-rwxr-xr-x] | init/property_service.c | 34 |
4 files changed, 48 insertions, 28 deletions
diff --git a/init/builtins.c b/init/builtins.c index 576f0d9..6e37d08 100644 --- a/init/builtins.c +++ b/init/builtins.c @@ -32,6 +32,7 @@ #include <sys/wait.h> #include <linux/loop.h> #include <cutils/partition_utils.h> +#include <cutils/android_reboot.h> #include <sys/system_properties.h> #include <fs_mgr.h> @@ -598,6 +599,43 @@ int do_restart(int nargs, char **args) return 0; } +int do_powerctl(int nargs, char **args) +{ + char command[PROP_VALUE_MAX]; + int res; + int len = 0; + int cmd = 0; + char *reboot_target; + + res = expand_props(command, args[1], sizeof(command)); + if (res) { + ERROR("powerctl: cannot expand '%s'\n", args[1]); + return -EINVAL; + } + + if (strncmp(command, "shutdown", 8) == 0) { + cmd = ANDROID_RB_POWEROFF; + len = 8; + } else if (strncmp(command, "reboot", 6) == 0) { + cmd = ANDROID_RB_RESTART2; + len = 6; + } else { + ERROR("powerctl: unrecognized command '%s'\n", command); + return -EINVAL; + } + + if (command[len] == ',') { + reboot_target = &command[len + 1]; + } else if (command[len] == '\0') { + reboot_target = ""; + } else { + ERROR("powerctl: unrecognized reboot target '%s'\n", &command[len]); + return -EINVAL; + } + + return android_reboot(cmd, 0, reboot_target); +} + int do_trigger(int nargs, char **args) { action_for_each_trigger(args[1], action_add_queue_tail); diff --git a/init/init_parser.c b/init/init_parser.c index cce1093..28bf30c 100644 --- a/init/init_parser.c +++ b/init/init_parser.c @@ -130,6 +130,8 @@ int lookup_keyword(const char *s) if (!strcmp(s, "neshot")) return K_oneshot; if (!strcmp(s, "nrestart")) return K_onrestart; break; + case 'p': + if (!strcmp(s, "owerctl")) return K_powerctl; case 'r': if (!strcmp(s, "estart")) return K_restart; if (!strcmp(s, "estorecon")) return K_restorecon; diff --git a/init/keywords.h b/init/keywords.h index f188db5..f147506 100644 --- a/init/keywords.h +++ b/init/keywords.h @@ -14,6 +14,7 @@ int do_insmod(int nargs, char **args); int do_mkdir(int nargs, char **args); int do_mount_all(int nargs, char **args); int do_mount(int nargs, char **args); +int do_powerctl(int nargs, char **args); int do_restart(int nargs, char **args); int do_restorecon(int nargs, char **args); int do_rm(int nargs, char **args); @@ -66,6 +67,7 @@ enum { KEYWORD(on, SECTION, 0, 0) KEYWORD(oneshot, OPTION, 0, 0) KEYWORD(onrestart, OPTION, 0, 0) + KEYWORD(powerctl, COMMAND, 1, do_powerctl) KEYWORD(restart, COMMAND, 1, do_restart) KEYWORD(restorecon, COMMAND, 1, do_restorecon) KEYWORD(rm, COMMAND, 1, do_rm) diff --git a/init/property_service.c b/init/property_service.c index 88348bd..9afc756 100755..100644 --- a/init/property_service.c +++ b/init/property_service.c @@ -78,6 +78,7 @@ struct { { "runtime.", AID_SYSTEM, 0 }, { "hw.", AID_SYSTEM, 0 }, { "sys.", AID_SYSTEM, 0 }, + { "sys.powerctl", AID_SHELL, 0 }, { "service.", AID_SYSTEM, 0 }, { "wlan.", AID_SYSTEM, 0 }, { "bluetooth.", AID_BLUETOOTH, 0 }, @@ -111,7 +112,6 @@ struct { }; typedef struct { - void *data; size_t size; int fd; } workspace; @@ -119,36 +119,13 @@ typedef struct { static int init_workspace(workspace *w, size_t size) { void *data; - int fd; - - /* dev is a tmpfs that we can use to carve a shared workspace - * out of, so let's do that... - */ - fd = open(PROP_FILENAME, O_RDWR | O_CREAT | O_NOFOLLOW, 0644); - if (fd < 0) - return -1; - - if (ftruncate(fd, size) < 0) - goto out; - - data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - if(data == MAP_FAILED) - goto out; - - close(fd); - - fd = open(PROP_FILENAME, O_RDONLY | O_NOFOLLOW); + int fd = open(PROP_FILENAME, O_RDONLY | O_NOFOLLOW); if (fd < 0) return -1; - w->data = data; w->size = size; w->fd = fd; return 0; - -out: - close(fd); - return -1; } static workspace pa_workspace; @@ -158,12 +135,13 @@ static int init_property_area(void) if (property_area_inited) return -1; - if(init_workspace(&pa_workspace, PA_SIZE)) + if(__system_property_area_init()) return -1; - fcntl(pa_workspace.fd, F_SETFD, FD_CLOEXEC); + if(init_workspace(&pa_workspace, 0)) + return -1; - __system_property_area_init(pa_workspace.data); + fcntl(pa_workspace.fd, F_SETFD, FD_CLOEXEC); property_area_inited = 1; return 0; |
