summaryrefslogtreecommitdiffstats
path: root/adb
diff options
context:
space:
mode:
authorMike Lockwood <lockwood@google.com>2011-06-21 16:44:32 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2011-06-21 16:44:32 -0700
commit693e78b9b61da835b6d2f88348bb99ab0840b37e (patch)
tree98f8abf167a767ea55c5d0460b34db4e21d2e15d /adb
parent4d557db514655e85479a5f0ca1fb6152abb24a40 (diff)
parent10f129ca8eb266f46393e981484e60521f9011df (diff)
downloadcore-693e78b9b61da835b6d2f88348bb99ab0840b37e.tar.gz
core-693e78b9b61da835b6d2f88348bb99ab0840b37e.tar.bz2
core-693e78b9b61da835b6d2f88348bb99ab0840b37e.zip
Merge "Fix hang after end of backup"
Diffstat (limited to 'adb')
-rw-r--r--adb/backup_service.c21
1 files changed, 17 insertions, 4 deletions
diff --git a/adb/backup_service.c b/adb/backup_service.c
index 4f0c8ac76..669ff8623 100644
--- a/adb/backup_service.c
+++ b/adb/backup_service.c
@@ -22,6 +22,11 @@
#define TRACE_TAG TRACE_ADB
#include "adb.h"
+typedef struct {
+ pid_t pid;
+ int fd;
+} backup_harvest_params;
+
// socketpair but do *not* mark as close_on_exec
static int backup_socketpair(int sv[2]) {
int rc = unix_socketpair( AF_UNIX, SOCK_STREAM, 0, sv );
@@ -31,11 +36,14 @@ static int backup_socketpair(int sv[2]) {
return 0;
}
-static void* backup_child_waiter(void* pid_cookie) {
+// harvest the child process then close the read end of the socketpair
+static void* backup_child_waiter(void* args) {
int status;
+ backup_harvest_params* params = (backup_harvest_params*) args;
- waitpid((pid_t) pid_cookie, &status, 0);
- D("harvested backup/restore child, status=%d\n", status);
+ waitpid(params->pid, &status, 0);
+ adb_close(params->fd);
+ free(params);
return NULL;
}
@@ -124,14 +132,19 @@ int backup_service(BackupOperation op, char* args) {
exit(-1);
} else {
adb_thread_t t;
+ backup_harvest_params* params;
// parent, i.e. adbd -- close the sending half of the socket
D("fork() returned pid %d\n", pid);
adb_close(s[1]);
// spin a thread to harvest the child process
- if (adb_thread_create(&t, backup_child_waiter, (void*)pid)) {
+ params = (backup_harvest_params*) malloc(sizeof(backup_harvest_params));
+ params->pid = pid;
+ params->fd = s[0];
+ if (adb_thread_create(&t, backup_child_waiter, params)) {
adb_close(s[0]);
+ free(params);
D("Unable to create child harvester\n");
return -1;
}