static bool do_recv(int s, const char* path, std::vector<char>& buffer) { int fd = adb_open(path, O_RDONLY | O_CLOEXEC); if (fd < 0) { SendSyncFailErrno(s, "open failed"); return false; } syncmsg msg; msg.data.id = ID_DATA; while (true) { int r = adb_read(fd, &buffer[0], buffer.size()); if (r <= 0) { if (r == 0) break; SendSyncFailErrno(s, "read failed"); adb_close(fd); return false; } msg.data.size = r; if (!WriteFdExactly(s, &msg.data, sizeof(msg.data)) || !WriteFdExactly(s, &buffer[0], r)) { adb_close(fd); return false; } } adb_close(fd); msg.data.id = ID_DONE; msg.data.size = 0; return WriteFdExactly(s, &msg.data, sizeof(msg.data)); }
static int get_target_device_size(int fd, const char *blk_device, uint64_t *device_size) { int data_device; struct ext4_super_block sb; struct fs_info info; info.len = 0; /* Only len is set to 0 to ask the device for real size. */ data_device = adb_open(blk_device, O_RDONLY | O_CLOEXEC); if (data_device < 0) { write_console(fd, "Error opening block device (%s)\n", strerror(errno)); return -1; } if (lseek64(data_device, 1024, SEEK_SET) < 0) { write_console(fd, "Error seeking to superblock\n"); adb_close(data_device); return -1; } if (adb_read(data_device, &sb, sizeof(sb)) != sizeof(sb)) { write_console(fd, "Error reading superblock\n"); adb_close(data_device); return -1; } ext4_parse_sb(&sb, &info); *device_size = info.len; adb_close(data_device); return 0; }
static int restore(int argc, char** argv) { const char* filename; int fd, tarFd; if (argc != 2) return usage(); filename = argv[1]; tarFd = adb_open(filename, O_RDONLY); if (tarFd < 0) { fprintf(stderr, "adb: unable to open file %s\n", filename); return -1; } fd = adb_connect("restore:"); if (fd < 0) { fprintf(stderr, "adb: unable to connect for backup\n"); adb_close(tarFd); return -1; } printf("Now unlock your device and confirm the restore operation.\n"); copy_to_file(tarFd, fd); adb_close(fd); adb_close(tarFd); return 0; }
static int write_data_file(int fd, const char *path, syncsendbuf *sbuf, int show_progress) { int lfd, err = 0; unsigned long long size = 0; lfd = adb_open(path, O_RDONLY); if(lfd < 0) { fprintf(stderr,"cannot open '%s': %s\n", path, strerror(errno)); return -1; } if (show_progress) { // Determine local file size. struct stat st; if (fstat(lfd, &st)) { fprintf(stderr,"cannot stat '%s': %s\n", path, strerror(errno)); return -1; } size = st.st_size; } sbuf->id = ID_DATA; for(;;) { int ret; ret = adb_read(lfd, sbuf->data, SYNC_DATA_MAX); if(!ret) break; if(ret < 0) { if(errno == EINTR) continue; fprintf(stderr,"cannot read '%s': %s\n", path, strerror(errno)); break; } sbuf->size = htoll(ret); if(writex(fd, sbuf, sizeof(unsigned) * 2 + ret)){ err = -1; break; } total_bytes += ret; if (show_progress) { print_transfer_progress(total_bytes, size); } } adb_close(lfd); return err; }
static void init_subproc_child() { setsid(); // Set OOM score adjustment to prevent killing int fd = adb_open("/proc/self/oom_score_adj", O_WRONLY | O_CLOEXEC); if (fd >= 0) { adb_write(fd, "0", 1); adb_close(fd); } else { D("adb: unable to update oom_score_adj\n"); } }
TEST(adb_utils, set_file_block_mode) { int fd = adb_open("/dev/null", O_RDWR | O_APPEND); ASSERT_GE(fd, 0); int flags = fcntl(fd, F_GETFL, 0); ASSERT_EQ(O_RDWR | O_APPEND, (flags & (O_RDWR | O_APPEND))); ASSERT_TRUE(set_file_block_mode(fd, false)); int new_flags = fcntl(fd, F_GETFL, 0); ASSERT_EQ(flags | O_NONBLOCK, new_flags); ASSERT_TRUE(set_file_block_mode(fd, true)); new_flags = fcntl(fd, F_GETFL, 0); ASSERT_EQ(flags, new_flags); ASSERT_EQ(0, adb_close(fd)); }
static int sysfs_write(const char *node, const char *message) { int fd; ssize_t to_write; int ret = 0; fd = adb_open(node, O_RDWR); if (!fd) { D("open '%s' failed: %s\n", node, strerror(errno)); return -1; } to_write = strlen(message); if (adb_write(fd, message, to_write) != to_write) { D("write '%s' failed: %s\n", node, strerror(errno)); ret = -1; } adb_close(fd); return ret; }
static int write_data_file(int fd, const char *path, syncsendbuf *sbuf) { int lfd, err = 0; lfd = adb_open(path, O_RDONLY); if(lfd < 0) { fprintf(stderr,"cannot open '%s': %s\n", path, strerror(errno)); return -1; } sbuf->id = ID_DATA; for(;;) { int ret; ret = adb_read(lfd, sbuf->data, SYNC_DATA_MAX); if(!ret) break; if(ret < 0) { if(errno == EINTR) continue; fprintf(stderr,"cannot read '%s': %s\n", path, strerror(errno)); break; } sbuf->size = htoll(ret); if(writex(fd, sbuf, sizeof(unsigned) * 2 + ret)){ err = -1; break; } total_bytes += ret; STATUS(); } adb_close(lfd); return err; }
static int do_send(int s, char *path, char *buffer) { char *tmp; unsigned int mode; int is_link, ret; bool do_unlink; tmp = strrchr(path,','); if(tmp) { *tmp = 0; errno = 0; mode = strtoul(tmp + 1, NULL, 0); #ifndef HAVE_SYMLINKS is_link = 0; #else is_link = S_ISLNK((mode_t) mode); #endif mode &= 0777; } if(!tmp || errno) { mode = 0644; is_link = 0; do_unlink = true; } else { struct stat st; /* Don't delete files before copying if they are not "regular" */ do_unlink = lstat(path, &st) || S_ISREG(st.st_mode) || S_ISLNK(st.st_mode); if (do_unlink) { adb_unlink(path); } } #ifdef HAVE_SYMLINKS if(is_link) ret = handle_send_link(s, path, buffer); else { #else { #endif uid_t uid = -1; gid_t gid = -1; uint64_t cap = 0; /* copy user permission bits to "group" and "other" permissions */ mode |= ((mode >> 3) & 0070); mode |= ((mode >> 3) & 0007); tmp = path; if(*tmp == '/') { tmp++; } if (is_on_system(path) || is_on_vendor(path)) { fs_config(tmp, 0, &uid, &gid, &mode, &cap); } ret = handle_send_file(s, path, uid, gid, mode, buffer, do_unlink); } return ret; } static int do_recv(int s, const char *path, char *buffer) { syncmsg msg; int fd, r; fd = adb_open(path, O_RDONLY | O_CLOEXEC); if(fd < 0) { if(fail_errno(s)) return -1; return 0; } msg.data.id = ID_DATA; for(;;) { if(syc_size_enabled == 1) { r = adb_read(fd, buffer, SYNC_DATA_MAX_CUSTOMIZE); } else { r = adb_read(fd, buffer, SYNC_DATA_MAX); } if(r <= 0) { if(r == 0) break; if(errno == EINTR) continue; r = fail_errno(s); adb_close(fd); return r; } msg.data.size = htoll(r); if(writex(s, &msg.data, sizeof(msg.data)) || writex(s, buffer, r)) { adb_close(fd); return -1; } } adb_close(fd); msg.data.id = ID_DONE; msg.data.size = 0; if(writex(s, &msg.data, sizeof(msg.data))) { return -1; } return 0; }
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 */ }
static int sync_send(int fd, const char *lpath, const char *rpath, unsigned mtime, mode_t mode, int verifyApk) { syncmsg msg; int len, r; syncsendbuf *sbuf = &send_buffer; char* file_buffer = NULL; int size = 0; char tmp[64]; len = strlen(rpath); if(len > 1024) goto fail; snprintf(tmp, sizeof(tmp), ",%d", mode); r = strlen(tmp); if (verifyApk) { int lfd; zipfile_t zip; zipentry_t entry; int amt; // if we are transferring an APK file, then sanity check to make sure // we have a real zip file that contains an AndroidManifest.xml // this requires that we read the entire file into memory. lfd = adb_open(lpath, O_RDONLY); if(lfd < 0) { fprintf(stderr,"cannot open '%s': %s\n", lpath, strerror(errno)); return -1; } size = adb_lseek(lfd, 0, SEEK_END); if (size == -1 || -1 == adb_lseek(lfd, 0, SEEK_SET)) { fprintf(stderr, "error seeking in file '%s'\n", lpath); adb_close(lfd); return 1; } file_buffer = (char *)malloc(size); if (file_buffer == NULL) { fprintf(stderr, "could not allocate buffer for '%s'\n", lpath); adb_close(lfd); return 1; } amt = adb_read(lfd, file_buffer, size); if (amt != size) { fprintf(stderr, "error reading from file: '%s'\n", lpath); adb_close(lfd); free(file_buffer); return 1; } adb_close(lfd); zip = init_zipfile(file_buffer, size); if (zip == NULL) { fprintf(stderr, "file '%s' is not a valid zip file\n", lpath); free(file_buffer); return 1; } entry = lookup_zipentry(zip, "AndroidManifest.xml"); release_zipfile(zip); if (entry == NULL) { fprintf(stderr, "file '%s' does not contain AndroidManifest.xml\n", lpath); free(file_buffer); return 1; } } msg.req.id = ID_SEND; msg.req.namelen = htoll(len + r); if(writex(fd, &msg.req, sizeof(msg.req)) || writex(fd, rpath, len) || writex(fd, tmp, r)) { free(file_buffer); goto fail; } if (file_buffer) { write_data_buffer(fd, file_buffer, size, sbuf); free(file_buffer); } else if (S_ISREG(mode)) write_data_file(fd, lpath, sbuf); #ifdef HAVE_SYMLINKS else if (S_ISLNK(mode)) write_data_link(fd, lpath, sbuf); #endif else goto fail; msg.data.id = ID_DONE; msg.data.size = htoll(mtime); if(writex(fd, &msg.data, sizeof(msg.data))) goto fail; if(readx(fd, &msg.status, sizeof(msg.status))) return -1; if(msg.status.id != ID_OKAY) { if(msg.status.id == ID_FAIL) { len = ltohl(msg.status.msglen); if(len > 256) len = 256; if(readx(fd, sbuf->data, len)) { return -1; } sbuf->data[len] = 0; } else strcpy(sbuf->data, "unknown reason"); fprintf(stderr,"failed to copy '%s' to '%s': %s\n", lpath, rpath, sbuf->data); return -1; } return 0; fail: fprintf(stderr,"protocol failure\n"); adb_close(fd); return -1; }
/* Turn verity on/off */ static int set_verity_enabled_state(int fd, const char *block_device, const char* mount_point, bool enable) { uint32_t magic_number; const uint32_t new_magic = enable ? VERITY_METADATA_MAGIC_NUMBER : VERITY_METADATA_MAGIC_DISABLE; uint64_t device_length = 0; int device = -1; int retval = -1; if (make_block_device_writable(block_device)) { write_console(fd, "Could not make block device %s writable (%s).\n", block_device, strerror(errno)); goto errout; } device = adb_open(block_device, O_RDWR | O_CLOEXEC); if (device == -1) { write_console(fd, "Could not open block device %s (%s).\n", block_device, strerror(errno)); write_console(fd, "Maybe run adb remount?\n"); goto errout; } // find the start of the verity metadata if (get_target_device_size(fd, (char*)block_device, &device_length) < 0) { write_console(fd, "Could not get target device size.\n"); goto errout; } if (lseek64(device, device_length, SEEK_SET) < 0) { write_console(fd, "Could not seek to start of verity metadata block.\n"); goto errout; } // check the magic number if (adb_read(device, &magic_number, sizeof(magic_number)) != sizeof(magic_number)) { write_console(fd, "Couldn't read magic number!\n"); goto errout; } if (!enable && magic_number == VERITY_METADATA_MAGIC_DISABLE) { write_console(fd, "Verity already disabled on %s\n", mount_point); goto errout; } if (enable && magic_number == VERITY_METADATA_MAGIC_NUMBER) { write_console(fd, "Verity already enabled on %s\n", mount_point); goto errout; } if (magic_number != VERITY_METADATA_MAGIC_NUMBER && magic_number != VERITY_METADATA_MAGIC_DISABLE) { write_console(fd, "Couldn't find verity metadata at offset %" PRIu64 "!\n", device_length); goto errout; } if (lseek64(device, device_length, SEEK_SET) < 0) { write_console(fd, "Could not seek to start of verity metadata block.\n"); goto errout; } if (adb_write(device, &new_magic, sizeof(new_magic)) != sizeof(new_magic)) { write_console( fd, "Could not set verity %s flag on device %s with error %s\n", enable ? "enabled" : "disabled", block_device, strerror(errno)); goto errout; } write_console(fd, "Verity %s on %s\n", enable ? "enabled" : "disabled", mount_point); retval = 0; errout: if (device != -1) adb_close(device); return retval; }
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 */ }
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 do_send(int s, char *path, char *buffer) { char *tmp; mode_t mode; int is_link, ret; tmp = strrchr(path,','); if(tmp) { *tmp = 0; errno = 0; mode = strtoul(tmp + 1, NULL, 0); #ifndef HAVE_SYMLINKS is_link = 0; #else is_link = S_ISLNK(mode); #endif mode &= 0777; } if(!tmp || errno) { mode = 0644; is_link = 0; } adb_unlink(path); #ifdef HAVE_SYMLINKS if(is_link) ret = handle_send_link(s, path, buffer); else { #else { #endif /* copy user permission bits to "group" and "other" permissions */ mode |= ((mode >> 3) & 0070); mode |= ((mode >> 3) & 0007); ret = handle_send_file(s, path, mode, buffer); } return ret; } static int do_recv(int s, const char *path, char *buffer) { syncmsg msg; int fd, r; fd = adb_open(path, O_RDONLY); if(fd < 0) { if(fail_errno(s)) return -1; return 0; } msg.data.id = ID_DATA; for(;;) { r = adb_read(fd, buffer, SYNC_DATA_MAX); if(r <= 0) { if(r == 0) break; if(errno == EINTR) continue; r = fail_errno(s); adb_close(fd); return r; } msg.data.size = htoll(r); if(writex(s, &msg.data, sizeof(msg.data)) || writex(s, buffer, r)) { adb_close(fd); return -1; } } adb_close(fd); msg.data.id = ID_DONE; msg.data.size = 0; if(writex(s, &msg.data, sizeof(msg.data))) { return -1; } return 0; }
int adb_main(int is_daemon) { #if !ADB_HOST int secure = 0; char value[PROPERTY_VALUE_MAX]; // prevent the OOM killer from killing us char text[64]; snprintf(text, sizeof text, "/proc/%d/oom_adj", (int)getpid()); int fd = adb_open(text, O_WRONLY); if (fd >= 0) { // -17 should make us immune to OOM snprintf(text, sizeof text, "%d", -17); adb_write(fd, text, strlen(text)); adb_close(fd); } else { D("adb: unable to open %s\n", text); } #endif atexit(adb_cleanup); #ifdef HAVE_WIN32_PROC SetConsoleCtrlHandler( ctrlc_handler, TRUE ); #elif defined(HAVE_FORKEXEC) signal(SIGCHLD, sigchld_handler); signal(SIGPIPE, SIG_IGN); #endif init_transport_registration(); #if ADB_HOST HOST = 1; usb_init(); local_init(); if(install_listener("tcp:5037", "*smartsocket*", NULL)) { exit(1); } #else /* run adbd in secure mode if ro.secure is set and ** we are not in the emulator */ property_get("ro.kernel.qemu", value, ""); if (strcmp(value, "1") != 0) { property_get("ro.secure", value, ""); if (strcmp(value, "1") == 0) { // don't run as root if ro.secure is set... secure = 1; // ... except we allow running as root in userdebug builds if the // service.adb.root property has been set by the "adb root" command property_get("ro.debuggable", value, ""); if (strcmp(value, "1") == 0) { property_get("service.adb.root", value, ""); if (strcmp(value, "1") == 0) { secure = 0; } } } } /* don't listen on port 5037 if we are running in secure mode */ /* don't run as root if we are running in secure mode */ if (secure) { /* add extra groups: ** AID_ADB to access the USB driver ** AID_LOG to read system logs (adb logcat) ** AID_INPUT to diagnose input issues (getevent) ** AID_INET to diagnose network issues (netcfg, ping) ** AID_GRAPHICS to access the frame buffer ** AID_NET_BT and AID_NET_BT_ADMIN to diagnose bluetooth (hcidump) */ gid_t groups[] = { AID_ADB, AID_LOG, AID_INPUT, AID_INET, AID_GRAPHICS, AID_NET_BT, AID_NET_BT_ADMIN }; setgroups(sizeof(groups)/sizeof(groups[0]), groups); /* then switch user and group to "shell" */ setgid(AID_SHELL); setuid(AID_SHELL); D("Local port 5037 disabled\n"); } else { if(install_listener("tcp:5037", "*smartsocket*", NULL)) { exit(1); } } /* for the device, start the usb transport if the ** android usb device exists, otherwise start the ** network transport. */ if(access("/dev/android_adb", F_OK) == 0 || access("/dev/android", F_OK) == 0) { usb_init(); } else { local_init(); } init_jdwp(); #endif if (is_daemon) { // inform our parent that we are up and running. #ifdef HAVE_WIN32_PROC DWORD count; WriteFile( GetStdHandle( STD_OUTPUT_HANDLE ), "OK\n", 3, &count, NULL ); #elif defined(HAVE_FORKEXEC) fprintf(stderr, "OK\n"); #endif start_logging(); } fdevent_loop(); usb_cleanup(); return 0; }