Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 143b9e3d authored by Colin Cross's avatar Colin Cross Committed by Gerrit Code Review
Browse files

Merge changes I1730d1df,I42c18cb5,I03bb5cc1

* changes:
  adb: use oom_score_adj instead of oom_adj
  Add "exec" service: shell commands with no pty.
  adb: added support for adb pull -a to preserve time stamps and mode
parents d8b00c89 1b3f2ff0
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -102,7 +102,6 @@ include $(CLEAR_VARS)

LOCAL_SRC_FILES := \
	adb.c \
	backup_service.c \
	fdevent.c \
	transport.c \
	transport_local.c \
+6 −6
Original line number Diff line number Diff line
@@ -326,11 +326,6 @@ int create_jdwp_connection_fd(int jdwp_pid);
int handle_forward_request(const char* service, transport_type ttype, char* serial, int reply_fd);

#if !ADB_HOST
typedef enum {
    BACKUP,
    RESTORE
} BackupOperation;
int backup_service(BackupOperation operation, char* args);
void framebuffer_service(int fd, void *cookie);
void remount_service(int fd, void *cookie);
#endif
@@ -418,7 +413,7 @@ void adb_qemu_trace(const char* fmt, ...);
#  define  D(...)          ((void)0)
#  define  DR(...)         ((void)0)
#  define  ADB_TRACING     0
#endif
#endif /* ADB_TRACE */


#if !DEBUG_PACKETS
@@ -476,6 +471,11 @@ int connection_state(atransport *t);
extern int HOST;
extern int SHELL_EXIT_NOTIFY_FD;

typedef enum {
    SUBPROC_PTY = 0,
    SUBPROC_RAW = 1,
} subproc_mode;

#define CHUNK_SIZE (64*1024)

#if !ADB_HOST

adb/backup_service.c

deleted100644 → 0
+0 −152
Original line number Diff line number Diff line
/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <unistd.h>
#include <stdio.h>

#include "sysdeps.h"

#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 );
    if (rc < 0)
        return -1;

    return 0;
}

// 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(params->pid, &status, 0);
    adb_close(params->fd);
    free(params);
    return NULL;
}

/* returns the data socket passing the backup data here for forwarding */
int backup_service(BackupOperation op, char* args) {
    pid_t pid;
    int s[2];
    char* operation;

    // Command string depends on our invocation
    if (op == BACKUP) {
        operation = "backup";
    } else {
        operation = "restore";
    }

    D("backup_service(%s, %s)\n", operation, args);

    // set up the pipe from the subprocess to here
    // parent will read s[0]; child will write s[1]
    if (backup_socketpair(s)) {
        D("can't create backup/restore socketpair\n");
        fprintf(stderr, "unable to create backup/restore socketpair\n");
        return -1;
    }

    D("Backup/restore socket pair: (send=%d, receive=%d)\n", s[1], s[0]);
    close_on_exec(s[0]);    // only the side we hold on to

    // spin off the child process to run the backup command
    pid = fork();
    if (pid < 0) {
        // failure
        D("can't fork for %s\n", operation);
        fprintf(stderr, "unable to fork for %s\n", operation);
        adb_close(s[0]);
        adb_close(s[1]);
        return -1;
    }

    // Great, we're off and running.
    if (pid == 0) {
        // child -- actually run the backup here
        char* p;
        int argc;
        char portnum[16];
        char** bu_args;

        // fixed args:  [0] is 'bu', [1] is the port number, [2] is the 'operation' string
        argc = 3;
        for (p = (char*)args; p && *p; ) {
            argc++;
            while (*p && *p != ':') p++;
            if (*p == ':') p++;
        }

        bu_args = (char**) alloca(argc*sizeof(char*) + 1);

        // run through again to build the argv array
        argc = 0;
        bu_args[argc++] = "bu";
        snprintf(portnum, sizeof(portnum), "%d", s[1]);
        bu_args[argc++] = portnum;
        bu_args[argc++] = operation;
        for (p = (char*)args; p && *p; ) {
            bu_args[argc++] = p;
            while (*p && *p != ':') p++;
            if (*p == ':') {
                *p = 0;
                p++;
            }
        }
        bu_args[argc] = NULL;

        // Close the half of the socket that we don't care about, route 'bu's console
        // to the output socket, and off we go
        adb_close(s[0]);

        // off we go
        execvp("/system/bin/bu", (char * const *)bu_args);
        // oops error - close up shop and go home
        fprintf(stderr, "Unable to exec 'bu', bailing\n");
        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
        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;
        }
    }

    // we'll be reading from s[0] as the data is sent by the child process
    return s[0];
}
+75 −23
Original line number Diff line number Diff line
@@ -110,9 +110,10 @@ void help()
        "  adb push [-p] <local> <remote>\n"
        "                               - copy file/dir to device\n"
        "                                 ('-p' to display the transfer progress)\n"
        "  adb pull [-p] <remote> [<local>]\n"
        "  adb pull [-p] [-a] <remote> [<local>]\n"
        "                               - copy file/dir from device\n"
        "                                 ('-p' to display the transfer progress)\n"
        "                                 ('-a' means copy timestamp and mode)\n"
        "  adb sync [ <directory> ]     - copy host->device only if changed\n"
        "                                 (-l means list but don't copy)\n"
        "                                 (see 'adb help all')\n"
@@ -285,8 +286,17 @@ static void copy_to_file(int inFd, int outFd) {
    long total = 0;

    D("copy_to_file(%d -> %d)\n", inFd, outFd);
#ifdef HAVE_TERMIO_H
    if (inFd == STDIN_FILENO) {
        stdin_raw_init(STDIN_FILENO);
    }
#endif
    for (;;) {
        if (inFd == STDIN_FILENO) {
            len = unix_read(inFd, buf, BUFSIZE);
        } else {
            len = adb_read(inFd, buf, BUFSIZE);
        }
        if (len == 0) {
            D("copy_to_file() : read 0 bytes; exiting\n");
            break;
@@ -299,9 +309,19 @@ static void copy_to_file(int inFd, int outFd) {
            D("copy_to_file() : error %d\n", errno);
            break;
        }
        if (outFd == STDOUT_FILENO) {
            fwrite(buf, 1, len, stdout);
            fflush(stdout);
        } else {
            adb_write(outFd, buf, len);
        }
        total += len;
    }
#ifdef HAVE_TERMIO_H
    if (inFd == STDIN_FILENO) {
        stdin_raw_restore(STDIN_FILENO);
    }
#endif
    D("copy_to_file() finished after %lu bytes\n", total);
    free(buf);
}
@@ -938,13 +958,19 @@ static const char *find_product_out_path(const char *hint)
    return path_buf;
}


static void parse_push_pull_args(char **arg, int narg, char const **path1, char const **path2,
                                 int* show_progress) {
                                 int *show_progress, int *copy_attrs) {
    *show_progress = 0;
    *copy_attrs = 0;

    if ((narg > 0) && !strcmp(*arg, "-p")) {
    while (narg > 0) {
        if (!strcmp(*arg, "-p")) {
            *show_progress = 1;
        } else if (!strcmp(*arg, "-a")) {
            *copy_attrs = 1;
        } else {
            break;
        }
        ++arg;
        --narg;
    }
@@ -968,7 +994,6 @@ int adb_commandline(int argc, char **argv)
    int is_server = 0;
    int persist = 0;
    int r;
    int quote;
    transport_type ttype = kTransportAny;
    char* serial = NULL;
    char* server_port_str = NULL;
@@ -1189,19 +1214,14 @@ top:
            return r;
        }

        snprintf(buf, sizeof buf, "shell:%s", argv[1]);
        snprintf(buf, sizeof(buf), "shell:%s", argv[1]);
        argc -= 2;
        argv += 2;
        while (argc-- > 0) {
            strcat(buf, " ");

            /* quote empty strings and strings with spaces */
            quote = (**argv == 0 || strchr(*argv, ' '));
            if (quote)
                strcat(buf, "\"");
            strcat(buf, *argv++);
            if (quote)
                strcat(buf, "\"");
            char *quoted = dupAndQuote(*argv++);
            strncat(buf, " ", sizeof(buf) - 1);
            strncat(buf, quoted, sizeof(buf) - 1);
            free(quoted);
        }

        for(;;) {
@@ -1233,6 +1253,36 @@ top:
        }
    }

    if (!strcmp(argv[0], "exec-in") || !strcmp(argv[0], "exec-out")) {
        int exec_in = !strcmp(argv[0], "exec-in");
        int fd;

        snprintf(buf, sizeof buf, "exec:%s", argv[1]);
        argc -= 2;
        argv += 2;
        while (argc-- > 0) {
            char *quoted = dupAndQuote(*argv++);
            strncat(buf, " ", sizeof(buf) - 1);
            strncat(buf, quoted, sizeof(buf) - 1);
            free(quoted);
        }

        fd = adb_connect(buf);
        if (fd < 0) {
            fprintf(stderr, "error: %s\n", adb_error());
            return -1;
        }

        if (exec_in) {
            copy_to_file(STDIN_FILENO, fd);
        } else {
            copy_to_file(fd, STDOUT_FILENO);
        }

        adb_close(fd);
        return 0;
    }

    if(!strcmp(argv[0], "kill-server")) {
        int fd;
        fd = _adb_connect("host:kill");
@@ -1415,9 +1465,10 @@ top:

    if(!strcmp(argv[0], "push")) {
        int show_progress = 0;
        int copy_attrs = 0; // unused
        const char* lpath = NULL, *rpath = NULL;

        parse_push_pull_args(&argv[1], argc - 1, &lpath, &rpath, &show_progress);
        parse_push_pull_args(&argv[1], argc - 1, &lpath, &rpath, &show_progress, &copy_attrs);

        if ((lpath != NULL) && (rpath != NULL)) {
            return do_sync_push(lpath, rpath, 0 /* no verify APK */, show_progress);
@@ -1428,12 +1479,13 @@ top:

    if(!strcmp(argv[0], "pull")) {
        int show_progress = 0;
        int copy_attrs = 0;
        const char* rpath = NULL, *lpath = ".";

        parse_push_pull_args(&argv[1], argc - 1, &rpath, &lpath, &show_progress);
        parse_push_pull_args(&argv[1], argc - 1, &rpath, &lpath, &show_progress, &copy_attrs);

        if (rpath != NULL) {
            return do_sync_pull(rpath, lpath, show_progress);
            return do_sync_pull(rpath, lpath, show_progress, copy_attrs);
        }

        return usage();
+28 −27
Original line number Diff line number Diff line
@@ -139,7 +139,8 @@ struct syncsendbuf {

static syncsendbuf send_buffer;

int sync_readtime(int fd, const char *path, unsigned *timestamp)
int sync_readtime(int fd, const char *path, unsigned int *timestamp,
                  unsigned int *mode)
{
    syncmsg msg;
    int len = strlen(path);
@@ -161,6 +162,7 @@ int sync_readtime(int fd, const char *path, unsigned *timestamp)
    }

    *timestamp = ltohl(msg.stat.time);
    *mode = ltohl(msg.stat.mode);
    return 0;
}

@@ -237,7 +239,7 @@ static int write_data_file(int fd, const char *path, syncsendbuf *sbuf, int show
    if (show_progress) {
        // Determine local file size.
        struct stat st;
        if (lstat(path, &st)) {
        if (fstat(lfd, &st)) {
            fprintf(stderr,"cannot stat '%s': %s\n", path, strerror(errno));
            return -1;
        }
@@ -931,8 +933,21 @@ static int remote_build_list(int syncfd, copyinfo **filelist,
    return 0;
}

static int set_time_and_mode(const char *lpath, unsigned int time, unsigned int mode)
{
    struct timeval times[2] = { {time, 0}, {time, 0} };
    int r1 = utimes(lpath, times);

    /* use umask for permissions */
    mode_t mask=umask(0000);
    umask(mask);
    int r2 = chmod(lpath, mode & ~mask);

    return r1 ? : r2;
}

static int copy_remote_dir_local(int fd, const char *rpath, const char *lpath,
                                 int checktimestamps)
                                 int copy_attrs)
{
    copyinfo *filelist = 0;
    copyinfo *ci, *next;
@@ -962,26 +977,6 @@ static int copy_remote_dir_local(int fd, const char *rpath, const char *lpath,
        return -1;
    }

#if 0
    if (checktimestamps) {
        for (ci = filelist; ci != 0; ci = ci->next) {
            if (sync_start_readtime(fd, ci->dst)) {
                return 1;
            }
        }
        for (ci = filelist; ci != 0; ci = ci->next) {
            unsigned int timestamp, mode, size;
            if (sync_finish_readtime(fd, &timestamp, &mode, &size))
                return 1;
            if (size == ci->size) {
                /* for links, we cannot update the atime/mtime */
                if ((S_ISREG(ci->mode & mode) && timestamp == ci->time) ||
                    (S_ISLNK(ci->mode & mode) && timestamp >= ci->time))
                    ci->flag = 1;
            }
        }
    }
#endif
    for (ci = filelist; ci != 0; ci = next) {
        next = ci->next;
        if (ci->flag == 0) {
@@ -989,6 +984,10 @@ static int copy_remote_dir_local(int fd, const char *rpath, const char *lpath,
            if (sync_recv(fd, ci->src, ci->dst, 0 /* no show progress */)) {
                return 1;
            }

            if (copy_attrs && set_time_and_mode(ci->dst, ci->time, ci->mode)) {
               return 1;
            }
            pulled++;
        } else {
            skipped++;
@@ -1003,9 +1002,9 @@ static int copy_remote_dir_local(int fd, const char *rpath, const char *lpath,
    return 0;
}

int do_sync_pull(const char *rpath, const char *lpath, int show_progress)
int do_sync_pull(const char *rpath, const char *lpath, int show_progress, int copy_attrs)
{
    unsigned mode;
    unsigned mode, time;
    struct stat st;

    int fd;
@@ -1016,7 +1015,7 @@ int do_sync_pull(const char *rpath, const char *lpath, int show_progress)
        return 1;
    }

    if(sync_readmode(fd, rpath, &mode)) {
    if(sync_readtime(fd, rpath, &time, &mode)) {
        return 1;
    }
    if(mode == 0) {
@@ -1047,13 +1046,15 @@ int do_sync_pull(const char *rpath, const char *lpath, int show_progress)
        if (sync_recv(fd, rpath, lpath, show_progress)) {
            return 1;
        } else {
            if (copy_attrs && set_time_and_mode(lpath, time, mode))
                return 1;
            END();
            sync_quit(fd);
            return 0;
        }
    } else if(S_ISDIR(mode)) {
        BEGIN();
        if (copy_remote_dir_local(fd, rpath, lpath, 0)) {
        if (copy_remote_dir_local(fd, rpath, lpath, copy_attrs)) {
            return 1;
        } else {
            END();
Loading