summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosh Gao <jmgao@google.com>2015-11-20 15:37:31 -0800
committerJosh Gao <jmgao@google.com>2015-12-10 12:52:06 -0800
commit09b4a3b561094d1b15c1fa2c74ffb04bdb9278b8 (patch)
tree6775770fff996f57215070b4cf8dbe18094b364a
parente821a5d6eaf21382c4fdd70cf6fc88cf82798939 (diff)
downloadadb-09b4a3b561094d1b15c1fa2c74ffb04bdb9278b8.tar.gz
adb: shell: add -n flag to not read from stdin.
Shell scripts of the following form do not work properly with adb: echo "foo\nbar\nbaz" | { read FOO while [ "$FOO" != "" ]; do adb shell echo $FOO read FOO done } The first run of adb shell will consume all of the contents of stdin, causing the loop to immediately end. ssh solves this by providing a -n flag that causes it to not read from stdin. This commit adds the same. Bug: http://b/25817224 Change-Id: Id74ca62ef520bcf03678b50f4bf203916fd81038
-rw-r--r--adb_utils.cpp19
-rw-r--r--adb_utils.h2
-rw-r--r--client/main.cpp16
-rw-r--r--commandline.cpp8
-rw-r--r--daemon/main.cpp11
5 files changed, 30 insertions, 26 deletions
diff --git a/adb_utils.cpp b/adb_utils.cpp
index 42f1c7d..1c3526b 100644
--- a/adb_utils.cpp
+++ b/adb_utils.cpp
@@ -30,12 +30,31 @@
#include <base/stringprintf.h>
#include <base/strings.h>
+#include "adb.h"
#include "adb_trace.h"
#include "sysdeps.h"
ADB_MUTEX_DEFINE(basename_lock);
ADB_MUTEX_DEFINE(dirname_lock);
+#if defined(_WIN32)
+constexpr char kNullFileName[] = "NUL";
+#else
+constexpr char kNullFileName[] = "/dev/null";
+#endif
+
+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);
+}
+
bool getcwd(std::string* s) {
char* cwd = getcwd(nullptr, 0);
if (cwd != nullptr) *s = cwd;
diff --git a/adb_utils.h b/adb_utils.h
index 537d0e4..388d7dd 100644
--- a/adb_utils.h
+++ b/adb_utils.h
@@ -19,6 +19,8 @@
#include <string>
+void close_stdin();
+
bool getcwd(std::string* cwd);
bool directory_exists(const std::string& path);
diff --git a/client/main.cpp b/client/main.cpp
index 04b9882..1ac6e82 100644
--- a/client/main.cpp
+++ b/client/main.cpp
@@ -34,11 +34,10 @@
#include "adb.h"
#include "adb_auth.h"
#include "adb_listeners.h"
+#include "adb_utils.h"
#include "transport.h"
#if defined(_WIN32)
-static const char kNullFileName[] = "NUL";
-
static BOOL WINAPI ctrlc_handler(DWORD type) {
// TODO: Consider trying to kill a starting up adb server (if we're in
// launch_server) by calling GenerateConsoleCtrlEvent().
@@ -66,24 +65,11 @@ static std::string GetLogFilePath() {
return temp_path_utf8 + log_name;
}
#else
-static const char kNullFileName[] = "/dev/null";
-
static std::string GetLogFilePath() {
return std::string("/tmp/adb.log");
}
#endif
-static void close_stdin() {
- int fd = unix_open(kNullFileName, O_RDONLY);
- if (fd == -1) {
- fatal("cannot open '%s': %s", kNullFileName, strerror(errno));
- }
- if (dup2(fd, STDIN_FILENO) == -1) {
- fatal("cannot redirect stdin: %s", strerror(errno));
- }
- unix_close(fd);
-}
-
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);
diff --git a/commandline.cpp b/commandline.cpp
index bd3813e..a43b6ab 100644
--- a/commandline.cpp
+++ b/commandline.cpp
@@ -112,9 +112,10 @@ static void help() {
" (-a preserves file timestamp and mode)\n"
" adb sync [ <directory> ] - copy host->device only if changed\n"
" (-l means list but don't copy)\n"
- " adb shell [-e escape] [-Tt] [-x] [command]\n"
+ " adb shell [-e escape] [-n] [-Tt] [-x] [command]\n"
" - run remote shell command (interactive shell if no command given)\n"
" (-e: choose escape character, or \"none\"; default '~')\n"
+ " (-n: don't read from stdin)\n"
" (-T: disable PTY allocation)\n"
" (-t: force PTY allocation)\n"
" (-x: disable remote exit codes and stdout/stderr separation)\n"
@@ -733,6 +734,11 @@ static int adb_shell(int argc, const char** argv,
use_shell_protocol = false;
--argc;
++argv;
+ } else if (!strcmp(argv[0], "-n")) {
+ close_stdin();
+
+ --argc;
+ ++argv;
} else {
break;
}
diff --git a/daemon/main.cpp b/daemon/main.cpp
index f4e054e..a56d1dc 100644
--- a/daemon/main.cpp
+++ b/daemon/main.cpp
@@ -34,6 +34,7 @@
#include "adb.h"
#include "adb_auth.h"
#include "adb_listeners.h"
+#include "adb_utils.h"
#include "transport.h"
static const char* root_seclabel = nullptr;
@@ -217,16 +218,6 @@ int adbd_main(int server_port) {
return 0;
}
-static 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, STDIN_FILENO);
- unix_close(fd);
-}
-
int main(int argc, char** argv) {
while (true) {
static struct option opts[] = {