void start_device_log(void) { int fd; char path[PATH_MAX]; struct tm now; time_t t; char value[PROPERTY_VALUE_MAX]; // read the trace mask from persistent property persist.adb.trace_mask // give up if the property is not set or cannot be parsed property_get("persist.adb.trace_mask", value, ""); if (sscanf(value, "%x", &adb_trace_mask) != 1) return; adb_mkdir("/data/adb", 0775); tzset(); time(&t); localtime_r(&t, &now); strftime(path, sizeof(path), "/data/adb/adb-%Y-%m-%d-%H-%M-%S.txt", &now); fd = unix_open(path, O_WRONLY | O_CREAT | O_TRUNC, 0640); if (fd < 0) return; // redirect stdout and stderr to the log file dup2(fd, 1); dup2(fd, 2); fprintf(stderr,"--- adb starting (pid %d) ---\n", getpid()); adb_close(fd); fd = unix_open("/dev/null", O_RDONLY); dup2(fd, 0); adb_close(fd); }
void start_device_log(void) { int fd; char path[PATH_MAX]; struct tm now; time_t t; adb_mkdir("/var/adb", 0775); tzset(); time(&t); localtime_r(&t, &now); strftime(path, sizeof(path), "/var/adb/adb-%Y-%m-%d-%H-%M-%S.txt", &now); fd = unix_open(path, O_WRONLY | O_CREAT | O_TRUNC, 0640); if (fd < 0) return; // redirect stdout and stderr to the log file dup2(fd, 1); dup2(fd, 2); fprintf(stderr,"--- adb starting (pid %d) ---\n", getpid()); adb_close(fd); fd = unix_open("/dev/null", O_RDONLY); dup2(fd, 0); adb_close(fd); }
static int create_subproc_pty(const char *cmd, const char *arg0, const char *arg1, pid_t *pid) { D("create_subproc_pty(cmd=%s, arg0=%s, arg1=%s)\n", cmd, arg0, arg1); #ifdef HAVE_WIN32_PROC fprintf(stderr, "error: create_subproc_pty not implemented on Win32 (%s %s %s)\n", cmd, arg0, arg1); return -1; #else /* !HAVE_WIN32_PROC */ char *devname; int ptm; ptm = unix_open("/dev/ptmx", O_RDWR | O_CLOEXEC); // | O_NOCTTY); if(ptm < 0){ printf("[ cannot open /dev/ptmx - %s ]\n",strerror(errno)); return -1; } if(grantpt(ptm) || unlockpt(ptm) || ((devname = (char*) ptsname(ptm)) == 0)){ printf("[ trouble with /dev/ptmx - %s ]\n", strerror(errno)); adb_close(ptm); return -1; } *pid = fork(); if(*pid < 0) { printf("- fork failed: %s -\n", strerror(errno)); adb_close(ptm); return -1; } if (*pid == 0) { init_subproc_child(); int pts = unix_open(devname, O_RDWR | O_CLOEXEC); if (pts < 0) { fprintf(stderr, "child failed to open pseudo-term slave: %s\n", devname); exit(-1); } dup2(pts, STDIN_FILENO); dup2(pts, STDOUT_FILENO); dup2(pts, STDERR_FILENO); adb_close(pts); adb_close(ptm); execl(cmd, cmd, arg0, arg1, NULL); fprintf(stderr, "- exec '%s' failed: %s (%d) -\n", cmd, strerror(errno), errno); exit(-1); } else { return ptm; } #endif /* !HAVE_WIN32_PROC */ }
void usb_init() { usb_handle *h; adb_thread_t tid; int fd; h = calloc(1, sizeof(usb_handle)); h->fd = -1; adb_cond_init(&h->notify, 0); adb_mutex_init(&h->lock, 0); // Open the file /dev/android_adb_enable to trigger // the enabling of the adb USB function in the kernel. // We never touch this file again - just leave it open // indefinitely so the kernel will know when we are running // and when we are not. fd = unix_open("/dev/android_adb_enable", O_RDWR); if (fd < 0) { D("failed to open /dev/android_adb_enable\n"); } else { close_on_exec(fd); } D("[ usb_init - starting thread ]\n"); if(adb_thread_create(&tid, usb_open_thread, h)){ fatal_errno("cannot create usb thread"); } }
/* we keep a list of opened transports. The atransport struct knows to which * local transport it is connected. The list is used to detect when we're * trying to connect twice to a given local transport. */ #define SDB_LOCAL_TRANSPORT_MAX 16 SDB_MUTEX_DEFINE( local_transports_lock ); static atransport* local_transports[ SDB_LOCAL_TRANSPORT_MAX ]; #endif /* SDB_HOST */ static int remote_read(apacket *p, atransport *t) { if(readx(t->sfd, &p->msg, sizeof(amessage))){ D("remote local: read terminated (message)\n"); return -1; } fix_endians(p); #if 0 && defined __ppc__ D("read remote packet: %04x arg0=%0x arg1=%0x data_length=%0x data_check=%0x magic=%0x\n", p->msg.command, p->msg.arg0, p->msg.arg1, p->msg.data_length, p->msg.data_check, p->msg.magic); #endif if(check_header(p)) { D("bad header: terminated (data)\n"); return -1; } if(readx(t->sfd, p->data, p->msg.data_length)){ D("remote local: terminated (data)\n"); return -1; } if(check_data(p)) { D("bad data: terminated (data)\n"); return -1; } return 0; } static int remote_write(apacket *p, atransport *t) { int length = p->msg.data_length; fix_endians(p); #if 0 && defined __ppc__ D("write remote packet: %04x arg0=%0x arg1=%0x data_length=%0x data_check=%0x magic=%0x\n", p->msg.command, p->msg.arg0, p->msg.arg1, p->msg.data_length, p->msg.data_check, p->msg.magic); #endif if(writex(t->sfd, &p->msg, sizeof(amessage) + length)) { D("remote local: write terminated\n"); return -1; } return 0; } int local_connect(int port, const char *device_name) { return local_connect_arbitrary_ports(port-1, port, device_name); } int local_connect_arbitrary_ports(int console_port, int sdb_port, const char *device_name) { char buf[64]; int fd = -1; #if SDB_HOST const char *host = getenv("SDBHOST"); if (host) { fd = socket_network_client(host, sdb_port, SOCK_STREAM); } #endif if (fd < 0) { fd = socket_loopback_client(sdb_port, SOCK_STREAM); } if (fd >= 0) { D("client: connected on remote on fd %d\n", fd); close_on_exec(fd); disable_tcp_nagle(fd); snprintf(buf, sizeof buf, "%s%d", LOCAL_CLIENT_PREFIX, console_port); register_socket_transport(fd, buf, sdb_port, 1, device_name); return 0; } return -1; } #if SDB_HOST /* tizen specific */ int get_devicename(int port, char *device_name) { int fd; char buffer[MAX_PAYLOAD]; char *tok = NULL; int found = 0; fd = unix_open(DEVICEMAP_FILENAME, O_RDONLY); if (fd > 0) { for(;;) { if(read_line(fd, buffer, MAX_PAYLOAD) < 0) break; tok = strtok(buffer, DEVICEMAP_SEPARATOR); if (tok != NULL) { strncpy(device_name, tok, DEVICENAME_MAX); tok = strtok(NULL, DEVICEMAP_SEPARATOR); if (tok != NULL) { if (port == atoi(tok)) { found = 1; break; } } } } sdb_close(fd); } if (found != 1) strncpy(device_name, DEFAULT_DEVICENAME, DEVICENAME_MAX); D("init device name %s on port %d\n", device_name, port); return found; }
void start_logging(void) { int fd; fd = unix_open("/dev/null", O_RDONLY); dup2(fd, 0); adb_close(fd); fd = unix_open("/tmp/adb.log", O_WRONLY | O_CREAT | O_APPEND, 0640); if(fd < 0) { fd = unix_open("/dev/null", O_WRONLY); } dup2(fd, 1); dup2(fd, 2); adb_close(fd); fprintf(stderr,"--- adb starting (pid %d) ---\n", getpid()); }
/*** generic file functions */ void * file_open(char * filename, int mode, int creatmode, int buffering) { #ifdef WIN32 return win32_open(filename, mode, creatmode, buffering); #else return unix_open(filename, mode, creatmode, buffering); #endif }
static int create_subproc_pty(const char* cmd, const char* arg0, const char* arg1, pid_t* pid) { D("create_subproc_pty(cmd=%s, arg0=%s, arg1=%s)\n", cmd, arg0, arg1); char pts_name[PATH_MAX]; int ptm; *pid = forkpty(&ptm, pts_name, nullptr, nullptr); if (*pid == -1) { printf("- fork failed: %s -\n", strerror(errno)); adb_close(ptm); return -1; } if (*pid == 0) { init_subproc_child(); int pts = unix_open(pts_name, O_RDWR | O_CLOEXEC); if (pts == -1) { fprintf(stderr, "child failed to open pseudo-term slave %s: %s\n", pts_name, strerror(errno)); adb_close(ptm); exit(-1); } // arg0 is "-c" in batch mode and "-" in interactive mode. if (strcmp(arg0, "-c") == 0) { termios tattr; if (tcgetattr(pts, &tattr) == -1) { fprintf(stderr, "tcgetattr failed: %s\n", strerror(errno)); adb_close(pts); adb_close(ptm); exit(-1); } cfmakeraw(&tattr); if (tcsetattr(pts, TCSADRAIN, &tattr) == -1) { fprintf(stderr, "tcsetattr failed: %s\n", strerror(errno)); adb_close(pts); adb_close(ptm); exit(-1); } } dup2(pts, STDIN_FILENO); dup2(pts, STDOUT_FILENO); dup2(pts, STDERR_FILENO); adb_close(pts); adb_close(ptm); execl(cmd, cmd, arg0, arg1, nullptr); fprintf(stderr, "- exec '%s' failed: %s (%d) -\n", cmd, strerror(errno), errno); exit(-1); } else { return ptm; } }
void close_stdin() { int fd = unix_open("/dev/null", O_RDONLY); if (fd == -1) { perror("failed to open /dev/null, stdin will remain open"); return; } dup2(fd, 0); adb_close(fd); }
void start_logging(void) { #ifdef HAVE_WIN32_PROC char temp[ MAX_PATH ]; WCHAR temp_[ MAX_PATH ]; FILE* fnul; FILE* flog; GetTempPath( sizeof(temp) - 8, temp_ ); wcstombs(temp, temp_, MAX_PATH); strcat( temp, "adb.log" ); /* Win32 specific redirections */ fnul = fopen( "NUL", "rt" ); if (fnul != NULL) stdin[0] = fnul[0]; flog = fopen( temp, "at" ); if (flog == NULL) flog = fnul; setvbuf( flog, NULL, _IONBF, 0 ); stdout[0] = flog[0]; stderr[0] = flog[0]; fprintf(stderr,"--- adb starting (pid %d) ---\n", getpid()); #else int fd; fd = unix_open("/dev/null", O_RDONLY); dup2(fd, 0); adb_close(fd); fd = unix_open("/tmp/adb.log", O_WRONLY | O_CREAT | O_APPEND, 0640); if(fd < 0) { fd = unix_open("/dev/null", O_WRONLY); } dup2(fd, 1); dup2(fd, 2); adb_close(fd); fprintf(stderr,"--- adb starting (pid %d) ---\n", getpid()); #endif }
bool make_block_device_writable(const std::string& dev) { int fd = unix_open(dev.c_str(), O_RDONLY | O_CLOEXEC); if (fd == -1) { return false; } int OFF = 0; bool result = (ioctl(fd, BLKROSET, &OFF) != -1); unix_close(fd); return result; }
void close_stdin() { int fd = unix_open(kNullFileName, O_RDONLY); if (fd == -1) { fatal_errno("failed to open %s", kNullFileName); } if (TEMP_FAILURE_RETRY(dup2(fd, STDIN_FILENO)) == -1) { fatal_errno("failed to redirect stdin to %s", kNullFileName); } unix_close(fd); }
void start_device_log(void) { int fd = unix_open(get_log_file_name().c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0640); if (fd == -1) { return; } // Redirect stdout and stderr to the log file. dup2(fd, STDOUT_FILENO); dup2(fd, STDERR_FILENO); fprintf(stderr, "--- adb starting (pid %d) ---\n", getpid()); adb_close(fd); }
void start_device_log(void) { int fd; char path[100]; snprintf(path, sizeof path, "/data/adb_%ld.txt", (long)time(NULL)); fd = unix_open(path, O_WRONLY | O_CREAT | O_APPEND, 0640); if (fd < 0) return; // redirect stdout and stderr to the log file dup2(fd, 1); dup2(fd, 2); fprintf(stderr,"--- adb starting (pid %d) ---\n", getpid()); fd = unix_open("/dev/null", O_RDONLY); dup2(fd, 0); // log everything adb_trace_mask = ~0; // except TRACE_RWX is a bit too verbose adb_trace_mask &= ~TRACE_RWX; }
static void *usb_open_thread(void *x) { struct usb_handle *usb = (struct usb_handle *)x; int fd; while (1) { // wait until the USB device needs opening adb_mutex_lock(&usb->lock); while (usb->fd != -1) adb_cond_wait(&usb->notify, &usb->lock); adb_mutex_unlock(&usb->lock); D("[ usb_thread - opening device ]\n"); do { /* XXX use inotify? */ fd = unix_open("/dev/android_adb", O_RDWR); if (fd < 0) { // to support older kernels fd = unix_open("/dev/android", O_RDWR); } if (fd < 0) { adb_sleep_ms(1000); } } while (fd < 0); D("[ opening device succeeded ]\n"); close_on_exec(fd); usb->fd = fd; D("[ usb_thread - registering device ]\n"); register_usb_transport(usb, 0, 1); } // never gets here return 0; }
static void setup_daemon_logging(void) { const std::string log_file_path(GetLogFilePath()); int fd = unix_open(log_file_path.c_str(), O_WRONLY | O_CREAT | O_APPEND, 0640); if (fd == -1) { fatal("cannot open '%s': %s", log_file_path.c_str(), strerror(errno)); } if (dup2(fd, STDOUT_FILENO) == -1) { fatal("cannot redirect stdout: %s", strerror(errno)); } if (dup2(fd, STDERR_FILENO) == -1) { fatal("cannot redirect stderr: %s", strerror(errno)); } unix_close(fd); fprintf(stderr, "--- adb starting (pid %d) ---\n", getpid()); LOG(INFO) << adb_version(); }
static void status_window(transport_type ttype, const char* serial) { char command[4096]; char *state = 0; char *laststate = 0; /* silence stderr */ #ifdef _WIN32 /* XXX: TODO */ #else int fd; fd = unix_open("/dev/null", O_WRONLY); dup2(fd, 2); adb_close(fd); #endif format_host_command(command, sizeof command, "get-state", ttype, serial); for(;;) { adb_sleep_ms(250); if(state) { free(state); state = 0; } state = adb_query(command); if(state) { if(laststate && !strcmp(state,laststate)){ continue; } else { if(laststate) free(laststate); laststate = strdup(state); } } printf("%c[2J%c[2H", 27, 27); printf("Android Debug Bridge\n"); printf("State: %s\n", state ? state : "offline"); fflush(stdout); } }
void log_service(int fd, void *cookie) { /* get the name of the log filepath to read */ char * log_filepath = cookie; /* open the log file. */ int logfd = unix_open(log_filepath, O_RDONLY); if (logfd < 0) { goto done; } // temp buffer to read the entries unsigned char buf[LOGGER_ENTRY_MAX_LEN + 1] __attribute__((aligned(4))); struct logger_entry *entry = (struct logger_entry *) buf; while (1) { int ret; ret = unix_read(logfd, entry, LOGGER_ENTRY_MAX_LEN); if (ret < 0) { if (errno == EINTR || errno == EAGAIN) continue; // perror("logcat read"); goto done; } else if (!ret) { // fprintf(stderr, "read: Unexpected EOF!\n"); goto done; } /* NOTE: driver guarantees we read exactly one full entry */ entry->msg[entry->len] = '\0'; write_log_entry(fd, entry); } done: unix_close(fd); free(log_filepath); }
void start_device_log(void) { struct tm now; time_t t; tzset(); time(&t); localtime_r(&t, &now); char timestamp[PATH_MAX]; strftime(timestamp, sizeof(timestamp), "%Y-%m-%d-%H-%M-%S", &now); std::string path = android::base::StringPrintf("/data/adb/adb-%s-%d", timestamp, getpid()); int fd = unix_open(path.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0640); if (fd == -1) { return; } // redirect stdout and stderr to the log file dup2(fd, STDOUT_FILENO); dup2(fd, STDERR_FILENO); fprintf(stderr, "--- adb starting (pid %d) ---\n", getpid()); adb_close(fd); }
/* Returns the device used to mount a directory in /proc/mounts */ static char *find_mount(const char *dir) { int fd; int res; int size; char *token = NULL; const char delims[] = "\n"; char buf[4096]; fd = unix_open("/proc/mounts", O_RDONLY); if (fd < 0) return NULL; buf[sizeof(buf) - 1] = '\0'; size = sdb_read(fd, buf, sizeof(buf) - 1); sdb_close(fd); token = strtok(buf, delims); while (token) { char mount_dev[256]; char mount_dir[256]; int mount_freq; int mount_passno; res = sscanf(token, "%255s %255s %*s %*s %d %d\n", mount_dev, mount_dir, &mount_freq, &mount_passno); mount_dev[255] = 0; mount_dir[255] = 0; if (res == 4 && (strcmp(dir, mount_dir) == 0)) return strdup(mount_dev); token = strtok(NULL, delims); } return NULL; }
int service_to_fd(const char* name, const atransport* transport) { int ret = -1; if(!strncmp(name, "tcp:", 4)) { int port = atoi(name + 4); name = strchr(name + 4, ':'); if(name == 0) { std::string error; ret = network_loopback_client(port, SOCK_STREAM, &error); if (ret >= 0) disable_tcp_nagle(ret); } else { #if ADB_HOST std::string error; ret = network_connect(name + 1, port, SOCK_STREAM, 0, &error); #else return -1; #endif } #if !defined(_WIN32) /* winsock doesn't implement unix domain sockets */ } else if(!strncmp(name, "local:", 6)) { ret = socket_local_client(name + 6, ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM); } else if(!strncmp(name, "localreserved:", 14)) { ret = socket_local_client(name + 14, ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM); } else if(!strncmp(name, "localabstract:", 14)) { ret = socket_local_client(name + 14, ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM); } else if(!strncmp(name, "localfilesystem:", 16)) { ret = socket_local_client(name + 16, ANDROID_SOCKET_NAMESPACE_FILESYSTEM, SOCK_STREAM); #endif #if !ADB_HOST } else if(!strncmp("dev:", name, 4)) { ret = unix_open(name + 4, O_RDWR | O_CLOEXEC); } else if(!strncmp(name, "framebuffer:", 12)) { ret = create_service_thread(framebuffer_service, 0); } else if (!strncmp(name, "jdwp:", 5)) { ret = create_jdwp_connection_fd(atoi(name+5)); } else if(!strncmp(name, "shell", 5)) { ret = ShellService(name + 5, transport); } else if(!strncmp(name, "exec:", 5)) { ret = StartSubprocess(name + 5, nullptr, SubprocessType::kRaw, SubprocessProtocol::kNone); } else if(!strncmp(name, "sync:", 5)) { ret = create_service_thread(file_sync_service, NULL); } else if(!strncmp(name, "remount:", 8)) { ret = create_service_thread(remount_service, NULL); } else if(!strncmp(name, "reboot:", 7)) { void* arg = strdup(name + 7); if (arg == NULL) return -1; ret = create_service_thread(reboot_service, arg); } else if(!strncmp(name, "root:", 5)) { ret = create_service_thread(restart_root_service, NULL); } else if(!strncmp(name, "unroot:", 7)) { ret = create_service_thread(restart_unroot_service, NULL); } else if(!strncmp(name, "backup:", 7)) { ret = StartSubprocess(android::base::StringPrintf("/system/bin/bu backup %s", (name + 7)).c_str(), nullptr, SubprocessType::kRaw, SubprocessProtocol::kNone); } else if(!strncmp(name, "restore:", 8)) { ret = StartSubprocess("/system/bin/bu restore", nullptr, SubprocessType::kRaw, SubprocessProtocol::kNone); } else if(!strncmp(name, "tcpip:", 6)) { int port; if (sscanf(name + 6, "%d", &port) != 1) { return -1; } ret = create_service_thread(restart_tcp_service, (void *) (uintptr_t) port); } else if(!strncmp(name, "usb:", 4)) { ret = create_service_thread(restart_usb_service, NULL); } else if (!strncmp(name, "reverse:", 8)) { ret = reverse_service(name + 8); } else if(!strncmp(name, "disable-verity:", 15)) { ret = create_service_thread(set_verity_enabled_state_service, (void*)0); } else if(!strncmp(name, "enable-verity:", 15)) { ret = create_service_thread(set_verity_enabled_state_service, (void*)1); #endif } if (ret >= 0) { close_on_exec(ret); } return ret; }
int service_to_fd(const char *name) { int ret = -1; if(!strncmp(name, "tcp:", 4)) { int port = atoi(name + 4); name = strchr(name + 4, ':'); if(name == 0) { ret = socket_loopback_client(port, SOCK_STREAM); if (ret >= 0) disable_tcp_nagle(ret); } else { #if ADB_HOST ret = socket_network_client(name + 1, port, SOCK_STREAM); #else return -1; #endif } #ifndef HAVE_WINSOCK /* winsock doesn't implement unix domain sockets */ } else if(!strncmp(name, "local:", 6)) { ret = socket_local_client(name + 6, ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM); } else if(!strncmp(name, "localreserved:", 14)) { ret = socket_local_client(name + 14, ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM); } else if(!strncmp(name, "localabstract:", 14)) { ret = socket_local_client(name + 14, ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM); } else if(!strncmp(name, "localfilesystem:", 16)) { ret = socket_local_client(name + 16, ANDROID_SOCKET_NAMESPACE_FILESYSTEM, SOCK_STREAM); #endif #if !ADB_HOST } else if(!strncmp("dev:", name, 4)) { ret = unix_open(name + 4, O_RDWR | O_CLOEXEC); } else if(!strncmp(name, "framebuffer:", 12)) { ret = create_service_thread(framebuffer_service, 0); } else if (!strncmp(name, "jdwp:", 5)) { ret = create_jdwp_connection_fd(atoi(name+5)); } else if(!HOST && !strncmp(name, "shell:", 6)) { ret = create_subproc_thread(name + 6, SUBPROC_PTY); } else if(!HOST && !strncmp(name, "exec:", 5)) { ret = create_subproc_thread(name + 5, SUBPROC_RAW); } else if(!strncmp(name, "sync:", 5)) { ret = create_service_thread(file_sync_service, NULL); } else if(!strncmp(name, "remount:", 8)) { ret = create_service_thread(remount_service, NULL); } else if(!strncmp(name, "reboot:", 7)) { void* arg = strdup(name + 7); if (arg == NULL) return -1; ret = create_service_thread(reboot_service, arg); } else if(!strncmp(name, "root:", 5)) { ret = create_service_thread(restart_root_service, NULL); } else if(!strncmp(name, "backup:", 7)) { char* arg = strdup(name + 7); if (arg == NULL) return -1; char* c = arg; for (; *c != '\0'; c++) { if (*c == ':') *c = ' '; } char* cmd; if (asprintf(&cmd, "%s backup %s", bu_path(), arg) != -1) { ret = create_subproc_thread(cmd, SUBPROC_RAW); free(cmd); } free(arg); } else if(!strncmp(name, "restore:", 8)) { char* cmd; if (asprintf(&cmd, "%s restore", bu_path()) != -1) { ret = create_subproc_thread(cmd, SUBPROC_RAW); free(cmd); } } else if(!strncmp(name, "tcpip:", 6)) { int port; if (sscanf(name + 6, "%d", &port) == 0) { port = 0; } ret = create_service_thread(restart_tcp_service, (void *) (uintptr_t) port); } else if(!strncmp(name, "usb:", 4)) { ret = create_service_thread(restart_usb_service, NULL); } else if (!strncmp(name, "reverse:", 8)) { char* cookie = strdup(name + 8); if (cookie == NULL) { ret = -1; } else { ret = create_service_thread(reverse_service, cookie); if (ret < 0) { free(cookie); } } #endif } if (ret >= 0) { close_on_exec(ret); } return ret; }
int service_to_fd(const char* name, const atransport* transport) { int ret = -1; if (is_socket_spec(name)) { std::string error; ret = socket_spec_connect(name, &error); if (ret < 0) { LOG(ERROR) << "failed to connect to socket '" << name << "': " << error; } #if !ADB_HOST } else if(!strncmp("dev:", name, 4)) { ret = unix_open(name + 4, O_RDWR | O_CLOEXEC); } else if(!strncmp(name, "framebuffer:", 12)) { ret = create_service_thread(framebuffer_service, 0); } else if (!strncmp(name, "jdwp:", 5)) { ret = create_jdwp_connection_fd(atoi(name+5)); } else if(!strncmp(name, "shell", 5)) { ret = ShellService(name + 5, transport); } else if(!strncmp(name, "exec:", 5)) { ret = StartSubprocess(name + 5, nullptr, SubprocessType::kRaw, SubprocessProtocol::kNone); } else if(!strncmp(name, "sync:", 5)) { ret = create_service_thread(file_sync_service, NULL); } else if(!strncmp(name, "remount:", 8)) { ret = create_service_thread(remount_service, NULL); } else if(!strncmp(name, "reboot:", 7)) { void* arg = strdup(name + 7); if (arg == NULL) return -1; ret = create_service_thread(reboot_service, arg); } else if(!strncmp(name, "root:", 5)) { ret = create_service_thread(restart_root_service, NULL); } else if(!strncmp(name, "unroot:", 7)) { ret = create_service_thread(restart_unroot_service, NULL); } else if(!strncmp(name, "backup:", 7)) { ret = StartSubprocess(android::base::StringPrintf("/system/bin/bu backup %s", (name + 7)).c_str(), nullptr, SubprocessType::kRaw, SubprocessProtocol::kNone); } else if(!strncmp(name, "restore:", 8)) { ret = StartSubprocess("/system/bin/bu restore", nullptr, SubprocessType::kRaw, SubprocessProtocol::kNone); } else if(!strncmp(name, "tcpip:", 6)) { int port; if (sscanf(name + 6, "%d", &port) != 1) { return -1; } ret = create_service_thread(restart_tcp_service, (void *) (uintptr_t) port); } else if(!strncmp(name, "usb:", 4)) { ret = create_service_thread(restart_usb_service, NULL); } else if (!strncmp(name, "reverse:", 8)) { ret = reverse_service(name + 8); } else if(!strncmp(name, "disable-verity:", 15)) { ret = create_service_thread(set_verity_enabled_state_service, (void*)0); } else if(!strncmp(name, "enable-verity:", 15)) { ret = create_service_thread(set_verity_enabled_state_service, (void*)1); } else if (!strcmp(name, "reconnect")) { ret = create_service_thread(reconnect_service, const_cast<atransport*>(transport)); #endif } if (ret >= 0) { close_on_exec(ret); } return ret; }
static int create_subprocess(const char *cmd, const char *arg0, const char *arg1) { #ifdef HAVE_WIN32_PROC fprintf(stderr, "error: create_subprocess not implemented on Win32 (%s %s %s)\n", cmd, arg0, arg1); return -1; #else /* !HAVE_WIN32_PROC */ char *devname; int ptm; pid_t pid; ptm = unix_open("/dev/ptmx", O_RDWR); // | O_NOCTTY); if(ptm < 0){ printf("[ cannot open /dev/ptmx - %s ]\n",strerror(errno)); return -1; } fcntl(ptm, F_SETFD, FD_CLOEXEC); if(grantpt(ptm) || unlockpt(ptm) || ((devname = (char*) ptsname(ptm)) == 0)){ printf("[ trouble with /dev/ptmx - %s ]\n", strerror(errno)); return -1; } pid = fork(); if(pid < 0) { printf("- fork failed: %s -\n", strerror(errno)); return -1; } if(pid == 0){ int pts; setsid(); pts = unix_open(devname, O_RDWR); if(pts < 0) exit(-1); dup2(pts, 0); dup2(pts, 1); dup2(pts, 2); adb_close(ptm); execl(cmd, cmd, arg0, arg1, NULL); fprintf(stderr, "- exec '%s' failed: %s (%d) -\n", cmd, strerror(errno), errno); exit(-1); } else { #if !ADB_HOST // set child's OOM adjustment to zero char text[64]; snprintf(text, sizeof text, "/proc/%d/oom_adj", pid); int fd = adb_open(text, O_WRONLY); if (fd >= 0) { adb_write(fd, "0", 1); adb_close(fd); } else { D("adb: unable to open %s\n", text); } #endif return ptm; } #endif /* !HAVE_WIN32_PROC */ }
static int create_subproc_pty(const char *cmd, const char *arg0, const char *arg1, pid_t *pid) { D("create_subproc_pty(cmd=%s, arg0=%s, arg1=%s)\n", cmd, arg0, arg1); #ifdef HAVE_WIN32_PROC fprintf(stderr, "error: create_subproc_pty not implemented on Win32 (%s %s %s)\n", cmd, arg0, arg1); return -1; #else /* !HAVE_WIN32_PROC */ int ptm; ptm = unix_open("/dev/ptmx", O_RDWR | O_CLOEXEC); // | O_NOCTTY); if(ptm < 0){ printf("[ cannot open /dev/ptmx - %s ]\n",strerror(errno)); return -1; } char devname[64]; if(grantpt(ptm) || unlockpt(ptm) || ptsname_r(ptm, devname, sizeof(devname)) != 0) { printf("[ trouble with /dev/ptmx - %s ]\n", strerror(errno)); adb_close(ptm); return -1; } *pid = fork(); if(*pid < 0) { printf("- fork failed: %s -\n", strerror(errno)); XLOGW("- fork failed: pid(%d) %s -\n", *pid, strerror(errno)); adb_close(ptm); return -1; } if (*pid == 0) { init_subproc_child(); int pts = unix_open(devname, O_RDWR | O_CLOEXEC); if (pts < 0) { fprintf(stderr, "child failed to open pseudo-term slave: %s\n", devname); exit(-1); } dup2(pts, STDIN_FILENO); dup2(pts, STDOUT_FILENO); dup2(pts, STDERR_FILENO); adb_close(pts); adb_close(ptm); timer_t timerid; struct sigevent sev; /* Create the timer */ sev.sigev_notify = SIGEV_SIGNAL; sev.sigev_signo = SIGALRM; sev.sigev_value.sival_ptr = &timerid; if (timer_create(CLOCK_REALTIME, &sev, &timerid) == -1) { D("adb: Call timer_create failed!\n"); XLOGV("adb: Call timer_create failed!\n"); exit(-1); } struct itimerspec its; /* Start the timer */ its.it_value.tv_sec = 1; its.it_value.tv_nsec = 0; its.it_interval.tv_sec = 3; its.it_interval.tv_nsec = 0; if (timer_settime(timerid, 0, &its, NULL) == -1) { D("adb: Call timer_settime failed!\n"); XLOGV("adb: Call timer_settime failed!\n"); exit(-1); } sigset_t mask; struct sigaction sa; /* Establish handler for timer signal */ sa.sa_flags = SA_SIGINFO; sa.sa_sigaction = catcher; sigemptyset(&sa.sa_mask); if (sigaction(SIGALRM, &sa, NULL) == -1) { D("adb: Call sigaction failed!\n"); XLOGV("adb: Call sigaction failed!\n"); exit(-1); } int nRet = execl(cmd, cmd, arg0, arg1, NULL); fprintf(stderr, "- exec '%s' failed: %s (%d) -\n", cmd, strerror(errno), errno); XLOGV("- exec '%s' failed: %s (%d) nRet(%d) -\n", cmd, strerror(errno), errno, nRet); exit(-1); } else { return ptm; } #endif /* !HAVE_WIN32_PROC */ }
static int create_subprocess(const char *cmd, const char *arg0, const char *arg1, pid_t * pid) { #ifdef HAVE_WIN32_PROC D("create_subprocess(cmd=%s, arg0=%s, arg1=%s)\n", cmd, arg0, arg1); fprintf(stderr, "error: create_subprocess not implemented on Win32 (%s %s %s)\n", cmd, arg0, arg1); return -1; #else /* !HAVE_WIN32_PROC */ char *devname; int ptm; ptm = unix_open("/dev/ptmx", O_RDWR); // | O_NOCTTY); if (ptm < 0) { printf("[ cannot open /dev/ptmx - %s ]\n", strerror(errno)); return -1; } fcntl(ptm, F_SETFD, FD_CLOEXEC); if (grantpt(ptm) || unlockpt(ptm) || ((devname = (char *) ptsname(ptm)) == 0)) { printf("[ trouble with /dev/ptmx - %s ]\n", strerror(errno)); adb_close(ptm); return -1; } *pid = fork(); if (*pid < 0) { printf("- fork failed: %s -\n", strerror(errno)); adb_close(ptm); return -1; } if (*pid == 0) { int pts; setsid(); pts = unix_open(devname, O_RDWR); if (pts < 0) { fprintf(stderr, "child failed to open pseudo-term slave: %s\n", devname); exit(-1); } dup2(pts, 0); dup2(pts, 1); dup2(pts, 2); adb_close(pts); adb_close(ptm); // set OOM adjustment to zero char text[64]; snprintf(text, sizeof text, "/proc/%d/oom_adj", getpid()); int fd = adb_open(text, O_WRONLY); if (fd >= 0) { adb_write(fd, "0", 1); adb_close(fd); } else { D("adb: unable to open %s\n", text); } execl(cmd, cmd, arg0, arg1, NULL); fprintf(stderr, "- exec '%s' failed: %s (%d) -\n", cmd, strerror(errno), errno); exit(-1); } else { // Don't set child's OOM adjustment to zero. // Let the child do it itself, as sometimes the parent starts // running before the child has a /proc/pid/oom_adj. // """adb: unable to open /proc/644/oom_adj""" seen in some logs. return ptm; } #endif /* !HAVE_WIN32_PROC */ }
NTSTATUS NTAPI NtCreateFile(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PIO_STATUS_BLOCK IoStatusBlock, PLARGE_INTEGER AllocationSize, ULONG FileAttributes, ULONG ShareAccess, ULONG CreateDisposition, ULONG CreateOptions, PVOID EaBuffer, ULONG EaLength) { #ifdef _WIN32 HANDLE hFile; LARGE_INTEGER size; #endif DECLAREVARCONV(ObjectAttributesA); CHECK_POINTER(FileHandle); CHECK_POINTER(IoStatusBlock); OA2STR(ObjectAttributes); IoStatusBlock->Information = FILE_DOES_NOT_EXIST; #ifdef REDIR_IO { IO_STATUS_BLOCK iob; FILE_STANDARD_INFORMATION fi; NTSTATUS res = ftbl.nt.NtCreateFile(&hFile, DesiredAccess, ObjectAttributes, IoStatusBlock, AllocationSize, FileAttributes, ShareAccess, CreateDisposition, CreateOptions, EaBuffer, EaLength); if (res < 0) { Log("ntdll.NtCreateFile(\"%s\", 0x%08x) = 0x%08x\n", ObjectAttributesA, DesiredAccess, res); return res; } __CreateHandle(*FileHandle, HANDLE_FILE, ObjectAttributesA); (*FileHandle)->file.mode = DesiredAccess; (*FileHandle)->file.fh = hFile; res = ftbl.nt.NtQueryInformationFile(hFile, &iob, &fi, sizeof(fi), FileStandardInformation); if (res == STATUS_SUCCESS) (*FileHandle)->file.st.st_size = fi.EndOfFile.QuadPart; else { GET_LENGTH_INFORMATION gli; if ((res = ftbl.nt.NtDeviceIoControlFile(hFile, NULL, NULL, NULL, IoStatusBlock, IOCTL_DISK_GET_LENGTH_INFO, NULL, 0, &gli, sizeof(GET_LENGTH_INFORMATION))) < 0) { //fprintf(stderr, "NtOpenFile() - Unable to get size of %s: 0x%08x\n", ObjectAttributesA, res); // KeyboardClass etc (*FileHandle)->file.st.st_size = 0; } else (*FileHandle)->file.st.st_size = gli.Length.QuadPart; } } #endif /* REDIR_IO */ Log("ntdll.NtCreateFile(\"%s\", 0x%08x)\n", ObjectAttributesA, DesiredAccess); #ifdef _WIN32 hFile = CreateFileW(ObjectAttributes->ObjectName->Buffer, (DesiredAccess << 8) & 0xf0000000, ShareAccess, NULL, CreateDisposition, FileAttributes, NULL); if (hFile == INVALID_HANDLE_VALUE) { DWORD err = GetLastError(); if (err != 3 /* ERROR_PATH_NOT_FOUND */) fwprintf(stderr, L"CreateFileW '%s' failed with %d\n", ObjectAttributes->ObjectName->Buffer, GetLastError()); return (IoStatusBlock->u.Status = STATUS_OBJECT_NAME_NOT_FOUND); } if (!GetFileSizeEx(hFile, &size)) { fprintf(stderr, "CreateFileW() - Unable to get size of %s: %d\n", ObjectAttributesA, GetLastError()); return (IoStatusBlock->u.Status = STATUS_OBJECT_NAME_NOT_FOUND); } __CreateHandle(*FileHandle, HANDLE_FILE, ObjectAttributesA); (*FileHandle)->file.fh = hFile; (*FileHandle)->file.mode = DesiredAccess; (*FileHandle)->file.st.st_size = size.QuadPart; #else /* _WIN32 */ int fd = unix_open(ObjectAttributesA, ntflags_unix(DesiredAccess)); struct stat st; if ((fd < 0) || (fstat(fd, &st) < 0)) return (IoStatusBlock->u.Status = STATUS_OBJECT_NAME_NOT_FOUND); #if defined(BLKGETSIZE64) if (S_ISBLK(st.st_mode) && (ioctl(fd, BLKGETSIZE64, &st.st_size) < 0)) #elif defined(DIOCGMEDIASIZE) if (S_ISCHR(st.st_mode) && (ioctl(fd, DIOCGMEDIASIZE, &st.st_size) < 0)) #else if (!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode)) #endif st.st_size = 0; __CreateHandle(*FileHandle, HANDLE_FILE, ObjectAttributesA); (*FileHandle)->file.fh = fd; (*FileHandle)->file.mode = DesiredAccess; memcpy(&(*FileHandle)->file.st, &st, sizeof(st)); #endif /* _WIN32 */ IoStatusBlock->Information = FILE_CREATED; return (IoStatusBlock->u.Status = STATUS_SUCCESS); }
static int create_subprocess(const char *cmd, const char *arg0, const char *arg1, pid_t *pid) { #ifdef HAVE_WIN32_PROC D("create_subprocess(cmd=%s, arg0=%s, arg1=%s)\n", cmd, arg0, arg1); fprintf(stderr, "error: create_subprocess not implemented on Win32 (%s %s %s)\n", cmd, arg0, arg1); return -1; #else /* !HAVE_WIN32_PROC */ char *devname; int ptm; ptm = unix_open("/dev/ptmx", O_RDWR); // | O_NOCTTY); if(ptm < 0){ printf("[ cannot open /dev/ptmx - %s ]\n",strerror(errno)); return -1; } fcntl(ptm, F_SETFD, FD_CLOEXEC); if(grantpt(ptm) || unlockpt(ptm) || ((devname = (char*) ptsname(ptm)) == 0)){ printf("[ trouble with /dev/ptmx - %s ]\n", strerror(errno)); adb_close(ptm); return -1; } *pid = fork(); if(*pid < 0) { printf("- fork failed: pid(%d) %s -\n", *pid, strerror(errno)); XLOGV("- fork failed: pid(%d) %s -\n", *pid, strerror(errno)); adb_close(ptm); return -1; } if(*pid == 0){ int pts; setsid(); pts = unix_open(devname, O_RDWR); if(pts < 0) { fprintf(stderr, "child failed to open pseudo-term slave: %s\n", devname); XLOGV("child failed to open pseudo-term slave: %s\n", devname); exit(-1); } dup2(pts, 0); dup2(pts, 1); dup2(pts, 2); adb_close(pts); adb_close(ptm); // set OOM adjustment to zero char text[64]; snprintf(text, sizeof text, "/proc/%d/oom_adj", getpid()); int fd = adb_open(text, O_WRONLY); if (fd >= 0) { adb_write(fd, "0", 1); adb_close(fd); } else { D("adb: unable to open %s\n", text); XLOGW("adb: unable to open %s\n", text); } timer_t timerid; struct sigevent sev; /* Create the timer */ sev.sigev_notify = SIGEV_SIGNAL; sev.sigev_signo = SIGALRM; sev.sigev_value.sival_ptr = &timerid; if (timer_create(CLOCK_REALTIME, &sev, &timerid) == -1) { D("adb: Call timer_create failed!\n"); XLOGV("adb: Call timer_create failed!\n"); exit(-1); } struct itimerspec its; /* Start the timer */ its.it_value.tv_sec = 1; its.it_value.tv_nsec = 0; its.it_interval.tv_sec = 3; its.it_interval.tv_nsec = 0; if (timer_settime(timerid, 0, &its, NULL) == -1) { D("adb: Call timer_settime failed!\n"); XLOGV("adb: Call timer_settime failed!\n"); exit(-1); } sigset_t mask; struct sigaction sa; /* Establish handler for timer signal */ sa.sa_flags = SA_SIGINFO; sa.sa_sigaction = catcher; sigemptyset(&sa.sa_mask); if (sigaction(SIGALRM, &sa, NULL) == -1) { D("adb: Call sigaction failed!\n"); XLOGV("adb: Call sigaction failed!\n"); exit(-1); } int nRet = execl(cmd, cmd, arg0, arg1, NULL); fprintf(stderr, "- exec '%s' failed: %s (%d) nRet(%d) -\n", cmd, strerror(errno), errno, nRet); XLOGV("- exec '%s' failed: %s (%d) nRet(%d) -\n", cmd, strerror(errno), errno, nRet); exit(-1); } else { // Don't set child's OOM adjustment to zero. // Let the child do it itself, as sometimes the parent starts // running before the child has a /proc/pid/oom_adj. // """adb: unable to open /proc/644/oom_adj""" seen in some logs. return ptm; } #endif /* !HAVE_WIN32_PROC */ }
int service_to_fd(const char *name) { int ret = -1; #if !ADB_HOST XLOGV("service_to_fd() name=%s\n", name); #endif if(!strncmp(name, "tcp:", 4)) { int port = atoi(name + 4); name = strchr(name + 4, ':'); if(name == 0) { ret = socket_loopback_client(port, SOCK_STREAM); if (ret >= 0) disable_tcp_nagle(ret); } else { #if ADB_HOST adb_mutex_lock(&dns_lock); ret = socket_network_client(name + 1, port, SOCK_STREAM); adb_mutex_unlock(&dns_lock); #else return -1; #endif } #ifndef HAVE_WINSOCK /* winsock doesn't implement unix domain sockets */ } else if(!strncmp(name, "local:", 6)) { ret = socket_local_client(name + 6, ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM); } else if(!strncmp(name, "localreserved:", 14)) { ret = socket_local_client(name + 14, ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM); } else if(!strncmp(name, "localabstract:", 14)) { ret = socket_local_client(name + 14, ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM); } else if(!strncmp(name, "localfilesystem:", 16)) { ret = socket_local_client(name + 16, ANDROID_SOCKET_NAMESPACE_FILESYSTEM, SOCK_STREAM); #endif #if ADB_HOST } else if(!strncmp("dns:", name, 4)){ char *n = strdup(name + 4); if(n == 0) return -1; ret = create_service_thread(dns_service, n); #else /* !ADB_HOST */ } else if(!strncmp("dev:", name, 4)) { ret = unix_open(name + 4, O_RDWR); } else if(!strncmp(name, "framebuffer:", 12)) { ret = create_service_thread(framebuffer_service, 0); } else if(recovery_mode && !strncmp(name, "recover:", 8)) { ret = create_service_thread(recover_service, (void*) atoi(name + 8)); } else if (!strncmp(name, "jdwp:", 5)) { ret = create_jdwp_connection_fd(atoi(name+5)); } else if (!strncmp(name, "log:", 4)) { ret = create_service_thread(log_service, get_log_file_path(name + 4)); } else if(!HOST && !strncmp(name, "shell:", 6)) { if(name[6]) { ret = create_subproc_thread(name + 6); } else { ret = create_subproc_thread(0); } } else if(!strncmp(name, "sync:", 5)) { ret = create_service_thread(file_sync_service, NULL); } else if(!strncmp(name, "remount:", 8)) { ret = create_service_thread(remount_service, NULL); } else if(!strncmp(name, "reboot:", 7)) { void* arg = strdup(name + 7); if(arg == 0) return -1; ret = create_service_thread(reboot_service, arg); } else if(!strncmp(name, "root:", 5)) { ret = create_service_thread(restart_root_service, NULL); } else if(!strncmp(name, "backup:", 7)) { char* arg = strdup(name+7); if (arg == NULL) return -1; ret = backup_service(BACKUP, arg); } else if(!strncmp(name, "restore:", 8)) { ret = backup_service(RESTORE, NULL); } else if(!strncmp(name, "tcpip:", 6)) { int port; if (sscanf(name + 6, "%d", &port) == 0) { port = 0; } ret = create_service_thread(restart_tcp_service, (void *)port); } else if(!strncmp(name, "usb:", 4)) { ret = create_service_thread(restart_usb_service, NULL); #endif #if 0 } else if(!strncmp(name, "echo:", 5)){ ret = create_service_thread(echo_service, 0); #endif } if (ret >= 0) { close_on_exec(ret); } return ret; }