summaryrefslogtreecommitdiffstats
path: root/init
diff options
context:
space:
mode:
authorThe Android Open Source Project2009-01-09 20:04:23 -0600
committerThe Android Open Source Project2009-01-09 20:04:23 -0600
commit038862e152b98d0c0f355c6802beaa1ed59cefbe (patch)
treedbacb2690178316300d9fc2e4290582aec74cd9c /init
parent5a326952d72e7d4242a0664a6d9f27f4126beaa9 (diff)
parent5ae090ed949cea9d1e7ab1552b455a229f8f9757 (diff)
downloadplatform-system-core-038862e152b98d0c0f355c6802beaa1ed59cefbe.tar.gz
platform-system-core-038862e152b98d0c0f355c6802beaa1ed59cefbe.tar.xz
platform-system-core-038862e152b98d0c0f355c6802beaa1ed59cefbe.zip
Merge branch 'cupcake'
Diffstat (limited to 'init')
-rw-r--r--init/devices.c1
-rw-r--r--init/init.c157
-rw-r--r--init/init.h7
-rw-r--r--init/keywords.h1
-rw-r--r--init/parser.c45
5 files changed, 183 insertions, 28 deletions
diff --git a/init/devices.c b/init/devices.c
index 3cb1cb821..b58ff1e69 100644
--- a/init/devices.c
+++ b/init/devices.c
@@ -122,6 +122,7 @@ static struct perms_ devperms[] = {
122 { "/dev/msm_pcm_out", 0660, AID_SYSTEM, AID_AUDIO, 1 }, 122 { "/dev/msm_pcm_out", 0660, AID_SYSTEM, AID_AUDIO, 1 },
123 { "/dev/msm_pcm_in", 0660, AID_SYSTEM, AID_AUDIO, 1 }, 123 { "/dev/msm_pcm_in", 0660, AID_SYSTEM, AID_AUDIO, 1 },
124 { "/dev/msm_pcm_ctl", 0660, AID_SYSTEM, AID_AUDIO, 1 }, 124 { "/dev/msm_pcm_ctl", 0660, AID_SYSTEM, AID_AUDIO, 1 },
125 { "/dev/msm_snd", 0660, AID_SYSTEM, AID_AUDIO, 1 },
125 { "/dev/msm_mp3", 0660, AID_SYSTEM, AID_AUDIO, 1 }, 126 { "/dev/msm_mp3", 0660, AID_SYSTEM, AID_AUDIO, 1 },
126 { "/dev/msm_snd", 0660, AID_SYSTEM, AID_AUDIO, 1 }, 127 { "/dev/msm_snd", 0660, AID_SYSTEM, AID_AUDIO, 1 },
127 { "/dev/smd0", 0640, AID_RADIO, AID_RADIO, 0 }, 128 { "/dev/smd0", 0640, AID_RADIO, AID_RADIO, 0 },
diff --git a/init/init.c b/init/init.c
index 55ee9ab1c..163015553 100644
--- a/init/init.c
+++ b/init/init.c
@@ -37,6 +37,7 @@
37#include <cutils/sockets.h> 37#include <cutils/sockets.h>
38#include <termios.h> 38#include <termios.h>
39#include <linux/kd.h> 39#include <linux/kd.h>
40#include <linux/keychord.h>
40 41
41#include <sys/system_properties.h> 42#include <sys/system_properties.h>
42 43
@@ -60,6 +61,9 @@ static char bootloader[32];
60static char hardware[32]; 61static char hardware[32];
61static unsigned revision = 0; 62static unsigned revision = 0;
62static char qemu[32]; 63static char qemu[32];
64static struct input_keychord *keychords = 0;
65static int keychords_count = 0;
66static int keychords_length = 0;
63 67
64static void drain_action_queue(void); 68static void drain_action_queue(void);
65 69
@@ -233,7 +237,7 @@ void service_start(struct service *svc)
233 237
234 setpgid(0, getpid()); 238 setpgid(0, getpid());
235 239
236 /* as requested, set our gid, supplemental gids, and uid */ 240 /* as requested, set our gid, supplemental gids, and uid */
237 if (svc->gid) { 241 if (svc->gid) {
238 setgid(svc->gid); 242 setgid(svc->gid);
239 } 243 }
@@ -660,17 +664,101 @@ void open_devnull_stdio(void)
660 exit(1); 664 exit(1);
661} 665}
662 666
667void add_service_keycodes(struct service *svc)
668{
669 struct input_keychord *keychord;
670 int i, size;
671
672 if (svc->keycodes) {
673 /* add a new keychord to the list */
674 size = sizeof(*keychord) + svc->nkeycodes * sizeof(keychord->keycodes[0]);
675 keychords = realloc(keychords, keychords_length + size);
676 if (!keychords) {
677 ERROR("could not allocate keychords\n");
678 keychords_length = 0;
679 keychords_count = 0;
680 return;
681 }
682
683 keychord = (struct input_keychord *)((char *)keychords + keychords_length);
684 keychord->version = KEYCHORD_VERSION;
685 keychord->id = keychords_count + 1;
686 keychord->count = svc->nkeycodes;
687 svc->keychord_id = keychord->id;
688
689 for (i = 0; i < svc->nkeycodes; i++) {
690 keychord->keycodes[i] = svc->keycodes[i];
691 }
692 keychords_count++;
693 keychords_length += size;
694 }
695}
696
697int open_keychord()
698{
699 int fd, ret;
700
701 service_for_each(add_service_keycodes);
702
703 /* nothing to do if no services require keychords */
704 if (!keychords)
705 return -1;
706
707 fd = open("/dev/keychord", O_RDWR);
708 if (fd < 0) {
709 ERROR("could not open /dev/keychord\n");
710 return fd;
711 }
712 fcntl(fd, F_SETFD, FD_CLOEXEC);
713
714 ret = write(fd, keychords, keychords_length);
715 if (ret != keychords_length) {
716 ERROR("could not configure /dev/keychord %d (%d)\n", ret, errno);
717 close(fd);
718 fd = -1;
719 }
720
721 free(keychords);
722 keychords = 0;
723
724 return fd;
725}
726
727void handle_keychord(int fd)
728{
729 struct service *svc;
730 int ret;
731 __u16 id;
732
733 ret = read(fd, &id, sizeof(id));
734 if (ret != sizeof(id)) {
735 ERROR("could not read keychord id\n");
736 return;
737 }
738
739 svc = service_find_by_keychord(id);
740 if (svc) {
741 INFO("starting service %s from keychord\n", svc->name);
742 service_start(svc);
743 } else {
744 ERROR("service for keychord %d not found\n", id);
745 }
746}
747
663int main(int argc, char **argv) 748int main(int argc, char **argv)
664{ 749{
665 int device_fd = -1; 750 int device_fd = -1;
666 int property_set_fd = -1; 751 int property_set_fd = -1;
667 int signal_recv_fd = -1; 752 int signal_recv_fd = -1;
753 int keychord_fd = -1;
754 int fd_count;
668 int s[2]; 755 int s[2];
669 int fd; 756 int fd;
670 struct sigaction act; 757 struct sigaction act;
671 char tmp[PROP_VALUE_MAX]; 758 char tmp[PROP_VALUE_MAX];
672 struct pollfd ufds[4]; 759 struct pollfd ufds[4];
673 char *tmpdev; 760 char *tmpdev;
761 char* debuggable;
674 762
675 act.sa_handler = sigchld_handler; 763 act.sa_handler = sigchld_handler;
676 act.sa_flags = SA_NOCLDSTOP; 764 act.sa_flags = SA_NOCLDSTOP;
@@ -723,6 +811,12 @@ int main(int argc, char **argv)
723 device_fd = device_init(); 811 device_fd = device_init();
724 812
725 property_init(); 813 property_init();
814
815 // only listen for keychords if ro.debuggable is true
816 debuggable = property_get("ro.debuggable");
817 if (debuggable && !strcmp(debuggable, "1")) {
818 keychord_fd = open_keychord();
819 }
726 820
727 if (console[0]) { 821 if (console[0]) {
728 snprintf(tmp, sizeof(tmp), "/dev/%s", console); 822 snprintf(tmp, sizeof(tmp), "/dev/%s", console);
@@ -735,27 +829,27 @@ int main(int argc, char **argv)
735 close(fd); 829 close(fd);
736 830
737 if( load_565rle_image(INIT_IMAGE_FILE) ) { 831 if( load_565rle_image(INIT_IMAGE_FILE) ) {
738 fd = open("/dev/tty0", O_WRONLY); 832 fd = open("/dev/tty0", O_WRONLY);
739 if (fd >= 0) { 833 if (fd >= 0) {
740 const char *msg; 834 const char *msg;
741 msg = "\n" 835 msg = "\n"
742 "\n" 836 "\n"
743 "\n" 837 "\n"
744 "\n" 838 "\n"
745 "\n" 839 "\n"
746 "\n" 840 "\n"
747 "\n" // console is 40 cols x 30 lines 841 "\n" // console is 40 cols x 30 lines
748 "\n" 842 "\n"
749 "\n" 843 "\n"
750 "\n" 844 "\n"
751 "\n" 845 "\n"
752 "\n" 846 "\n"
753 "\n" 847 "\n"
754 "\n" 848 "\n"
755 " A N D R O I D "; 849 " A N D R O I D ";
756 write(fd, msg, strlen(msg)); 850 write(fd, msg, strlen(msg));
757 close(fd); 851 close(fd);
758 } 852 }
759 } 853 }
760 854
761 if (qemu[0]) 855 if (qemu[0])
@@ -825,6 +919,16 @@ int main(int argc, char **argv)
825 ufds[1].events = POLLIN; 919 ufds[1].events = POLLIN;
826 ufds[2].fd = signal_recv_fd; 920 ufds[2].fd = signal_recv_fd;
827 ufds[2].events = POLLIN; 921 ufds[2].events = POLLIN;
922 fd_count = 3;
923
924 if (keychord_fd > 0) {
925 ufds[3].fd = keychord_fd;
926 ufds[3].events = POLLIN;
927 fd_count++;
928 } else {
929 ufds[3].events = 0;
930 ufds[3].revents = 0;
931 }
828 932
829#if BOOTCHART 933#if BOOTCHART
830 bootchart_count = bootchart_init(); 934 bootchart_count = bootchart_init();
@@ -838,11 +942,10 @@ int main(int argc, char **argv)
838#endif 942#endif
839 943
840 for(;;) { 944 for(;;) {
841 int nr, timeout = -1; 945 int nr, i, timeout = -1;
842 946
843 ufds[0].revents = 0; 947 for (i = 0; i < fd_count; i++)
844 ufds[1].revents = 0; 948 ufds[i].revents = 0;
845 ufds[2].revents = 0;
846 949
847 drain_action_queue(); 950 drain_action_queue();
848 restart_processes(); 951 restart_processes();
@@ -863,7 +966,7 @@ int main(int argc, char **argv)
863 } 966 }
864 } 967 }
865#endif 968#endif
866 nr = poll(ufds, 3, timeout); 969 nr = poll(ufds, fd_count, timeout);
867 if (nr <= 0) 970 if (nr <= 0)
868 continue; 971 continue;
869 972
@@ -880,6 +983,8 @@ int main(int argc, char **argv)
880 983
881 if (ufds[1].revents == POLLIN) 984 if (ufds[1].revents == POLLIN)
882 handle_property_set_fd(property_set_fd); 985 handle_property_set_fd(property_set_fd);
986 if (ufds[3].revents == POLLIN)
987 handle_keychord(keychord_fd);
883 } 988 }
884 989
885 return 0; 990 return 0;
diff --git a/init/init.h b/init/init.h
index 4ff0c69dd..b68686930 100644
--- a/init/init.h
+++ b/init/init.h
@@ -139,12 +139,19 @@ struct service {
139 int nargs; 139 int nargs;
140 char *args[1]; 140 char *args[1];
141 struct action onrestart; /* Actions to execute on restart. */ 141 struct action onrestart; /* Actions to execute on restart. */
142
143 /* keycodes for triggering this service via /dev/keychord */
144 int *keycodes;
145 int nkeycodes;
146 int keychord_id;
142}; 147};
143 148
144int parse_config_file(const char *fn); 149int parse_config_file(const char *fn);
145 150
146struct service *service_find_by_name(const char *name); 151struct service *service_find_by_name(const char *name);
147struct service *service_find_by_pid(pid_t pid); 152struct service *service_find_by_pid(pid_t pid);
153struct service *service_find_by_keychord(int keychord_id);
154void service_for_each(void (*func)(struct service *svc));
148void service_for_each_class(const char *classname, 155void service_for_each_class(const char *classname,
149 void (*func)(struct service *svc)); 156 void (*func)(struct service *svc));
150void service_for_each_flags(unsigned matchflags, 157void service_for_each_flags(unsigned matchflags,
diff --git a/init/keywords.h b/init/keywords.h
index 058996e3b..6f47379c6 100644
--- a/init/keywords.h
+++ b/init/keywords.h
@@ -45,6 +45,7 @@ enum {
45 KEYWORD(ifup, COMMAND, 1, do_ifup) 45 KEYWORD(ifup, COMMAND, 1, do_ifup)
46 KEYWORD(insmod, COMMAND, 1, do_insmod) 46 KEYWORD(insmod, COMMAND, 1, do_insmod)
47 KEYWORD(import, COMMAND, 1, do_import) 47 KEYWORD(import, COMMAND, 1, do_import)
48 KEYWORD(keycodes, OPTION, 0, 0)
48 KEYWORD(mkdir, COMMAND, 1, do_mkdir) 49 KEYWORD(mkdir, COMMAND, 1, do_mkdir)
49 KEYWORD(mount, COMMAND, 3, do_mount) 50 KEYWORD(mount, COMMAND, 3, do_mount)
50 KEYWORD(on, SECTION, 0, 0) 51 KEYWORD(on, SECTION, 0, 0)
diff --git a/init/parser.c b/init/parser.c
index a51691be2..6a22d242d 100644
--- a/init/parser.c
+++ b/init/parser.c
@@ -158,6 +158,9 @@ int lookup_keyword(const char *s)
158 if (!strcmp(s, "nsmod")) return K_insmod; 158 if (!strcmp(s, "nsmod")) return K_insmod;
159 if (!strcmp(s, "mport")) return K_import; 159 if (!strcmp(s, "mport")) return K_import;
160 break; 160 break;
161 case 'k':
162 if (!strcmp(s, "eycodes")) return K_keycodes;
163 break;
161 case 'l': 164 case 'l':
162 if (!strcmp(s, "oglevel")) return K_loglevel; 165 if (!strcmp(s, "oglevel")) return K_loglevel;
163 break; 166 break;
@@ -183,7 +186,7 @@ int lookup_keyword(const char *s)
183 if (!strcmp(s, "tart")) return K_start; 186 if (!strcmp(s, "tart")) return K_start;
184 if (!strcmp(s, "top")) return K_stop; 187 if (!strcmp(s, "top")) return K_stop;
185 if (!strcmp(s, "ymlink")) return K_symlink; 188 if (!strcmp(s, "ymlink")) return K_symlink;
186 if (!strcmp(s, "ysclktz")) return K_sysclktz; 189 if (!strcmp(s, "ysclktz")) return K_sysclktz;
187 break; 190 break;
188 case 't': 191 case 't':
189 if (!strcmp(s, "rigger")) return K_trigger; 192 if (!strcmp(s, "rigger")) return K_trigger;
@@ -440,6 +443,29 @@ struct service *service_find_by_pid(pid_t pid)
440 return 0; 443 return 0;
441} 444}
442 445
446struct service *service_find_by_keychord(int keychord_id)
447{
448 struct listnode *node;
449 struct service *svc;
450 list_for_each(node, &service_list) {
451 svc = node_to_item(node, struct service, slist);
452 if (svc->keychord_id == keychord_id) {
453 return svc;
454 }
455 }
456 return 0;
457}
458
459void service_for_each(void (*func)(struct service *svc))
460{
461 struct listnode *node;
462 struct service *svc;
463 list_for_each(node, &service_list) {
464 svc = node_to_item(node, struct service, slist);
465 func(svc);
466 }
467}
468
443void service_for_each_class(const char *classname, 469void service_for_each_class(const char *classname,
444 void (*func)(struct service *svc)) 470 void (*func)(struct service *svc))
445{ 471{
@@ -586,7 +612,7 @@ static void parse_line_service(struct parse_state *state, int nargs, char **args
586{ 612{
587 struct service *svc = state->context; 613 struct service *svc = state->context;
588 struct command *cmd; 614 struct command *cmd;
589 int kw, kw_nargs; 615 int i, kw, kw_nargs;
590 616
591 if (nargs == 0) { 617 if (nargs == 0) {
592 return; 618 return;
@@ -624,6 +650,21 @@ static void parse_line_service(struct parse_state *state, int nargs, char **args
624 svc->nr_supp_gids = n - 2; 650 svc->nr_supp_gids = n - 2;
625 } 651 }
626 break; 652 break;
653 case K_keycodes:
654 if (nargs < 2) {
655 parse_error(state, "keycodes option requires atleast one keycode\n");
656 } else {
657 svc->keycodes = malloc((nargs - 1) * sizeof(svc->keycodes[0]));
658 if (!svc->keycodes) {
659 parse_error(state, "could not allocate keycodes\n");
660 } else {
661 svc->nkeycodes = nargs - 1;
662 for (i = 1; i < nargs; i++) {
663 svc->keycodes[i - 1] = atoi(args[i]);
664 }
665 }
666 }
667 break;
627 case K_oneshot: 668 case K_oneshot:
628 svc->flags |= SVC_ONESHOT; 669 svc->flags |= SVC_ONESHOT;
629 break; 670 break;