services.c revision 7941cf87f624e7747b5bb868a27904c7a3be0ca4
1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * you may not use this file except in compliance with the License. 6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * You may obtain a copy of the License at 7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * See the License for the specific language governing permissions and 14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * limitations under the License. 15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdlib.h> 18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdio.h> 19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <unistd.h> 20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <string.h> 21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <errno.h> 22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "sysdeps.h" 24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 25408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall#define TRACE_TAG TRACE_SERVICES 26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "adb.h" 27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "file_sync_service.h" 28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_HOST 30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project# ifndef HAVE_WINSOCK 31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project# include <netinet/in.h> 32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project# include <netdb.h> 33408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall# include <sys/ioctl.h> 34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project# endif 35cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood#else 36e3aeeb4de34dbb93e832e6554f494122ba633f3bKen Sumrall# include <cutils/android_reboot.h> 37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttypedef struct stinfo stinfo; 40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct stinfo { 42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project void (*func)(int fd, void *cookie); 43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fd; 44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project void *cookie; 45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}; 46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid *service_bootstrap_func(void *x) 49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project stinfo *sti = x; 51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sti->func(sti->fd, sti->cookie); 52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(sti); 53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_HOST 57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectADB_MUTEX_DEFINE( dns_lock ); 58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void dns_service(int fd, void *cookie) 60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *hostname = cookie; 62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct hostent *hp; 63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned zero = 0; 64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock(&dns_lock); 66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project hp = gethostbyname(hostname); 67b6b40079e6d5b32026cc2abfcb71adfd49e8d954Mike Lockwood free(cookie); 68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(hp == 0) { 69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project writex(fd, &zero, 4); 70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project writex(fd, hp->h_addr, 4); 72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock(&dns_lock); 74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_close(fd); 75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else 77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectextern int recovery_mode; 78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void recover_service(int s, void *cookie) 80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned char buf[4096]; 82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned count = (unsigned) cookie; 83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fd; 84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd = adb_creat("/tmp/update", 0644); 86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(fd < 0) { 87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_close(s); 88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return; 89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while(count > 0) { 92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project unsigned xfer = (count > 4096) ? 4096 : count; 93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(readx(s, buf, xfer)) break; 94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(writex(fd, buf, xfer)) break; 95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project count -= xfer; 96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(count == 0) { 99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project writex(s, "OKAY", 4); 100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project writex(s, "FAIL", 4); 102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_close(fd); 104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_close(s); 105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fd = adb_creat("/tmp/update.begin", 0644); 107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_close(fd); 108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 110e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Projectvoid restart_root_service(int fd, void *cookie) 111e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project{ 112e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project char buf[100]; 113e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project char value[PROPERTY_VALUE_MAX]; 114e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project 115e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project if (getuid() == 0) { 116e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project snprintf(buf, sizeof(buf), "adbd is already running as root\n"); 117e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project writex(fd, buf, strlen(buf)); 118e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project adb_close(fd); 119e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project } else { 120e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project property_get("ro.debuggable", value, ""); 121e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project if (strcmp(value, "1") != 0) { 122e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project snprintf(buf, sizeof(buf), "adbd cannot run as root in production builds\n"); 123e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project writex(fd, buf, strlen(buf)); 124ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood adb_close(fd); 125e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project return; 126e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project } 127e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project 1287941cf87f624e7747b5bb868a27904c7a3be0ca4Benoit Goby property_set("service.adb.root", "1"); 129e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project snprintf(buf, sizeof(buf), "restarting adbd as root\n"); 130e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project writex(fd, buf, strlen(buf)); 131e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project adb_close(fd); 132e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project 1337941cf87f624e7747b5bb868a27904c7a3be0ca4Benoit Goby // quit, and init will restart us as root 1347941cf87f624e7747b5bb868a27904c7a3be0ca4Benoit Goby sleep(1); 1357941cf87f624e7747b5bb868a27904c7a3be0ca4Benoit Goby exit(1); 136e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project } 137e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project} 138e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project 139ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwoodvoid restart_tcp_service(int fd, void *cookie) 140ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood{ 141ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood char buf[100]; 142ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood char value[PROPERTY_VALUE_MAX]; 143ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood int port = (int)cookie; 144ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood 145ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood if (port <= 0) { 146ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood snprintf(buf, sizeof(buf), "invalid port\n"); 147ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood writex(fd, buf, strlen(buf)); 148ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood adb_close(fd); 149ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood return; 150ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood } 151ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood 152ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood snprintf(value, sizeof(value), "%d", port); 153ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood property_set("service.adb.tcp.port", value); 154ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood snprintf(buf, sizeof(buf), "restarting in TCP mode port: %d\n", port); 155ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood writex(fd, buf, strlen(buf)); 156ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood adb_close(fd); 157ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood 158ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood // quit, and init will restart us in TCP mode 159ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood sleep(1); 160ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood exit(1); 161ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood} 162ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood 163ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwoodvoid restart_usb_service(int fd, void *cookie) 164ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood{ 165ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood char buf[100]; 166ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood 167ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood property_set("service.adb.tcp.port", "0"); 168ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood snprintf(buf, sizeof(buf), "restarting in USB mode\n"); 169ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood writex(fd, buf, strlen(buf)); 170ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood adb_close(fd); 171ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood 172ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood // quit, and init will restart us in USB mode 173ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood sleep(1); 174ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood exit(1); 175ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood} 176ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood 177ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwoodvoid reboot_service(int fd, void *arg) 178ee15662140632672a6878787a1ff26f5ebdc1e68Mike Lockwood{ 179ee15662140632672a6878787a1ff26f5ebdc1e68Mike Lockwood char buf[100]; 180d969faa161310d0a3792766320daa3200b84bd74Mike Lockwood int pid, ret; 181ee15662140632672a6878787a1ff26f5ebdc1e68Mike Lockwood 182ee15662140632672a6878787a1ff26f5ebdc1e68Mike Lockwood sync(); 183d969faa161310d0a3792766320daa3200b84bd74Mike Lockwood 184d969faa161310d0a3792766320daa3200b84bd74Mike Lockwood /* Attempt to unmount the SD card first. 185d969faa161310d0a3792766320daa3200b84bd74Mike Lockwood * No need to bother checking for errors. 186d969faa161310d0a3792766320daa3200b84bd74Mike Lockwood */ 187d969faa161310d0a3792766320daa3200b84bd74Mike Lockwood pid = fork(); 188d969faa161310d0a3792766320daa3200b84bd74Mike Lockwood if (pid == 0) { 189d969faa161310d0a3792766320daa3200b84bd74Mike Lockwood /* ask vdc to unmount it */ 190d969faa161310d0a3792766320daa3200b84bd74Mike Lockwood execl("/system/bin/vdc", "/system/bin/vdc", "volume", "unmount", 191d969faa161310d0a3792766320daa3200b84bd74Mike Lockwood getenv("EXTERNAL_STORAGE"), "force", NULL); 192d969faa161310d0a3792766320daa3200b84bd74Mike Lockwood } else if (pid > 0) { 193d969faa161310d0a3792766320daa3200b84bd74Mike Lockwood /* wait until vdc succeeds or fails */ 194d969faa161310d0a3792766320daa3200b84bd74Mike Lockwood waitpid(pid, &ret, 0); 195d969faa161310d0a3792766320daa3200b84bd74Mike Lockwood } 196d969faa161310d0a3792766320daa3200b84bd74Mike Lockwood 197e3aeeb4de34dbb93e832e6554f494122ba633f3bKen Sumrall ret = android_reboot(ANDROID_RB_RESTART2, 0, (char *) arg); 198ee15662140632672a6878787a1ff26f5ebdc1e68Mike Lockwood if (ret < 0) { 199ee15662140632672a6878787a1ff26f5ebdc1e68Mike Lockwood snprintf(buf, sizeof(buf), "reboot failed: %s\n", strerror(errno)); 200ee15662140632672a6878787a1ff26f5ebdc1e68Mike Lockwood writex(fd, buf, strlen(buf)); 201ee15662140632672a6878787a1ff26f5ebdc1e68Mike Lockwood } 202b6b40079e6d5b32026cc2abfcb71adfd49e8d954Mike Lockwood free(arg); 203ee15662140632672a6878787a1ff26f5ebdc1e68Mike Lockwood adb_close(fd); 204ee15662140632672a6878787a1ff26f5ebdc1e68Mike Lockwood} 205ee15662140632672a6878787a1ff26f5ebdc1e68Mike Lockwood 206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if 0 209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void echo_service(int fd, void *cookie) 210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char buf[4096]; 212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int r; 213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *p; 214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int c; 215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project for(;;) { 217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project r = read(fd, buf, 4096); 218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(r == 0) goto done; 219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(r < 0) { 220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(errno == EINTR) continue; 221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else goto done; 222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project c = r; 225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p = buf; 226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project while(c > 0) { 227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project r = write(fd, p, c); 228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(r > 0) { 229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project c -= r; 230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project p += r; 231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project continue; 232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if((r < 0) && (errno == EINTR)) continue; 234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project goto done; 235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectdone: 238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close(fd); 239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int create_service_thread(void (*func)(int, void *), void *cookie) 243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project stinfo *sti; 245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_thread_t t; 246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int s[2]; 247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(adb_socketpair(s)) { 249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project printf("cannot create service socket pair\n"); 250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sti = malloc(sizeof(stinfo)); 254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(sti == 0) fatal("cannot allocate stinfo"); 255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sti->func = func; 256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sti->cookie = cookie; 257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sti->fd = s[1]; 258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(adb_thread_create( &t, service_bootstrap_func, sti)){ 260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(sti); 261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_close(s[0]); 262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_close(s[1]); 263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project printf("cannot create service thread\n"); 264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("service thread started, %d:%d\n",s[0], s[1]); 268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return s[0]; 269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 271408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall#if !ADB_HOST 272408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrallstatic int create_subprocess(const char *cmd, const char *arg0, const char *arg1, pid_t *pid) 273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 27491acb14877e7138879057f794a61ee2fd424a41dJoe Onorato#ifdef HAVE_WIN32_PROC 275408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall D("create_subprocess(cmd=%s, arg0=%s, arg1=%s)\n", cmd, arg0, arg1); 276408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall fprintf(stderr, "error: create_subprocess not implemented on Win32 (%s %s %s)\n", cmd, arg0, arg1); 277408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall return -1; 27891acb14877e7138879057f794a61ee2fd424a41dJoe Onorato#else /* !HAVE_WIN32_PROC */ 279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *devname; 280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int ptm; 281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ptm = unix_open("/dev/ptmx", O_RDWR); // | O_NOCTTY); 283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(ptm < 0){ 284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project printf("[ cannot open /dev/ptmx - %s ]\n",strerror(errno)); 285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project fcntl(ptm, F_SETFD, FD_CLOEXEC); 288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(grantpt(ptm) || unlockpt(ptm) || 290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ((devname = (char*) ptsname(ptm)) == 0)){ 291dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project printf("[ trouble with /dev/ptmx - %s ]\n", strerror(errno)); 292408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall adb_close(ptm); 293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 296408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall *pid = fork(); 297408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall if(*pid < 0) { 298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project printf("- fork failed: %s -\n", strerror(errno)); 299408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall adb_close(ptm); 300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 303408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall if(*pid == 0){ 304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int pts; 305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project setsid(); 307dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 308dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project pts = unix_open(devname, O_RDWR); 309408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall if(pts < 0) { 310408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall fprintf(stderr, "child failed to open pseudo-term slave: %s\n", devname); 311408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall exit(-1); 312408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall } 313dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 314dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dup2(pts, 0); 315dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dup2(pts, 1); 316dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project dup2(pts, 2); 317dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 31895ef82866c7a922bf588027aa38c58a45eb84d9cBenoit Goby adb_close(pts); 319dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_close(ptm); 320dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 321408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall // set OOM adjustment to zero 322249ad57a887680538d1dc0195e746b1d877ebd6aMike Lockwood char text[64]; 323408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall snprintf(text, sizeof text, "/proc/%d/oom_adj", getpid()); 324249ad57a887680538d1dc0195e746b1d877ebd6aMike Lockwood int fd = adb_open(text, O_WRONLY); 325249ad57a887680538d1dc0195e746b1d877ebd6aMike Lockwood if (fd >= 0) { 326249ad57a887680538d1dc0195e746b1d877ebd6aMike Lockwood adb_write(fd, "0", 1); 327249ad57a887680538d1dc0195e746b1d877ebd6aMike Lockwood adb_close(fd); 328249ad57a887680538d1dc0195e746b1d877ebd6aMike Lockwood } else { 329249ad57a887680538d1dc0195e746b1d877ebd6aMike Lockwood D("adb: unable to open %s\n", text); 330249ad57a887680538d1dc0195e746b1d877ebd6aMike Lockwood } 331408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall execl(cmd, cmd, arg0, arg1, NULL); 332408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall fprintf(stderr, "- exec '%s' failed: %s (%d) -\n", 333408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall cmd, strerror(errno), errno); 334408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall exit(-1); 335408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall } else { 336408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall // Don't set child's OOM adjustment to zero. 337408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall // Let the child do it itself, as sometimes the parent starts 338408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall // running before the child has a /proc/pid/oom_adj. 339408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall // """adb: unable to open /proc/644/oom_adj""" seen in some logs. 340dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return ptm; 341dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 34291acb14877e7138879057f794a61ee2fd424a41dJoe Onorato#endif /* !HAVE_WIN32_PROC */ 343dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 344408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall#endif /* !ABD_HOST */ 345dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 346dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_HOST 347dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define SHELL_COMMAND "/bin/sh" 348dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else 349dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define SHELL_COMMAND "/system/bin/sh" 350dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 351dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 352408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall#if !ADB_HOST 353408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrallstatic void subproc_waiter_service(int fd, void *cookie) 354408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall{ 355408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall pid_t pid = (pid_t)cookie; 356408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall 357408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall D("entered. fd=%d of pid=%d\n", fd, pid); 358408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall for (;;) { 359408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall int status; 360408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall pid_t p = waitpid(pid, &status, 0); 361408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall if (p == pid) { 362408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall D("fd=%d, post waitpid(pid=%d) status=%04x\n", fd, p, status); 363408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall if (WIFSIGNALED(status)) { 364408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall D("*** Killed by signal %d\n", WTERMSIG(status)); 365408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall break; 366408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall } else if (!WIFEXITED(status)) { 367408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall D("*** Didn't exit!!. status %d\n", status); 368408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall break; 369408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall } else if (WEXITSTATUS(status) >= 0) { 370408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall D("*** Exit code %d\n", WEXITSTATUS(status)); 371408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall break; 372408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall } 373408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall } 374408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall usleep(100000); // poll every 0.1 sec 375408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall } 376408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall D("shell exited fd=%d of pid=%d err=%d\n", fd, pid, errno); 377408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall if (SHELL_EXIT_NOTIFY_FD >=0) { 378408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall int res; 379408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall res = writex(SHELL_EXIT_NOTIFY_FD, &fd, sizeof(fd)); 380408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall D("notified shell exit via fd=%d for pid=%d res=%d errno=%d\n", 381408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall SHELL_EXIT_NOTIFY_FD, pid, res, errno); 382408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall } 383408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall} 384408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall 385408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrallstatic int create_subproc_thread(const char *name) 386408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall{ 387408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall stinfo *sti; 388408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall adb_thread_t t; 389408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall int ret_fd; 390408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall pid_t pid; 391408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall if(name) { 392408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall ret_fd = create_subprocess(SHELL_COMMAND, "-c", name, &pid); 393408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall } else { 394408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall ret_fd = create_subprocess(SHELL_COMMAND, "-", 0, &pid); 395408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall } 396408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall D("create_subprocess() ret_fd=%d pid=%d\n", ret_fd, pid); 397408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall 398408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall sti = malloc(sizeof(stinfo)); 399408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall if(sti == 0) fatal("cannot allocate stinfo"); 400408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall sti->func = subproc_waiter_service; 401408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall sti->cookie = (void*)pid; 402408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall sti->fd = ret_fd; 403408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall 404408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall if(adb_thread_create( &t, service_bootstrap_func, sti)){ 405408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall free(sti); 406408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall adb_close(ret_fd); 407408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall printf("cannot create service thread\n"); 408408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall return -1; 409408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall } 410408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall 411408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall D("service thread started, fd=%d pid=%d\n",ret_fd, pid); 412408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall return ret_fd; 413408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall} 414408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall#endif 415408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall 416dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint service_to_fd(const char *name) 417dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 418dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int ret = -1; 419dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 420dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(!strncmp(name, "tcp:", 4)) { 421dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int port = atoi(name + 4); 422dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project name = strchr(name + 4, ':'); 423dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(name == 0) { 424dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret = socket_loopback_client(port, SOCK_STREAM); 425dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ret >= 0) 426dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project disable_tcp_nagle(ret); 427dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 428dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_HOST 429dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_lock(&dns_lock); 430dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret = socket_network_client(name + 1, port, SOCK_STREAM); 431dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_mutex_unlock(&dns_lock); 432dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else 433dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 434dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 435dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 436dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifndef HAVE_WINSOCK /* winsock doesn't implement unix domain sockets */ 437dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if(!strncmp(name, "local:", 6)) { 438dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret = socket_local_client(name + 6, 439dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM); 440dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if(!strncmp(name, "localreserved:", 14)) { 441dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret = socket_local_client(name + 14, 442dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM); 443dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if(!strncmp(name, "localabstract:", 14)) { 444dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret = socket_local_client(name + 14, 445dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM); 446dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if(!strncmp(name, "localfilesystem:", 16)) { 447dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret = socket_local_client(name + 16, 448dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ANDROID_SOCKET_NAMESPACE_FILESYSTEM, SOCK_STREAM); 449dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 450dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_HOST 451dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if(!strncmp("dns:", name, 4)){ 452dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char *n = strdup(name + 4); 453dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(n == 0) return -1; 454dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret = create_service_thread(dns_service, n); 455dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else /* !ADB_HOST */ 456dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if(!strncmp("dev:", name, 4)) { 457dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret = unix_open(name + 4, O_RDWR); 458dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if(!strncmp(name, "framebuffer:", 12)) { 459dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret = create_service_thread(framebuffer_service, 0); 460dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if(recovery_mode && !strncmp(name, "recover:", 8)) { 461dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret = create_service_thread(recover_service, (void*) atoi(name + 8)); 462dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (!strncmp(name, "jdwp:", 5)) { 463dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret = create_jdwp_connection_fd(atoi(name+5)); 464dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (!strncmp(name, "log:", 4)) { 465dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret = create_service_thread(log_service, get_log_file_path(name + 4)); 466dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if(!HOST && !strncmp(name, "shell:", 6)) { 467dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(name[6]) { 468408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall ret = create_subproc_thread(name + 6); 469dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 470408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall ret = create_subproc_thread(0); 471dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 472dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if(!strncmp(name, "sync:", 5)) { 473dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret = create_service_thread(file_sync_service, NULL); 474dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if(!strncmp(name, "remount:", 8)) { 475dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret = create_service_thread(remount_service, NULL); 476ee15662140632672a6878787a1ff26f5ebdc1e68Mike Lockwood } else if(!strncmp(name, "reboot:", 7)) { 477b6b40079e6d5b32026cc2abfcb71adfd49e8d954Mike Lockwood void* arg = strdup(name + 7); 478b6b40079e6d5b32026cc2abfcb71adfd49e8d954Mike Lockwood if(arg == 0) return -1; 479b6b40079e6d5b32026cc2abfcb71adfd49e8d954Mike Lockwood ret = create_service_thread(reboot_service, arg); 480e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project } else if(!strncmp(name, "root:", 5)) { 481e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project ret = create_service_thread(restart_root_service, NULL); 482d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate } else if(!strncmp(name, "backup:", 7)) { 483d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate char* arg = strdup(name+7); 484d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate if (arg == NULL) return -1; 485702967afb1bebc97c0b8a23c075d4932820ef7a3Christopher Tate ret = backup_service(BACKUP, arg); 486702967afb1bebc97c0b8a23c075d4932820ef7a3Christopher Tate } else if(!strncmp(name, "restore:", 8)) { 487702967afb1bebc97c0b8a23c075d4932820ef7a3Christopher Tate ret = backup_service(RESTORE, NULL); 488ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood } else if(!strncmp(name, "tcpip:", 6)) { 489ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood int port; 490ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood if (sscanf(name + 6, "%d", &port) == 0) { 491ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood port = 0; 492ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood } 493ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood ret = create_service_thread(restart_tcp_service, (void *)port); 494ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood } else if(!strncmp(name, "usb:", 4)) { 495ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood ret = create_service_thread(restart_usb_service, NULL); 496dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 497dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if 0 498dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if(!strncmp(name, "echo:", 5)){ 499dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret = create_service_thread(echo_service, 0); 500dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 501dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 502dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ret >= 0) { 503dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close_on_exec(ret); 504dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 505dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return ret; 506dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 507dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 508dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_HOST 509dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct state_info { 510dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project transport_type transport; 511dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char* serial; 512dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int state; 513dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}; 514dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 515dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void wait_for_state(int fd, void* cookie) 516dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 517dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct state_info* sinfo = cookie; 518dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char* err = "unknown error"; 519dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 520dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("wait_for_state %d\n", sinfo->state); 521dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 522dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project atransport *t = acquire_one_transport(sinfo->state, sinfo->transport, sinfo->serial, &err); 523dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(t != 0) { 524dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project writex(fd, "OKAY", 4); 525dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 526dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sendfailmsg(fd, err); 527dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 528dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 529dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (sinfo->serial) 530dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(sinfo->serial); 531dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(sinfo); 532dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_close(fd); 533dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("wait_for_state is done\n"); 534dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 535dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 536dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 537dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_HOST 538dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectasocket* host_service_to_socket(const char* name, const char *serial) 539dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 540dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!strcmp(name,"track-devices")) { 541dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return create_device_tracker(); 542dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (!strncmp(name, "wait-for-", strlen("wait-for-"))) { 543dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct state_info* sinfo = malloc(sizeof(struct state_info)); 544dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 545dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (serial) 546dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sinfo->serial = strdup(serial); 547dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else 548dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sinfo->serial = NULL; 549dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 550dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project name += strlen("wait-for-"); 551dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 552dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!strncmp(name, "local", strlen("local"))) { 553dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sinfo->transport = kTransportLocal; 554dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sinfo->state = CS_DEVICE; 555dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (!strncmp(name, "usb", strlen("usb"))) { 556dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sinfo->transport = kTransportUsb; 557dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sinfo->state = CS_DEVICE; 558dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (!strncmp(name, "any", strlen("any"))) { 559dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sinfo->transport = kTransportAny; 560dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sinfo->state = CS_DEVICE; 561dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 562dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(sinfo); 563dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return NULL; 564dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 565dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 566dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fd = create_service_thread(wait_for_state, sinfo); 567dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return create_local_socket(fd); 568dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 569dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return NULL; 570dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 571dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif /* ADB_HOST */ 572