1 /* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <stdlib.h> 18 #include <stdio.h> 19 #include <unistd.h> 20 #include <string.h> 21 #include <errno.h> 22 23 #include "sysdeps.h" 24 #include "fdevent.h" 25 26 #define TRACE_TAG TRACE_SERVICES 27 #include "adb.h" 28 29 typedef struct stinfo stinfo; 30 31 struct stinfo { 32 void (*func)(int fd, void *cookie); 33 int fd; 34 void *cookie; 35 }; 36 37 38 void *service_bootstrap_func(void *x) 39 { 40 stinfo *sti = x; 41 sti->func(sti->fd, sti->cookie); 42 free(sti); 43 return 0; 44 } 45 46 static void sideload_service(int s, void *cookie) 47 { 48 unsigned char buf[4096]; 49 unsigned count = (unsigned) cookie; 50 int fd; 51 52 fprintf(stderr, "sideload_service invoked\n"); 53 54 fd = adb_creat(ADB_SIDELOAD_FILENAME, 0644); 55 if(fd < 0) { 56 fprintf(stderr, "failed to create %s\n", ADB_SIDELOAD_FILENAME); 57 adb_close(s); 58 return; 59 } 60 61 while(count > 0) { 62 unsigned xfer = (count > 4096) ? 4096 : count; 63 if(readx(s, buf, xfer)) break; 64 if(writex(fd, buf, xfer)) break; 65 count -= xfer; 66 } 67 68 if(count == 0) { 69 writex(s, "OKAY", 4); 70 } else { 71 writex(s, "FAIL", 4); 72 } 73 adb_close(fd); 74 adb_close(s); 75 76 if (count == 0) { 77 fprintf(stderr, "adbd exiting after successful sideload\n"); 78 sleep(1); 79 exit(0); 80 } 81 } 82 83 84 #if 0 85 static void echo_service(int fd, void *cookie) 86 { 87 char buf[4096]; 88 int r; 89 char *p; 90 int c; 91 92 for(;;) { 93 r = read(fd, buf, 4096); 94 if(r == 0) goto done; 95 if(r < 0) { 96 if(errno == EINTR) continue; 97 else goto done; 98 } 99 100 c = r; 101 p = buf; 102 while(c > 0) { 103 r = write(fd, p, c); 104 if(r > 0) { 105 c -= r; 106 p += r; 107 continue; 108 } 109 if((r < 0) && (errno == EINTR)) continue; 110 goto done; 111 } 112 } 113 done: 114 close(fd); 115 } 116 #endif 117 118 static int create_service_thread(void (*func)(int, void *), void *cookie) 119 { 120 stinfo *sti; 121 adb_thread_t t; 122 int s[2]; 123 124 if(adb_socketpair(s)) { 125 printf("cannot create service socket pair\n"); 126 return -1; 127 } 128 129 sti = malloc(sizeof(stinfo)); 130 if(sti == 0) fatal("cannot allocate stinfo"); 131 sti->func = func; 132 sti->cookie = cookie; 133 sti->fd = s[1]; 134 135 if(adb_thread_create( &t, service_bootstrap_func, sti)){ 136 free(sti); 137 adb_close(s[0]); 138 adb_close(s[1]); 139 printf("cannot create service thread\n"); 140 return -1; 141 } 142 143 D("service thread started, %d:%d\n",s[0], s[1]); 144 return s[0]; 145 } 146 147 int service_to_fd(const char *name) 148 { 149 int ret = -1; 150 151 if (!strncmp(name, "sideload:", 9)) { 152 ret = create_service_thread(sideload_service, (void*) atoi(name + 9)); 153 #if 0 154 } else if(!strncmp(name, "echo:", 5)){ 155 ret = create_service_thread(echo_service, 0); 156 #endif 157 } 158 if (ret >= 0) { 159 close_on_exec(ret); 160 } 161 return ret; 162 } 163