Home | History | Annotate | Download | only in adb
      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 typedef struct {
     26     pid_t pid;
     27     int fd;
     28 } backup_harvest_params;
     29 
     30 // socketpair but do *not* mark as close_on_exec
     31 static int backup_socketpair(int sv[2]) {
     32     int rc = unix_socketpair( AF_UNIX, SOCK_STREAM, 0, sv );
     33     if (rc < 0)
     34         return -1;
     35 
     36     return 0;
     37 }
     38 
     39 // harvest the child process then close the read end of the socketpair
     40 static void* backup_child_waiter(void* args) {
     41     int status;
     42     backup_harvest_params* params = (backup_harvest_params*) args;
     43 
     44     waitpid(params->pid, &status, 0);
     45     adb_close(params->fd);
     46     free(params);
     47     return NULL;
     48 }
     49 
     50 /* returns the data socket passing the backup data here for forwarding */
     51 int backup_service(BackupOperation op, char* args) {
     52     pid_t pid;
     53     int s[2];
     54     char* operation;
     55     int socketnum;
     56 
     57     // Command string and choice of stdin/stdout for the pipe depend on our invocation
     58     if (op == BACKUP) {
     59         operation = "backup";
     60         socketnum = STDOUT_FILENO;
     61     } else {
     62         operation = "restore";
     63         socketnum = STDIN_FILENO;
     64     }
     65 
     66     D("backup_service(%s, %s)\n", operation, args);
     67 
     68     // set up the pipe from the subprocess to here
     69     // parent will read s[0]; child will write s[1]
     70     if (backup_socketpair(s)) {
     71         D("can't create backup/restore socketpair\n");
     72         fprintf(stderr, "unable to create backup/restore socketpair\n");
     73         return -1;
     74     }
     75 
     76     D("Backup/restore socket pair: (send=%d, receive=%d)\n", s[1], s[0]);
     77     close_on_exec(s[0]);    // only the side we hold on to
     78 
     79     // spin off the child process to run the backup command
     80     pid = fork();
     81     if (pid < 0) {
     82         // failure
     83         D("can't fork for %s\n", operation);
     84         fprintf(stderr, "unable to fork for %s\n", operation);
     85         adb_close(s[0]);
     86         adb_close(s[1]);
     87         return -1;
     88     }
     89 
     90     // Great, we're off and running.
     91     if (pid == 0) {
     92         // child -- actually run the backup here
     93         char* p;
     94         int argc;
     95         char portnum[16];
     96         char** bu_args;
     97 
     98         // fixed args:  [0] is 'bu', [1] is the port number, [2] is the 'operation' string
     99         argc = 3;
    100         for (p = (char*)args; p && *p; ) {
    101             argc++;
    102             while (*p && *p != ':') p++;
    103             if (*p == ':') p++;
    104         }
    105 
    106         bu_args = (char**) alloca(argc*sizeof(char*) + 1);
    107 
    108         // run through again to build the argv array
    109         argc = 0;
    110         bu_args[argc++] = "bu";
    111         snprintf(portnum, sizeof(portnum), "%d", s[1]);
    112         bu_args[argc++] = portnum;
    113         bu_args[argc++] = operation;
    114         for (p = (char*)args; p && *p; ) {
    115             bu_args[argc++] = p;
    116             while (*p && *p != ':') p++;
    117             if (*p == ':') {
    118                 *p = 0;
    119                 p++;
    120             }
    121         }
    122         bu_args[argc] = NULL;
    123 
    124         // Close the half of the socket that we don't care about, route 'bu's console
    125         // to the output socket, and off we go
    126         adb_close(s[0]);
    127 
    128         // off we go
    129         execvp("/system/bin/bu", (char * const *)bu_args);
    130         // oops error - close up shop and go home
    131         fprintf(stderr, "Unable to exec 'bu', bailing\n");
    132         exit(-1);
    133     } else {
    134         adb_thread_t t;
    135         backup_harvest_params* params;
    136 
    137         // parent, i.e. adbd -- close the sending half of the socket
    138         D("fork() returned pid %d\n", pid);
    139         adb_close(s[1]);
    140 
    141         // spin a thread to harvest the child process
    142         params = (backup_harvest_params*) malloc(sizeof(backup_harvest_params));
    143         params->pid = pid;
    144         params->fd = s[0];
    145         if (adb_thread_create(&t, backup_child_waiter, params)) {
    146             adb_close(s[0]);
    147             free(params);
    148             D("Unable to create child harvester\n");
    149             return -1;
    150         }
    151     }
    152 
    153     // we'll be reading from s[0] as the data is sent by the child process
    154     return s[0];
    155 }
    156