backup_service.c revision 5b811fa5dd00288954f15209a56aea03d5e4a004
1/* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include <unistd.h> 18#include <stdio.h> 19 20#include "sysdeps.h" 21 22#define TRACE_TAG TRACE_ADB 23#include "adb.h" 24 25// socketpair but do *not* mark as close_on_exec 26static int backup_socketpair(int sv[2]) { 27 int rc = unix_socketpair( AF_UNIX, SOCK_STREAM, 0, sv ); 28 if (rc < 0) 29 return -1; 30 31 return 0; 32} 33 34static void* backup_child_waiter(void* pid_cookie) { 35 int status; 36 37 waitpid((pid_t) pid_cookie, &status, 0); 38 D("harvested backup/restore child, status=%d\n", status); 39 return NULL; 40} 41 42/* returns the data socket passing the backup data here for forwarding */ 43int backup_service(BackupOperation op, char* args) { 44 pid_t pid; 45 int s[2]; 46 char* operation; 47 int socketnum; 48 49 // Command string and choice of stdin/stdout for the pipe depend on our invocation 50 if (op == BACKUP) { 51 operation = "backup"; 52 socketnum = STDOUT_FILENO; 53 } else { 54 operation = "restore"; 55 socketnum = STDIN_FILENO; 56 } 57 58 D("backup_service(%s, %s)\n", operation, args); 59 60 // set up the pipe from the subprocess to here 61 // parent will read s[0]; child will write s[1] 62 if (backup_socketpair(s)) { 63 D("can't create backup/restore socketpair\n"); 64 fprintf(stderr, "unable to create backup/restore socketpair\n"); 65 return -1; 66 } 67 68 D("Backup/restore socket pair: (send=%d, receive=%d)\n", s[1], s[0]); 69 close_on_exec(s[0]); // only the side we hold on to 70 71 // spin off the child process to run the backup command 72 pid = fork(); 73 if (pid < 0) { 74 // failure 75 D("can't fork for %s\n", operation); 76 fprintf(stderr, "unable to fork for %s\n", operation); 77 adb_close(s[0]); 78 adb_close(s[1]); 79 return -1; 80 } 81 82 // Great, we're off and running. 83 if (pid == 0) { 84 // child -- actually run the backup here 85 char* p; 86 int argc; 87 char portnum[16]; 88 char** bu_args; 89 90 // fixed args: [0] is 'bu', [1] is the port number, [2] is the 'operation' string 91 argc = 3; 92 for (p = (char*)args; p && *p; ) { 93 argc++; 94 while (*p && *p != ':') p++; 95 if (*p == ':') p++; 96 } 97 98 bu_args = (char**) alloca(argc*sizeof(char*) + 1); 99 100 // run through again to build the argv array 101 argc = 0; 102 bu_args[argc++] = "bu"; 103 snprintf(portnum, sizeof(portnum), "%d", s[1]); 104 bu_args[argc++] = portnum; 105 bu_args[argc++] = operation; 106 for (p = (char*)args; p && *p; ) { 107 bu_args[argc++] = p; 108 while (*p && *p != ':') p++; 109 if (*p == ':') { 110 *p = 0; 111 p++; 112 } 113 } 114 bu_args[argc] = NULL; 115 116 // Close the half of the socket that we don't care about, route 'bu's console 117 // to the output socket, and off we go 118 adb_close(s[0]); 119 120 // off we go 121 execvp("/system/bin/bu", (char * const *)bu_args); 122 // oops error - close up shop and go home 123 fprintf(stderr, "Unable to exec 'bu', bailing\n"); 124 exit(-1); 125 } else { 126 adb_thread_t t; 127 128 // parent, i.e. adbd -- close the sending half of the socket 129 D("fork() returned pid %d\n", pid); 130 adb_close(s[1]); 131 132 // spin a thread to harvest the child process 133 if (adb_thread_create(&t, backup_child_waiter, (void*)pid)) { 134 adb_close(s[0]); 135 D("Unable to create child harvester\n"); 136 return -1; 137 } 138 } 139 140 // we'll be reading from s[0] as the data is sent by the child process 141 return s[0]; 142} 143