Merge "adb: fix fd double close, Subprocess lifetime issue."

This commit is contained in:
Treehugger Robot 2016-06-20 20:15:59 +00:00 committed by Gerrit Code Review
commit b23e5729a8
1 changed files with 26 additions and 9 deletions

View File

@ -160,9 +160,14 @@ class Subprocess {
pid_t pid() const { return pid_; }
// Sets up FDs, forks a subprocess, starts the subprocess manager thread,
// and exec's the child. Returns false on failure.
// and exec's the child. Returns false and sets error on failure.
bool ForkAndExec(std::string* _Nonnull error);
// Start the subprocess manager thread. Consumes the subprocess, regardless of success.
// Returns false and sets error on failure.
static bool StartThread(std::unique_ptr<Subprocess> subprocess,
std::string* _Nonnull error);
private:
// Opens the file at |pts_name|.
int OpenPtyChildFd(const char* pts_name, unique_fd* error_sfd);
@ -390,14 +395,19 @@ bool Subprocess::ForkAndExec(std::string* error) {
}
}
if (!adb_thread_create(ThreadHandler, this)) {
D("subprocess parent: completed");
return true;
}
bool Subprocess::StartThread(std::unique_ptr<Subprocess> subprocess, std::string* error) {
Subprocess* raw = subprocess.release();
if (!adb_thread_create(ThreadHandler, raw)) {
*error =
android::base::StringPrintf("failed to create subprocess thread: %s", strerror(errno));
kill(pid_, SIGKILL);
kill(raw->pid_, SIGKILL);
return false;
}
D("subprocess parent: completed");
return true;
}
@ -441,6 +451,7 @@ void Subprocess::ThreadHandler(void* userdata) {
adb_thread_setname(android::base::StringPrintf(
"shell srvc %d", subprocess->local_socket_fd()));
D("passing data streams for PID %d", subprocess->pid());
subprocess->PassDataStreams();
D("deleting Subprocess for PID %d", subprocess->pid());
@ -733,7 +744,7 @@ int StartSubprocess(const char* name, const char* terminal_type,
protocol == SubprocessProtocol::kNone ? "none" : "shell",
terminal_type, name);
Subprocess* subprocess = new Subprocess(name, terminal_type, type, protocol);
auto subprocess = std::make_unique<Subprocess>(name, terminal_type, type, protocol);
if (!subprocess) {
LOG(ERROR) << "failed to allocate new subprocess";
return ReportError(protocol, "failed to allocate new subprocess");
@ -742,11 +753,17 @@ int StartSubprocess(const char* name, const char* terminal_type,
std::string error;
if (!subprocess->ForkAndExec(&error)) {
LOG(ERROR) << "failed to start subprocess: " << error;
delete subprocess;
return ReportError(protocol, error);
}
D("subprocess creation successful: local_socket_fd=%d, pid=%d",
subprocess->local_socket_fd(), subprocess->pid());
return subprocess->local_socket_fd();
unique_fd local_socket(dup(subprocess->local_socket_fd()));
D("subprocess creation successful: local_socket_fd=%d, pid=%d", local_socket.get(),
subprocess->pid());
if (!Subprocess::StartThread(std::move(subprocess), &error)) {
LOG(ERROR) << "failed to start subprocess management thread: " << error;
return ReportError(protocol, error);
}
return local_socket.release();
}