int adb_send_emulator_command(int argc, char **argv) { int fd, nn; fd = connect_to_console(); if (fd < 0) return 1; #define QUIT "quit\n" for (nn = 1; nn < argc; nn++) { adb_write(fd, argv[nn], strlen(argv[nn])); adb_write(fd, (nn == argc - 1) ? "\n" : " ", 1); } adb_write(fd, QUIT, sizeof(QUIT) - 1); adb_close(fd); return 0; }
int adb_send_emulator_command(int argc, char** argv) { int fd, nn; printf("function = %s, file = %s, line = %u \n", __FUNCTION__, __FILE__, __LINE__); fd = connect_to_console(); if (fd < 0) return 1; #define QUIT "quit\n" for (nn = 1; nn < argc; nn++) { adb_write( fd, argv[nn], strlen(argv[nn]) ); adb_write( fd, (nn == argc-1) ? "\n" : " ", 1 ); } adb_write( fd, QUIT, sizeof(QUIT)-1 ); adb_close(fd); return 0; }
int adb_send_emulator_command(int argc, const char** argv, const char* serial) { int fd = connect_to_console(serial); if (fd == -1) { return 1; } std::string commands = adb_construct_auth_command(); for (int i = 1; i < argc; i++) { commands.append(argv[i]); commands.push_back(i == argc - 1 ? '\n' : ' '); } commands.append("quit\n"); if (!WriteFdExactly(fd, commands)) { fprintf(stderr, "error: cannot write to emulator: %s\n", strerror(errno)); adb_close(fd); return 1; } // Drain output that the emulator console has sent us to prevent a problem // on Windows where if adb closes the socket without reading all the data, // the emulator's next call to recv() will have an ECONNABORTED error, // preventing the emulator from reading the command that adb has sent. // https://code.google.com/p/android/issues/detail?id=21021 int result; std::string emulator_output; do { char buf[BUFSIZ]; result = adb_read(fd, buf, sizeof(buf)); // Keep reading until zero bytes (orderly/graceful shutdown) or an // error. If 'adb emu kill' is executed, the emulator calls exit() with // the socket open (and shutdown(SD_SEND) was not called), which causes // Windows to send a TCP RST segment which causes adb to get ECONNRESET. // Any other emu command is followed by the quit command that we // appended above, and that causes the emulator to close the socket // which should cause zero bytes (orderly/graceful shutdown) to be // returned. if (result > 0) emulator_output.append(buf, result); } while (result > 0); // Note: the following messages are expected to be quite stable from emulator. // // Emulator console will send the following message upon connection: // // Android Console: Authentication required // Android Console: type 'auth <auth_token>' to authenticate // Android Console: you can find your <auth_token> in // '/<path-to-home>/.emulator_console_auth_token' // OK\r\n // // and the following after authentication: // Android Console: type 'help' for a list of commands // OK\r\n // // So try search and skip first two "OK\r\n", print the rest. // const std::string delims = "OK\r\n"; size_t found = 0; for (int i = 0; i < 2; ++i) { const size_t result = emulator_output.find(delims, found); if (result == std::string::npos) { break; } else { found = result + delims.size(); } } printf("%s", emulator_output.c_str() + found); adb_close(fd); return 0; }