static int jdwp_control_init( JdwpControl* control, const char* sockname, int socknamelen ) { struct sockaddr_un addr; socklen_t addrlen; int s; int maxpath = sizeof(addr.sun_path); int pathlen = socknamelen; if (pathlen >= maxpath) { D( "vm debug control socket name too long (%d extra chars)\n", pathlen+1-maxpath ); return -1; } memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; memcpy(addr.sun_path, sockname, socknamelen); s = socket( AF_UNIX, SOCK_STREAM, 0 ); if (s < 0) { D( "could not create vm debug control socket. %d: %s\n", errno, strerror(errno)); return -1; } addrlen = (pathlen + sizeof(addr.sun_family)); if (bind(s, (struct sockaddr*)&addr, addrlen) < 0) { D( "could not bind vm debug control socket: %d: %s\n", errno, strerror(errno) ); adb_close(s); return -1; } if ( listen(s, 4) < 0 ) { D("listen failed in jdwp control socket: %d: %s\n", errno, strerror(errno)); adb_close(s); return -1; } control->listen_socket = s; control->fde = fdevent_create(s, jdwp_control_event, control); if (control->fde == NULL) { D( "could not create fdevent for jdwp control socket\n" ); adb_close(s); return -1; } /* only wait for incoming connections */ fdevent_add(control->fde, FDE_READ); close_on_exec(s); D("jdwp control socket started (%d)\n", control->listen_socket); return 0; }
static void fdevent_subproc_event_func(int fd, unsigned ev, void* /* userdata */) { ADB_LOGD(ADB_FDEV, "subproc handling on fd=%d ev=%04x", fd, ev); // Hook oneself back into the fde's suitable for select() on read. if ((fd < 0) || (fd >= fd_table_max)) { FATAL("fd %d out of range for fd_table", fd); } fdevent *fde = fd_table[fd]; fdevent_add(fde, FDE_READ); if (ev & FDE_READ) { int subproc_fd; if (!ReadFdExactly(fd, &subproc_fd, sizeof(subproc_fd))) { FATAL("Failed to read the subproc's fd from fd=%d", fd); } if ((subproc_fd < 0) || (subproc_fd >= fd_table_max)) { ADB_LOGD(ADB_FDEV, "subproc_fd %d out of range 0, fd_table_max=%d", subproc_fd, fd_table_max); return; } fdevent *subproc_fde = fd_table[subproc_fd]; if (!subproc_fde) { ADB_LOGD(ADB_FDEV, "subproc_fd %d cleared from fd_table", subproc_fd); return; } if (subproc_fde->fd != subproc_fd) { // Already reallocated? ADB_LOGD(ADB_FDEV, "subproc_fd %d != fd_table[].fd %d", subproc_fd, subproc_fde->fd); return; } subproc_fde->force_eof = 1; int rcount = 0; ioctl(subproc_fd, FIONREAD, &rcount); ADB_LOGD(ADB_FDEV, "subproc with fd=%d has rcount=%d err=%d", subproc_fd, rcount, errno); if (rcount) { // If there is data left, it will show up in the select(). // This works because there is no other thread reading that // data when in this fd_func(). return; } ADB_LOGD(ADB_FDEV, "subproc_fde.state=%04x", subproc_fde->state); subproc_fde->events |= FDE_READ; if (subproc_fde->state & FDE_PENDING) { return; } subproc_fde->state |= FDE_PENDING; fdevent_call_fdfunc(subproc_fde); } }
static void local_socket_ready(asocket *s) { /* far side is ready for data, pay attention to readable events */ fdevent_add(&s->fde, FDE_READ); // D("LS(%d): ready()\n", s->id); }
static void InvalidFdThreadFunc(void*) { const int INVALID_READ_FD = std::numeric_limits<int>::max() - 1; size_t happened_event_count = 0; InvalidFdArg read_arg; read_arg.expected_events = FDE_READ | FDE_ERROR; read_arg.happened_event_count = &happened_event_count; fdevent_install(&read_arg.fde, INVALID_READ_FD, InvalidFdEventCallback, &read_arg); fdevent_add(&read_arg.fde, FDE_READ); const int INVALID_WRITE_FD = std::numeric_limits<int>::max(); InvalidFdArg write_arg; write_arg.expected_events = FDE_READ | FDE_ERROR; write_arg.happened_event_count = &happened_event_count; fdevent_install(&write_arg.fde, INVALID_WRITE_FD, InvalidFdEventCallback, &write_arg); fdevent_add(&write_arg.fde, FDE_WRITE); fdevent_loop(); }
explicit JdwpProcess(int socket) { this->socket = socket; this->fde = fdevent_create(socket, jdwp_process_event, this); if (!this->fde) { LOG(FATAL) << "could not create fdevent for new JDWP process"; } /* start by waiting for the PID */ fdevent_add(this->fde, FDE_READ); }
static int local_socket_enqueue(asocket* s, apacket* p) { D("LS(%d): enqueue %zu", s->id, p->len); p->ptr = p->data; /* if there is already data queue'd, we will receive ** events when it's time to write. just add this to ** the tail */ if (s->pkt_first) { goto enqueue; } /* write as much as we can, until we ** would block or there is an error/eof */ while (p->len > 0) { int r = adb_write(s->fd, p->ptr, p->len); if (r > 0) { p->len -= r; p->ptr += r; continue; } if ((r == 0) || (errno != EAGAIN)) { D("LS(%d): not ready, errno=%d: %s", s->id, errno, strerror(errno)); put_apacket(p); s->has_write_error = true; s->close(s); return 1; /* not ready (error) */ } else { break; } } if (p->len == 0) { put_apacket(p); return 0; /* ready for more data */ } enqueue: p->next = 0; if (s->pkt_first) { s->pkt_last->next = p; } else { s->pkt_first = p; } s->pkt_last = p; /* make sure we are notified when we can drain the queue */ fdevent_add(&s->fde, FDE_WRITE); return 1; /* not ready (backlog) */ }
void fdevent_subproc_setup() { int s[2]; if(adb_socketpair(s)) { FATAL("cannot create shell-exit socket-pair\n"); } SHELL_EXIT_NOTIFY_FD = s[0]; fdevent *fde; fde = fdevent_create(s[1], fdevent_subproc_event_func, NULL); if(!fde) FATAL("cannot create fdevent for shell-exit handler\n"); fdevent_add(fde, FDE_READ); }
void fdevent_subproc_setup() { int s[2]; if(adb_socketpair(s)) { PLOG(FATAL) << "cannot create shell-exit socket-pair"; } D("fdevent_subproc: socket pair (%d, %d)", s[0], s[1]); SHELL_EXIT_NOTIFY_FD = s[0]; fdevent *fde = fdevent_create(s[1], fdevent_subproc_event_func, NULL); CHECK(fde != nullptr) << "cannot create fdevent for shell-exit handler"; fdevent_add(fde, FDE_READ); }
void adbd_auth_init(void) { int fd = android_get_control_socket("adbd"); if (fd == -1) { PLOG(ERROR) << "Failed to get adbd socket"; return; } if (listen(fd, 4) == -1) { PLOG(ERROR) << "Failed to listen on '" << fd << "'"; return; } listener_fde = fdevent_create(fd, adbd_auth_listener, nullptr); fdevent_add(listener_fde, FDE_READ); }
void fdevent_subproc_setup() { printf("function = %s, file = %s, line = %u \n", __FUNCTION__, __FILE__, __LINE__); int s[2]; if(adb_socketpair(s)) { FATAL("cannot create shell-exit socket-pair\n"); } SHELL_EXIT_NOTIFY_FD = s[0]; fdevent *fde; printf("function = %s, file = %s, line = %u before fdevent_create\n", __FUNCTION__, __FILE__, __LINE__); fde = fdevent_create(s[1], fdevent_subproc_event_func, NULL); if(!fde) FATAL("cannot create fdevent for shell-exit handler\n"); printf("function = %s, file = %s, line = %u before fdevent_add\n", __FUNCTION__, __FILE__, __LINE__); fdevent_add(fde, FDE_READ); }
void fdevent_subproc_setup() { int s[2]; if (adb_socketpair(s)) { FATAL("cannot create shell-exit socket-pair"); } ADB_LOGD(ADB_FDEV, "socketpair: (%d,%d)", s[0], s[1]); SHELL_EXIT_NOTIFY_FD = s[0]; fdevent *fde; fde = fdevent_create(s[1], fdevent_subproc_event_func, NULL); if (!fde) { FATAL("cannot create fdevent for shell-exit handler"); } fdevent_add(fde, FDE_READ); }
static void local_socket_ready(asocket *s) { /* far side is ready for data, pay attention to readable events */ bool bFound = false; int i = 0; for(i = 0; i < READY_ARRAY_SIZE; ++i){ if(fd_ready_array[i] == s->fde.fd){ //Do not need to update array bFound = true; break; } } if(bFound == false){ if(fd_ready_idx > READY_ARRAY_SIZE - 1){ //Out of range, so we have to print fd directly XLOGD("Too many local_socket_ready fd=%d, ", s->fde.fd); }else{ fd_ready_array[fd_ready_idx] = s->fde.fd; fd_ready_idx++; } } fdevent_add(&s->fde, FDE_READ); clock_t this_ready_time = clock(); double cpu_time_used = ((double) (this_ready_time - last_ready_time)) / CLOCKS_PER_SEC; if( cpu_time_used > 5.0 ){ char output_log[512]; char tmp[16]; sprintf(output_log, "%s", "adb local_socket_ready list "); int i = 0; for(i = 0; i < fd_ready_idx; ++i){ sprintf(tmp, "(%d) ", fd_ready_array[i]); strcat(output_log, tmp); fd_ready_array[i] = 0; } XLOGD("%s\n", output_log); last_ready_time = this_ready_time; fd_ready_idx = 0; } // D("LS(%d): ready()\n", s->id); }
static void adbd_auth_listener(int fd, unsigned events, void* data) { int s = adb_socket_accept(fd, nullptr, nullptr); if (s < 0) { PLOG(ERROR) << "Failed to accept"; return; } if (framework_fd >= 0) { LOG(WARNING) << "adb received framework auth socket connection again"; framework_disconnected(); } framework_fd = s; framework_fde = fdevent_create(framework_fd, adbd_auth_event, nullptr); fdevent_add(framework_fde, FDE_READ); if (needs_retry) { needs_retry = false; send_auth_request(usb_transport); } }
static void FdEventCallback(int fd, unsigned events, void* userdata) { FdHandler* handler = reinterpret_cast<FdHandler*>(userdata); ASSERT_EQ(0u, (events & ~(FDE_READ | FDE_WRITE))) << "unexpected events: " << events; if (events & FDE_READ) { ASSERT_EQ(fd, handler->read_fd_); char c; ASSERT_EQ(1, read(fd, &c, 1)); handler->queue_.push(c); fdevent_add(&handler->write_fde_, FDE_WRITE); } if (events & FDE_WRITE) { ASSERT_EQ(fd, handler->write_fd_); ASSERT_FALSE(handler->queue_.empty()); char c = handler->queue_.front(); handler->queue_.pop(); ASSERT_EQ(1, write(fd, &c, 1)); if (handler->queue_.empty()) { fdevent_del(&handler->write_fde_, FDE_WRITE); } } }
static JdwpProcess* jdwp_process_alloc( int socket ) { JdwpProcess* proc = reinterpret_cast<JdwpProcess*>( calloc(1, sizeof(*proc))); if (proc == NULL) { D("not enough memory to create new JDWP process\n"); return NULL; } proc->socket = socket; proc->pid = -1; proc->next = proc; proc->prev = proc; proc->fde = fdevent_create( socket, jdwp_process_event, proc ); if (proc->fde == NULL) { D("could not create fdevent for new JDWP process\n" ); free(proc); return NULL; } proc->fde->state |= FDE_DONT_CLOSE; proc->in_len = 0; proc->out_count = 0; /* append to list */ proc->next = &_jdwp_list; proc->prev = proc->next->prev; proc->prev->next = proc; proc->next->prev = proc; /* start by waiting for the PID */ fdevent_add(proc->fde, FDE_READ); return proc; }
int create_jdwp_connection_fd(int pid) { JdwpProcess* proc = _jdwp_list.next; D("looking for pid %d in JDWP process list\n", pid); for ( ; proc != &_jdwp_list; proc = proc->next ) { if (proc->pid == pid) { goto FoundIt; } } D("search failed !!\n"); return -1; FoundIt: { int fds[2]; if (proc->out_count >= MAX_OUT_FDS) { D("%s: too many pending JDWP connection for pid %d\n", __FUNCTION__, pid); return -1; } if (adb_socketpair(fds) < 0) { D("%s: socket pair creation failed: %s\n", __FUNCTION__, strerror(errno)); return -1; } D("socketpair: (%d,%d)", fds[0], fds[1]); proc->out_fds[ proc->out_count ] = fds[1]; if (++proc->out_count == 1) fdevent_add( proc->fde, FDE_WRITE ); return fds[0]; } }
unique_fd create_jdwp_connection_fd(int pid) { D("looking for pid %d in JDWP process list", pid); for (auto& proc : _jdwp_list) { if (proc->pid == pid) { int fds[2]; if (adb_socketpair(fds) < 0) { D("%s: socket pair creation failed: %s", __FUNCTION__, strerror(errno)); return unique_fd{}; } D("socketpair: (%d,%d)", fds[0], fds[1]); proc->out_fds.emplace_back(fds[1]); if (proc->out_fds.size() == 1) { fdevent_add(proc->fde, FDE_WRITE); } return unique_fd{fds[0]}; } } D("search failed !!"); return unique_fd{}; }
FdHandler(int read_fd, int write_fd) : read_fd_(read_fd), write_fd_(write_fd) { fdevent_install(&read_fde_, read_fd_, FdEventCallback, this); fdevent_add(&read_fde_, FDE_READ); fdevent_install(&write_fde_, write_fd_, FdEventCallback, this); }
static int local_socket_enqueue(asocket *s, apacket *p) { D("LS(%d): enqueue %d\n", s->id, p->len); p->ptr = p->data; /* if there is already data queue'd, we will receive ** events when it's time to write. just add this to ** the tail */ if(s->pkt_first) { goto enqueue; } //check if in the array bool bFound = false; int i = 0; for(i = 0; i < FD_ARRAY_SIZE; ++i){ if(fd_write_array[i] == s->fd){ //Do not need to update array bFound = true; break; } } if(bFound == false){ if(fd_write_idx > FD_ARRAY_SIZE - 1){ //Out of range, so we have to print fd directly XLOGD("Too many write adb socket fd=%d, ", s->fd); }else{ fd_write_array[fd_write_idx] = s->fd; fd_write_idx++; } } /* write as much as we can, until we ** would block or there is an error/eof */ while(p->len > 0) { int r = adb_write(s->fd, p->ptr, p->len); if(r > 0) { p->len -= r; p->ptr += r; write_data += r; continue; } if((r == 0) || (errno != EAGAIN)) { D( "LS(%d): not ready, errno=%d: %s\n", s->id, errno, strerror(errno) ); XLOGW( "LS(%d): not ready, errno=%d: %s\n", s->id, errno, strerror(errno) ); s->close(s); return 1; /* not ready (error) */ } else { break; } } clock_t this_write_time = clock(); double cpu_time_used = ((double) (this_write_time - last_write_time)) / CLOCKS_PER_SEC; if( cpu_time_used > 10.0 ) { char output_log[512]; char tmp[16]; sprintf(output_log, "%s", "adb socket write list "); int i = 0; for(i = 0; i < fd_write_idx; ++ i){ sprintf(tmp, "(%d) ", fd_write_array[i]); strcat(output_log, tmp); //XLOGD("adb socket write fd=%d, ", fd_write_array[i]); fd_write_array[i] = 0; } XLOGD("%s\n", output_log); XLOGD("write_data=%d\n", write_data); last_write_time = this_write_time; write_data = 0; fd_write_idx = 0; } if(p->len == 0) { put_apacket(p); return 0; /* ready for more data */ } enqueue: p->next = 0; if(s->pkt_first) { s->pkt_last->next = p; } else { s->pkt_first = p; } s->pkt_last = p; /* make sure we are notified when we can drain the queue */ fdevent_add(&s->fde, FDE_WRITE); return 1; /* not ready (backlog) */ }