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 171c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby#include <stddef.h> 18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdlib.h> 19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdio.h> 20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <unistd.h> 21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <string.h> 22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <errno.h> 23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "sysdeps.h" 25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 26408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall#define TRACE_TAG TRACE_SERVICES 27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "adb.h" 28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "file_sync_service.h" 29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_HOST 31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project# ifndef HAVE_WINSOCK 32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project# include <netinet/in.h> 33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project# include <netdb.h> 34408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall# include <sys/ioctl.h> 35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project# endif 36cc1de48dcdf06c76ee14abbe2a237aa51b5b3badMike Lockwood#else 37e3aeeb4de34dbb93e832e6554f494122ba633f3bKen Sumrall# include <cutils/android_reboot.h> 38893a4a47e8c9290128b9254af0246e36f821c260Nick Kralevich# include <cutils/properties.h> 39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttypedef struct stinfo stinfo; 42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct stinfo { 44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project void (*func)(int fd, void *cookie); 45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fd; 46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project void *cookie; 47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}; 48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid *service_bootstrap_func(void *x) 51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project stinfo *sti = x; 53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sti->func(sti->fd, sti->cookie); 54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(sti); 55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 589470c2f1ab555311633d52e5ed8303a813061cdfBenoit Goby#if !ADB_HOST 59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 60e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Projectvoid restart_root_service(int fd, void *cookie) 61e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project{ 62e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project char buf[100]; 63e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project char value[PROPERTY_VALUE_MAX]; 64e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project 65e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project if (getuid() == 0) { 66e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project snprintf(buf, sizeof(buf), "adbd is already running as root\n"); 67e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project writex(fd, buf, strlen(buf)); 68e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project adb_close(fd); 69e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project } else { 70e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project property_get("ro.debuggable", value, ""); 71e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project if (strcmp(value, "1") != 0) { 72e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project snprintf(buf, sizeof(buf), "adbd cannot run as root in production builds\n"); 73e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project writex(fd, buf, strlen(buf)); 74ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood adb_close(fd); 75e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project return; 76e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project } 77e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project 787941cf87f624e7747b5bb868a27904c7a3be0ca4Benoit Goby property_set("service.adb.root", "1"); 79e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project snprintf(buf, sizeof(buf), "restarting adbd as root\n"); 80e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project writex(fd, buf, strlen(buf)); 81e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project adb_close(fd); 82e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project } 83e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project} 84e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project 85ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwoodvoid restart_tcp_service(int fd, void *cookie) 86ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood{ 87ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood char buf[100]; 88ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood char value[PROPERTY_VALUE_MAX]; 89ccecf1425412beb2bc3bb38d470293fdc244d6f1Elliott Hughes int port = (int) (uintptr_t) cookie; 90ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood 91ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood if (port <= 0) { 92ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood snprintf(buf, sizeof(buf), "invalid port\n"); 93ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood writex(fd, buf, strlen(buf)); 94ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood adb_close(fd); 95ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood return; 96ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood } 97ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood 98ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood snprintf(value, sizeof(value), "%d", port); 99ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood property_set("service.adb.tcp.port", value); 100ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood snprintf(buf, sizeof(buf), "restarting in TCP mode port: %d\n", port); 101ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood writex(fd, buf, strlen(buf)); 102ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood adb_close(fd); 103ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood} 104ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood 105ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwoodvoid restart_usb_service(int fd, void *cookie) 106ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood{ 107ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood char buf[100]; 108ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood 109ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood property_set("service.adb.tcp.port", "0"); 110ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood snprintf(buf, sizeof(buf), "restarting in USB mode\n"); 111ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood writex(fd, buf, strlen(buf)); 112ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood adb_close(fd); 113ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood} 114ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood 115ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwoodvoid reboot_service(int fd, void *arg) 116ee15662140632672a6878787a1ff26f5ebdc1e68Mike Lockwood{ 117ee15662140632672a6878787a1ff26f5ebdc1e68Mike Lockwood char buf[100]; 118ca8e66a8b0f843812014a28d49208f9f6f64ecbcNick Kralevich char property_val[PROPERTY_VALUE_MAX]; 11902916aa20e3ffbe4b738bb12dc1607a7ec6a8c37Nick Kralevich int ret; 120ee15662140632672a6878787a1ff26f5ebdc1e68Mike Lockwood 121ee15662140632672a6878787a1ff26f5ebdc1e68Mike Lockwood sync(); 122d969faa161310d0a3792766320daa3200b84bd74Mike Lockwood 123ca8e66a8b0f843812014a28d49208f9f6f64ecbcNick Kralevich ret = snprintf(property_val, sizeof(property_val), "reboot,%s", (char *) arg); 124ca8e66a8b0f843812014a28d49208f9f6f64ecbcNick Kralevich if (ret >= (int) sizeof(property_val)) { 125ca8e66a8b0f843812014a28d49208f9f6f64ecbcNick Kralevich snprintf(buf, sizeof(buf), "reboot string too long. length=%d\n", ret); 126ca8e66a8b0f843812014a28d49208f9f6f64ecbcNick Kralevich writex(fd, buf, strlen(buf)); 127ca8e66a8b0f843812014a28d49208f9f6f64ecbcNick Kralevich goto cleanup; 128ca8e66a8b0f843812014a28d49208f9f6f64ecbcNick Kralevich } 129ca8e66a8b0f843812014a28d49208f9f6f64ecbcNick Kralevich 130ca8e66a8b0f843812014a28d49208f9f6f64ecbcNick Kralevich ret = property_set(ANDROID_RB_PROPERTY, property_val); 131ee15662140632672a6878787a1ff26f5ebdc1e68Mike Lockwood if (ret < 0) { 132ca8e66a8b0f843812014a28d49208f9f6f64ecbcNick Kralevich snprintf(buf, sizeof(buf), "reboot failed: %d\n", ret); 133ee15662140632672a6878787a1ff26f5ebdc1e68Mike Lockwood writex(fd, buf, strlen(buf)); 134917045222a69021eb36aea96708649c709685509Nick Kralevich goto cleanup; 135ee15662140632672a6878787a1ff26f5ebdc1e68Mike Lockwood } 136917045222a69021eb36aea96708649c709685509Nick Kralevich // Don't return early. Give the reboot command time to take effect 137917045222a69021eb36aea96708649c709685509Nick Kralevich // to avoid messing up scripts which do "adb reboot && adb wait-for-device" 138917045222a69021eb36aea96708649c709685509Nick Kralevich while(1) { pause(); } 139ca8e66a8b0f843812014a28d49208f9f6f64ecbcNick Kralevichcleanup: 140b6b40079e6d5b32026cc2abfcb71adfd49e8d954Mike Lockwood free(arg); 141ee15662140632672a6878787a1ff26f5ebdc1e68Mike Lockwood adb_close(fd); 142ee15662140632672a6878787a1ff26f5ebdc1e68Mike Lockwood} 143ee15662140632672a6878787a1ff26f5ebdc1e68Mike Lockwood 144252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turnervoid reverse_service(int fd, void* arg) 145252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner{ 146252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner const char* command = arg; 147252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner 148252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner if (handle_forward_request(command, kTransportAny, NULL, fd) < 0) { 149252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner sendfailmsg(fd, "not a reverse forwarding command"); 150252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner } 151252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner free(arg); 152252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner adb_close(fd); 153252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner} 154252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner 155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int create_service_thread(void (*func)(int, void *), void *cookie) 158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project stinfo *sti; 160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_thread_t t; 161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int s[2]; 162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(adb_socketpair(s)) { 164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project printf("cannot create service socket pair\n"); 165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sti = malloc(sizeof(stinfo)); 169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(sti == 0) fatal("cannot allocate stinfo"); 170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sti->func = func; 171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sti->cookie = cookie; 172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sti->fd = s[1]; 173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(adb_thread_create( &t, service_bootstrap_func, sti)){ 175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(sti); 176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_close(s[0]); 177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_close(s[1]); 178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project printf("cannot create service thread\n"); 179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("service thread started, %d:%d\n",s[0], s[1]); 183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return s[0]; 184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 186408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall#if !ADB_HOST 1875d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey 1885d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkeystatic void init_subproc_child() 1895d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey{ 1905d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey setsid(); 1915d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey 19207ce7cab72d9b3e5c701491daf8fd457d035eec8Rom Lemarchand // Set OOM score adjustment to prevent killing 193fe8d7f4f2e775d46d61f7c2d29a4e852434984daNick Kralevich int fd = adb_open("/proc/self/oom_score_adj", O_WRONLY | O_CLOEXEC); 1945d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey if (fd >= 0) { 1955d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey adb_write(fd, "0", 1); 1965d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey adb_close(fd); 1975d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey } else { 19807ce7cab72d9b3e5c701491daf8fd457d035eec8Rom Lemarchand D("adb: unable to update oom_score_adj\n"); 1995d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey } 2005d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey} 2015d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey 2025d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkeystatic int create_subproc_pty(const char *cmd, const char *arg0, const char *arg1, pid_t *pid) 203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 2045d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey D("create_subproc_pty(cmd=%s, arg0=%s, arg1=%s)\n", cmd, arg0, arg1); 20591acb14877e7138879057f794a61ee2fd424a41dJoe Onorato#ifdef HAVE_WIN32_PROC 2065d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey fprintf(stderr, "error: create_subproc_pty not implemented on Win32 (%s %s %s)\n", cmd, arg0, arg1); 207408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall return -1; 20891acb14877e7138879057f794a61ee2fd424a41dJoe Onorato#else /* !HAVE_WIN32_PROC */ 209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int ptm; 210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 211fe8d7f4f2e775d46d61f7c2d29a4e852434984daNick Kralevich ptm = unix_open("/dev/ptmx", O_RDWR | O_CLOEXEC); // | O_NOCTTY); 212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(ptm < 0){ 213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project printf("[ cannot open /dev/ptmx - %s ]\n",strerror(errno)); 214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 217a6ff5c95a3fa798d661e09aa628cd0c5e5c8608fElliott Hughes char devname[64]; 218a6ff5c95a3fa798d661e09aa628cd0c5e5c8608fElliott Hughes if(grantpt(ptm) || unlockpt(ptm) || ptsname_r(ptm, devname, sizeof(devname)) != 0) { 219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project printf("[ trouble with /dev/ptmx - %s ]\n", strerror(errno)); 220408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall adb_close(ptm); 221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 224408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall *pid = fork(); 225408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall if(*pid < 0) { 226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project printf("- fork failed: %s -\n", strerror(errno)); 227408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall adb_close(ptm); 228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 2315d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey if (*pid == 0) { 2325d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey init_subproc_child(); 233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 234fe8d7f4f2e775d46d61f7c2d29a4e852434984daNick Kralevich int pts = unix_open(devname, O_RDWR | O_CLOEXEC); 2355d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey if (pts < 0) { 236408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall fprintf(stderr, "child failed to open pseudo-term slave: %s\n", devname); 237408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall exit(-1); 238408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall } 239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 2405d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey dup2(pts, STDIN_FILENO); 2415d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey dup2(pts, STDOUT_FILENO); 2425d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey dup2(pts, STDERR_FILENO); 243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 24495ef82866c7a922bf588027aa38c58a45eb84d9cBenoit Goby adb_close(pts); 245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_close(ptm); 246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 247408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall execl(cmd, cmd, arg0, arg1, NULL); 248408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall fprintf(stderr, "- exec '%s' failed: %s (%d) -\n", 249408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall cmd, strerror(errno), errno); 250408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall exit(-1); 251408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall } else { 252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return ptm; 253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 25491acb14877e7138879057f794a61ee2fd424a41dJoe Onorato#endif /* !HAVE_WIN32_PROC */ 255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 2565d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey 2575d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkeystatic int create_subproc_raw(const char *cmd, const char *arg0, const char *arg1, pid_t *pid) 2585d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey{ 2595d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey D("create_subproc_raw(cmd=%s, arg0=%s, arg1=%s)\n", cmd, arg0, arg1); 2605d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey#ifdef HAVE_WIN32_PROC 2615d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey fprintf(stderr, "error: create_subproc_raw not implemented on Win32 (%s %s %s)\n", cmd, arg0, arg1); 2625d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey return -1; 2635d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey#else /* !HAVE_WIN32_PROC */ 2645d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey 2655d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey // 0 is parent socket, 1 is child socket 2665d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey int sv[2]; 2675d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey if (unix_socketpair(AF_UNIX, SOCK_STREAM, 0, sv) < 0) { 2685d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey printf("[ cannot create socket pair - %s ]\n", strerror(errno)); 2695d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey return -1; 2705d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey } 2715d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey 2725d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey *pid = fork(); 2735d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey if (*pid < 0) { 2745d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey printf("- fork failed: %s -\n", strerror(errno)); 2755d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey adb_close(sv[0]); 2765d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey adb_close(sv[1]); 2775d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey return -1; 2785d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey } 2795d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey 2805d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey if (*pid == 0) { 2815d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey adb_close(sv[0]); 2825d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey init_subproc_child(); 2835d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey 2845d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey dup2(sv[1], STDIN_FILENO); 2855d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey dup2(sv[1], STDOUT_FILENO); 286960df97c2356f5a804d3ef87fe49f788d7ecdfafJeff Sharkey dup2(sv[1], STDERR_FILENO); 287960df97c2356f5a804d3ef87fe49f788d7ecdfafJeff Sharkey 2885d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey adb_close(sv[1]); 2895d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey 2905d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey execl(cmd, cmd, arg0, arg1, NULL); 2915d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey fprintf(stderr, "- exec '%s' failed: %s (%d) -\n", 2925d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey cmd, strerror(errno), errno); 2935d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey exit(-1); 2945d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey } else { 2955d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey adb_close(sv[1]); 2965d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey return sv[0]; 2975d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey } 2985d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey#endif /* !HAVE_WIN32_PROC */ 2995d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey} 300408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall#endif /* !ABD_HOST */ 301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_HOST 303dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define SHELL_COMMAND "/bin/sh" 304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else 305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define SHELL_COMMAND "/system/bin/sh" 306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 307dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 308408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall#if !ADB_HOST 309408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrallstatic void subproc_waiter_service(int fd, void *cookie) 310408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall{ 311ccecf1425412beb2bc3bb38d470293fdc244d6f1Elliott Hughes pid_t pid = (pid_t) (uintptr_t) cookie; 312408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall 313408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall D("entered. fd=%d of pid=%d\n", fd, pid); 314408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall for (;;) { 315408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall int status; 316408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall pid_t p = waitpid(pid, &status, 0); 317408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall if (p == pid) { 318408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall D("fd=%d, post waitpid(pid=%d) status=%04x\n", fd, p, status); 319408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall if (WIFSIGNALED(status)) { 320408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall D("*** Killed by signal %d\n", WTERMSIG(status)); 321408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall break; 322408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall } else if (!WIFEXITED(status)) { 323408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall D("*** Didn't exit!!. status %d\n", status); 324408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall break; 325408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall } else if (WEXITSTATUS(status) >= 0) { 326408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall D("*** Exit code %d\n", WEXITSTATUS(status)); 327408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall break; 328408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall } 329408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall } 330408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall } 331408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall D("shell exited fd=%d of pid=%d err=%d\n", fd, pid, errno); 332408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall if (SHELL_EXIT_NOTIFY_FD >=0) { 333408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall int res; 334408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall res = writex(SHELL_EXIT_NOTIFY_FD, &fd, sizeof(fd)); 335408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall D("notified shell exit via fd=%d for pid=%d res=%d errno=%d\n", 336408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall SHELL_EXIT_NOTIFY_FD, pid, res, errno); 337408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall } 338408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall} 339408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall 3405d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkeystatic int create_subproc_thread(const char *name, const subproc_mode mode) 341408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall{ 342408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall stinfo *sti; 343408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall adb_thread_t t; 344408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall int ret_fd; 3455d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey pid_t pid = -1; 3465d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey 3475d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey const char *arg0, *arg1; 3485d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey if (name == 0 || *name == 0) { 3495d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey arg0 = "-"; arg1 = 0; 350408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall } else { 3515d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey arg0 = "-c"; arg1 = name; 3525d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey } 3535d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey 3545d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey switch (mode) { 3555d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey case SUBPROC_PTY: 3565d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey ret_fd = create_subproc_pty(SHELL_COMMAND, arg0, arg1, &pid); 3575d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey break; 3585d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey case SUBPROC_RAW: 3595d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey ret_fd = create_subproc_raw(SHELL_COMMAND, arg0, arg1, &pid); 3605d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey break; 3615d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey default: 3625d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey fprintf(stderr, "invalid subproc_mode %d\n", mode); 3635d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey return -1; 364408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall } 3655d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey D("create_subproc ret_fd=%d pid=%d\n", ret_fd, pid); 366408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall 367408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall sti = malloc(sizeof(stinfo)); 368408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall if(sti == 0) fatal("cannot allocate stinfo"); 369408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall sti->func = subproc_waiter_service; 370ccecf1425412beb2bc3bb38d470293fdc244d6f1Elliott Hughes sti->cookie = (void*) (uintptr_t) pid; 371408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall sti->fd = ret_fd; 372408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall 3735d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey if (adb_thread_create(&t, service_bootstrap_func, sti)) { 374408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall free(sti); 375408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall adb_close(ret_fd); 3765d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey fprintf(stderr, "cannot create service thread\n"); 377408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall return -1; 378408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall } 379408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall 3805d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey D("service thread started, fd=%d pid=%d\n", ret_fd, pid); 381408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall return ret_fd; 382408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall} 383408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall#endif 384408fa57864c01113deaa213e5c1848a9c594ae92JP Abgrall 385dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint service_to_fd(const char *name) 386dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 387dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int ret = -1; 388dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 389dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(!strncmp(name, "tcp:", 4)) { 390dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int port = atoi(name + 4); 391dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project name = strchr(name + 4, ':'); 392dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(name == 0) { 393dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret = socket_loopback_client(port, SOCK_STREAM); 394dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ret >= 0) 395dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project disable_tcp_nagle(ret); 396dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 397dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_HOST 398dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret = socket_network_client(name + 1, port, SOCK_STREAM); 399dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else 400dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return -1; 401dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 402dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 403dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifndef HAVE_WINSOCK /* winsock doesn't implement unix domain sockets */ 404dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if(!strncmp(name, "local:", 6)) { 405dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret = socket_local_client(name + 6, 406dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM); 407dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if(!strncmp(name, "localreserved:", 14)) { 408dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret = socket_local_client(name + 14, 409dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM); 410dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if(!strncmp(name, "localabstract:", 14)) { 411dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret = socket_local_client(name + 14, 412dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM); 413dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if(!strncmp(name, "localfilesystem:", 16)) { 414dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret = socket_local_client(name + 16, 415dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ANDROID_SOCKET_NAMESPACE_FILESYSTEM, SOCK_STREAM); 416dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 4179470c2f1ab555311633d52e5ed8303a813061cdfBenoit Goby#if !ADB_HOST 418dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if(!strncmp("dev:", name, 4)) { 419fe8d7f4f2e775d46d61f7c2d29a4e852434984daNick Kralevich ret = unix_open(name + 4, O_RDWR | O_CLOEXEC); 420dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if(!strncmp(name, "framebuffer:", 12)) { 421dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret = create_service_thread(framebuffer_service, 0); 422dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (!strncmp(name, "jdwp:", 5)) { 423dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret = create_jdwp_connection_fd(atoi(name+5)); 424dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if(!HOST && !strncmp(name, "shell:", 6)) { 4255d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey ret = create_subproc_thread(name + 6, SUBPROC_PTY); 4265d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey } else if(!HOST && !strncmp(name, "exec:", 5)) { 4275d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey ret = create_subproc_thread(name + 5, SUBPROC_RAW); 428dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if(!strncmp(name, "sync:", 5)) { 429dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret = create_service_thread(file_sync_service, NULL); 430dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if(!strncmp(name, "remount:", 8)) { 431dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project ret = create_service_thread(remount_service, NULL); 432ee15662140632672a6878787a1ff26f5ebdc1e68Mike Lockwood } else if(!strncmp(name, "reboot:", 7)) { 433b6b40079e6d5b32026cc2abfcb71adfd49e8d954Mike Lockwood void* arg = strdup(name + 7); 4345d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey if (arg == NULL) return -1; 435b6b40079e6d5b32026cc2abfcb71adfd49e8d954Mike Lockwood ret = create_service_thread(reboot_service, arg); 436e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project } else if(!strncmp(name, "root:", 5)) { 437e037fd7e193ecccbb5c0888e49f6d58c224bc11dThe Android Open Source Project ret = create_service_thread(restart_root_service, NULL); 438d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate } else if(!strncmp(name, "backup:", 7)) { 4395d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey char* arg = strdup(name + 7); 440d2f5415c603f7d9961f7a0b05579a0768e071410Christopher Tate if (arg == NULL) return -1; 4415d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey char* c = arg; 4425d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey for (; *c != '\0'; c++) { 4435d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey if (*c == ':') 4445d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey *c = ' '; 4455d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey } 4465d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey char* cmd; 4475d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey if (asprintf(&cmd, "/system/bin/bu backup %s", arg) != -1) { 4485d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey ret = create_subproc_thread(cmd, SUBPROC_RAW); 4495d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey free(cmd); 4505d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey } 4515d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey free(arg); 452702967afb1bebc97c0b8a23c075d4932820ef7a3Christopher Tate } else if(!strncmp(name, "restore:", 8)) { 4535d9d434efadf1c535c7fea634d5306e18c68ef1fJeff Sharkey ret = create_subproc_thread("/system/bin/bu restore", SUBPROC_RAW); 454ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood } else if(!strncmp(name, "tcpip:", 6)) { 455ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood int port; 456ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood if (sscanf(name + 6, "%d", &port) == 0) { 457ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood port = 0; 458ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood } 459ccecf1425412beb2bc3bb38d470293fdc244d6f1Elliott Hughes ret = create_service_thread(restart_tcp_service, (void *) (uintptr_t) port); 460ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood } else if(!strncmp(name, "usb:", 4)) { 461ff19670d485fd5ee296e23b00b035ac22975c647Mike Lockwood ret = create_service_thread(restart_usb_service, NULL); 462252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner } else if (!strncmp(name, "reverse:", 8)) { 463252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner char* cookie = strdup(name + 8); 464252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner if (cookie == NULL) { 465252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner ret = -1; 466252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner } else { 467252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner ret = create_service_thread(reverse_service, cookie); 468252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner if (ret < 0) { 469252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner free(cookie); 470252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner } 471252586941934d23073a8d167ec240b221062505fDavid 'Digit' Turner } 472dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 473dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 474dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (ret >= 0) { 475dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project close_on_exec(ret); 476dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 477dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return ret; 478dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 479dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 480dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_HOST 481dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstruct state_info { 482dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project transport_type transport; 483dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char* serial; 484dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int state; 485dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}; 486dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 487dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void wait_for_state(int fd, void* cookie) 488dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 489dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct state_info* sinfo = cookie; 490dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project char* err = "unknown error"; 491dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 492dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("wait_for_state %d\n", sinfo->state); 493dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 494dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project atransport *t = acquire_one_transport(sinfo->state, sinfo->transport, sinfo->serial, &err); 495dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if(t != 0) { 496dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project writex(fd, "OKAY", 4); 497dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 498dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sendfailmsg(fd, err); 499dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 500dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 501dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (sinfo->serial) 502dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(sinfo->serial); 503dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(sinfo); 504dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project adb_close(fd); 505dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project D("wait_for_state is done\n"); 506dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 5071c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby 5081c45ee92e2372f3c552744823143fb093fdbda9dBenoit Gobystatic void connect_device(char* host, char* buffer, int buffer_size) 5091c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby{ 5101c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby int port, fd; 5111c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby char* portstr = strchr(host, ':'); 5121c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby char hostbuf[100]; 5131c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby char serial[100]; 5141c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby int ret; 5151c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby 5161c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby strncpy(hostbuf, host, sizeof(hostbuf) - 1); 5171c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby if (portstr) { 5181c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby if (portstr - host >= (ptrdiff_t)sizeof(hostbuf)) { 5191c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby snprintf(buffer, buffer_size, "bad host name %s", host); 5201c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby return; 5211c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby } 5221c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby // zero terminate the host at the point we found the colon 5231c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby hostbuf[portstr - host] = 0; 5241c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby if (sscanf(portstr + 1, "%d", &port) == 0) { 5251c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby snprintf(buffer, buffer_size, "bad port number %s", portstr); 5261c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby return; 5271c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby } 5281c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby } else { 5291c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby port = DEFAULT_ADB_LOCAL_TRANSPORT_PORT; 5301c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby } 5311c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby 5321c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby snprintf(serial, sizeof(serial), "%s:%d", hostbuf, port); 5331c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby 534aecc6a6657746afc9b95a960eedad10484bf14acKen Lierman fd = socket_network_client_timeout(hostbuf, port, SOCK_STREAM, 10); 5351c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby if (fd < 0) { 5361c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby snprintf(buffer, buffer_size, "unable to connect to %s:%d", host, port); 5371c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby return; 5381c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby } 5391c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby 5401c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby D("client: connected on remote on fd %d\n", fd); 5411c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby close_on_exec(fd); 5421c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby disable_tcp_nagle(fd); 5431c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby 5441c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby ret = register_socket_transport(fd, serial, port, 0); 5451c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby if (ret < 0) { 5461c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby adb_close(fd); 5471c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby snprintf(buffer, buffer_size, "already connected to %s", serial); 5481c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby } else { 5491c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby snprintf(buffer, buffer_size, "connected to %s", serial); 5501c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby } 5511c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby} 5521c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby 5531c45ee92e2372f3c552744823143fb093fdbda9dBenoit Gobyvoid connect_emulator(char* port_spec, char* buffer, int buffer_size) 5541c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby{ 5551c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby char* port_separator = strchr(port_spec, ','); 5561c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby if (!port_separator) { 5571c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby snprintf(buffer, buffer_size, 5581c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby "unable to parse '%s' as <console port>,<adb port>", 5591c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby port_spec); 5601c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby return; 5611c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby } 5621c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby 5631c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby // Zero-terminate console port and make port_separator point to 2nd port. 5641c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby *port_separator++ = 0; 5651c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby int console_port = strtol(port_spec, NULL, 0); 5661c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby int adb_port = strtol(port_separator, NULL, 0); 5671c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby if (!(console_port > 0 && adb_port > 0)) { 5681c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby *(port_separator - 1) = ','; 5691c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby snprintf(buffer, buffer_size, 5701c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby "Invalid port numbers: Expected positive numbers, got '%s'", 5711c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby port_spec); 5721c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby return; 5731c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby } 5741c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby 5751c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby /* Check if the emulator is already known. 5761c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby * Note: There's a small but harmless race condition here: An emulator not 5771c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby * present just yet could be registered by another invocation right 5781c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby * after doing this check here. However, local_connect protects 5791c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby * against double-registration too. From here, a better error message 5801c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby * can be produced. In the case of the race condition, the very specific 5811c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby * error message won't be shown, but the data doesn't get corrupted. */ 5821c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby atransport* known_emulator = find_emulator_transport_by_adb_port(adb_port); 5831c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby if (known_emulator != NULL) { 5841c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby snprintf(buffer, buffer_size, 5851c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby "Emulator on port %d already registered.", adb_port); 5861c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby return; 5871c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby } 5881c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby 5891c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby /* Check if more emulators can be registered. Similar unproblematic 5901c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby * race condition as above. */ 5911c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby int candidate_slot = get_available_local_transport_index(); 5921c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby if (candidate_slot < 0) { 5931c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby snprintf(buffer, buffer_size, "Cannot accept more emulators."); 5941c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby return; 5951c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby } 5961c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby 5971c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby /* Preconditions met, try to connect to the emulator. */ 5981c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby if (!local_connect_arbitrary_ports(console_port, adb_port)) { 5991c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby snprintf(buffer, buffer_size, 6001c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby "Connected to emulator on ports %d,%d", console_port, adb_port); 6011c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby } else { 6021c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby snprintf(buffer, buffer_size, 6031c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby "Could not connect to emulator on ports %d,%d", 6041c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby console_port, adb_port); 6051c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby } 6061c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby} 6071c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby 6081c45ee92e2372f3c552744823143fb093fdbda9dBenoit Gobystatic void connect_service(int fd, void* cookie) 6091c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby{ 6101c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby char buf[4096]; 6111c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby char resp[4096]; 6121c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby char *host = cookie; 6131c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby 6141c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby if (!strncmp(host, "emu:", 4)) { 6151c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby connect_emulator(host + 4, buf, sizeof(buf)); 6161c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby } else { 6171c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby connect_device(host, buf, sizeof(buf)); 6181c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby } 6191c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby 6201c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby // Send response for emulator and device 6211c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby snprintf(resp, sizeof(resp), "%04x%s",(unsigned)strlen(buf), buf); 6221c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby writex(fd, resp, strlen(resp)); 6231c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby adb_close(fd); 6241c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby} 625dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif 626dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 627dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if ADB_HOST 628dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectasocket* host_service_to_socket(const char* name, const char *serial) 629dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 630dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!strcmp(name,"track-devices")) { 631dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return create_device_tracker(); 632dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (!strncmp(name, "wait-for-", strlen("wait-for-"))) { 633dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project struct state_info* sinfo = malloc(sizeof(struct state_info)); 634dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 635dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (serial) 636dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sinfo->serial = strdup(serial); 637dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project else 638dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sinfo->serial = NULL; 639dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 640dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project name += strlen("wait-for-"); 641dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 642dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (!strncmp(name, "local", strlen("local"))) { 643dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sinfo->transport = kTransportLocal; 644dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sinfo->state = CS_DEVICE; 645dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (!strncmp(name, "usb", strlen("usb"))) { 646dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sinfo->transport = kTransportUsb; 647dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sinfo->state = CS_DEVICE; 648dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else if (!strncmp(name, "any", strlen("any"))) { 649dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sinfo->transport = kTransportAny; 650dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sinfo->state = CS_DEVICE; 651dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } else { 652dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(sinfo); 653dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return NULL; 654dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 655dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 656dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int fd = create_service_thread(wait_for_state, sinfo); 657dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return create_local_socket(fd); 6581c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby } else if (!strncmp(name, "connect:", 8)) { 6591c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby const char *host = name + 8; 6601c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby int fd = create_service_thread(connect_service, (void *)host); 6611c45ee92e2372f3c552744823143fb093fdbda9dBenoit Goby return create_local_socket(fd); 662dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 663dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return NULL; 664dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 665dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif /* ADB_HOST */ 666