// This test checks if we can close local socket in the following situation:
// The socket is not closed and has some packets. When it fails to write to
// the socket's file handler because the other end is closed, we check if the
// socket is closed.
TEST_F(LocalSocketTest, write_error_when_having_packets) {
    int socket_fd[2];
    ASSERT_EQ(0, adb_socketpair(socket_fd));
    int cause_close_fd[2];
    ASSERT_EQ(0, adb_socketpair(cause_close_fd));
    CloseWithPacketArg arg;
    arg.socket_fd = socket_fd[1];
    arg.cause_close_fd = cause_close_fd[1];

    PrepareThread();
    adb_thread_t thread;
    ASSERT_TRUE(adb_thread_create(reinterpret_cast<void (*)(void*)>(CloseWithPacketThreadFunc),
                                  &arg, &thread));

    // Wait until the fdevent_loop() starts.
    adb_sleep_ms(100);
    EXPECT_EQ(3u, fdevent_installed_count());
    ASSERT_EQ(0, adb_close(socket_fd[0]));

    TerminateThread(thread);
}
Exemplo n.º 2
0
static void wait_for_state(int fd, void* cookie)
{
    state_info* sinfo = reinterpret_cast<state_info*>(cookie);

    D("wait_for_state %d", sinfo->state);

    std::string error_msg = "unknown error";
    atransport* t = acquire_one_transport(sinfo->state, sinfo->transport_type, sinfo->serial,
                                          &error_msg);
    if (t != nullptr) {
        SendOkay(fd);
    } else {
        SendFail(fd, error_msg);
    }

    if (sinfo->serial)
        free(sinfo->serial);
    free(sinfo);
    adb_close(fd);
    D("wait_for_state is done");
}
Exemplo n.º 3
0
static void wait_for_state(int fd, void *cookie)
{
    struct state_info *sinfo = cookie;
    char *err = "unknown error";

    D("wait_for_state %d\n", sinfo->state);

    atransport *t = acquire_one_transport(sinfo->state, sinfo->transport,
                                          sinfo->serial, &err);
    if (t != 0) {
        writex(fd, "OKAY", 4);
    } else {
        sendfailmsg(fd, err);
    }

    if (sinfo->serial)
        free(sinfo->serial);
    free(sinfo);
    adb_close(fd);
    D("wait_for_state is done\n");
}
static void remote_kick(atransport *t)
{
    int fd = t->sfd;
    t->sfd = -1;
    adb_shutdown(fd);
    adb_close(fd);

#if ADB_HOST
    if(HOST) {
        int  nn;
        adb_mutex_lock( &local_transports_lock );
        for (nn = 0; nn < ADB_LOCAL_TRANSPORT_MAX; nn++) {
            if (local_transports[nn] == t) {
                local_transports[nn] = NULL;
                break;
            }
        }
        adb_mutex_unlock( &local_transports_lock );
    }
#endif
}
Exemplo n.º 5
0
// This test checks when a local socket doesn't enable FDE_READ/FDE_WRITE/FDE_ERROR, it
// can still be closed when some error happens on its file handler.
// This test successes on linux but fails on mac because of different implementation of
// poll(). I think the function tested here is useful to make adb server more stable on
// linux.
TEST_F(LocalSocketTest, close_with_no_events_installed) {
    int socket_fd[2];
    ASSERT_EQ(0, adb_socketpair(socket_fd));

    CloseNoEventsArg arg;
    arg.socket_fd = socket_fd[1];
    pthread_t thread;
    ASSERT_EQ(0, pthread_create(&thread, nullptr,
                                reinterpret_cast<void* (*)(void*)>(CloseNoEventsThreadFunc),
                                &arg));
    // Wait until the fdevent_loop() starts.
    sleep(1);
    ASSERT_EQ(2u, fdevent_installed_count());
    ASSERT_EQ(0, adb_close(socket_fd[0]));

    // Wait until the socket is closed.
    sleep(1);

    ASSERT_EQ(0, pthread_kill(thread, SIGUSR1));
    ASSERT_EQ(0, pthread_join(thread, nullptr));
}
Exemplo n.º 6
0
static void listener_event_func(int _fd, unsigned ev, void* _l)
{
    alistener* listener = reinterpret_cast<alistener*>(_l);
    asocket *s;

    if (ev & FDE_READ) {
        int fd = adb_socket_accept(_fd, nullptr, nullptr);
        if (fd < 0) {
            return;
        }

        s = create_local_socket(fd);
        if (s) {
            s->transport = listener->transport;
            connect_to_remote(s, listener->connect_to.c_str());
            return;
        }

        adb_close(fd);
    }
}
static void connect_device(const std::string& host, std::string* response) {
    if (host.empty()) {
        *response = "empty host name";
        return;
    }

    std::vector<std::string> pieces = android::base::Split(host, ":");
    const std::string& hostname = pieces[0];

    int port = DEFAULT_ADB_LOCAL_TRANSPORT_PORT;
    if (pieces.size() > 1) {
        if (sscanf(pieces[1].c_str(), "%d", &port) != 1) {
            *response = android::base::StringPrintf("bad port number %s", pieces[1].c_str());
            return;
        }
    }

    // This may look like we're putting 'host' back together,
    // but we're actually inserting the default port if necessary.
    std::string serial = android::base::StringPrintf("%s:%d", hostname.c_str(), port);

    int fd = socket_network_client_timeout(hostname.c_str(), port, SOCK_STREAM, 10);
    if (fd < 0) {
        *response = android::base::StringPrintf("unable to connect to %s:%d",
                                                hostname.c_str(), port);
        return;
    }

    D("client: connected on remote on fd %d\n", fd);
    close_on_exec(fd);
    disable_tcp_nagle(fd);

    int ret = register_socket_transport(fd, serial.c_str(), port, 0);
    if (ret < 0) {
        adb_close(fd);
        *response = android::base::StringPrintf("already connected to %s", serial.c_str());
    } else {
        *response = android::base::StringPrintf("connected to %s", serial.c_str());
    }
}
Exemplo n.º 8
0
void start_device_log(void) {
    struct tm now;
    time_t t;
    tzset();
    time(&t);
    localtime_r(&t, &now);

    char timestamp[PATH_MAX];
    strftime(timestamp, sizeof(timestamp), "%Y-%m-%d-%H-%M-%S", &now);

    std::string path = android::base::StringPrintf("/data/adb/adb-%s-%d", timestamp, getpid());
    int fd = unix_open(path.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC, 0640);
    if (fd == -1) {
        return;
    }

    // redirect stdout and stderr to the log file
    dup2(fd, STDOUT_FILENO);
    dup2(fd, STDERR_FILENO);
    fprintf(stderr, "--- adb starting (pid %d) ---\n", getpid());
    adb_close(fd);
}
Exemplo n.º 9
0
int sync_ls(int fd, const char *path, sync_ls_cb func, void *cookie)
{
    syncmsg msg;
    char buf[257];
    int len;

    len = strlen(path);
    if(len > 1024) goto fail;

    msg.req.id = ID_LIST;
    msg.req.namelen = htoll(len);

    if(writex(fd, &msg.req, sizeof(msg.req)) ||
       writex(fd, path, len)) {
        goto fail;
    }

    for(;;) {
        if(readx(fd, &msg.dent, sizeof(msg.dent))) break;
        if(msg.dent.id == ID_DONE) return 0;
        if(msg.dent.id != ID_DENT) break;

        len = ltohl(msg.dent.namelen);
        if(len > 256) break;

        if(readx(fd, buf, len)) break;
        buf[len] = 0;

        func(ltohl(msg.dent.mode),
             ltohl(msg.dent.size),
             ltohl(msg.dent.time),
             buf, cookie);
    }

fail:
    adb_close(fd);
    return -1;
}
Exemplo n.º 10
0
static int write_data_file(int fd, const char *path, syncsendbuf *sbuf)
{
    int lfd, err = 0;

    lfd = adb_open(path, O_RDONLY);
    if(lfd < 0) {
        fprintf(stderr,"cannot open '%s': %s\n", path, strerror(errno));
        return -1;
    }

    sbuf->id = ID_DATA;
    for(;;) {
        int ret;

        ret = adb_read(lfd, sbuf->data, SYNC_DATA_MAX);
        if(!ret)
            break;

        if(ret < 0) {
            if(errno == EINTR)
                continue;
            fprintf(stderr,"cannot read '%s': %s\n", path, strerror(errno));
            break;
        }

        sbuf->size = htoll(ret);
        if(writex(fd, sbuf, sizeof(unsigned) * 2 + ret)){
            err = -1;
            break;
        }
        total_bytes += ret;
        STATUS();
    }

    adb_close(lfd);
    return err;
}
Exemplo n.º 11
0
static void ss_listener_event_func(int _fd, unsigned ev, void *_l)
{
    asocket *s;

    if(ev & FDE_READ) {
        struct sockaddr addr;
        socklen_t alen;
        int fd;

        alen = sizeof(addr);
        fd = adb_socket_accept(_fd, &addr, &alen);
        if(fd < 0) return;

        adb_socket_setbufsize(fd, CHUNK_SIZE);

        s = create_local_socket(fd);
        if(s) {
            connect_to_smartsocket(s);
            return;
        }

        adb_close(fd);
    }
}
Exemplo n.º 12
0
static char *_send_shellcommand(transport_type transport, char* serial, char* cmd) {
    int fd;

    if((fd=_adb_connect(cmd))<0) {
        return NULL;
    }

    char buf[4096<<2];
    char *ptr=buf;
    int left=sizeof(buf);
    int len = 0;
    while(left>0) {
        int n = adb_read(fd, ptr, left);
        if(n>0) {
            ptr += n;
            left -= n;
            len += n;
        } else if(n<=0) {
            break;
        }
    }
    adb_close(fd);
    return strndup(buf, len);
}
static void server_socket_thread(void* arg) {
    int serverfd, fd;
    sockaddr_storage ss;
    sockaddr *addrp = reinterpret_cast<sockaddr*>(&ss);
    socklen_t alen;
    int port = (int) (uintptr_t) arg;

    adb_thread_setname("server socket");
    D("transport: server_socket_thread() starting");
    serverfd = -1;
    for(;;) {
        if(serverfd == -1) {
            std::string error;
            serverfd = network_inaddr_any_server(port, SOCK_STREAM, &error);
            if(serverfd < 0) {
                D("server: cannot bind socket yet: %s", error.c_str());
                adb_sleep_ms(1000);
                continue;
            }
            close_on_exec(serverfd);
        }

        alen = sizeof(ss);
        D("server: trying to get new connection from %d", port);
        fd = adb_socket_accept(serverfd, addrp, &alen);
        if(fd >= 0) {
            D("server: new connection on fd %d", fd);
            close_on_exec(fd);
            disable_tcp_nagle(fd);
            if (register_socket_transport(fd, "host", port, 1) != 0) {
                adb_close(fd);
            }
        }
    }
    D("transport: server_socket_thread() exiting");
}
Exemplo n.º 14
0
// This test checks if we can close local socket in the following situation:
// The socket is not closed and has some packets. When it fails to write to
// the socket's file handler because the other end is closed, we check if the
// socket is closed.
TEST_F(LocalSocketTest, write_error_when_having_packets) {
    int socket_fd[2];
    ASSERT_EQ(0, adb_socketpair(socket_fd));
    int cause_close_fd[2];
    ASSERT_EQ(0, adb_socketpair(cause_close_fd));
    CloseWithPacketArg arg;
    arg.socket_fd = socket_fd[1];
    arg.cause_close_fd = cause_close_fd[1];

    pthread_t thread;
    ASSERT_EQ(0, pthread_create(&thread, nullptr,
                                reinterpret_cast<void* (*)(void*)>(CloseWithPacketThreadFunc),
                                &arg));
    // Wait until the fdevent_loop() starts.
    sleep(1);
    ASSERT_EQ(3u, fdevent_installed_count());
    ASSERT_EQ(0, adb_close(socket_fd[0]));

    // Wait until the socket is closed.
    sleep(1);

    ASSERT_EQ(0, pthread_kill(thread, SIGUSR1));
    ASSERT_EQ(0, pthread_join(thread, nullptr));
}
Exemplo n.º 15
0
bool AdbClient::adb_connect(const char *service)
{
    char tmp[5];
    int len;

    len = strlen(service);
    if((len < 1) || (len > 1024)) {
        __adb_error = "service name too long";
        return false;
    }
    snprintf(tmp, sizeof tmp, "%04x", len);

    if (memcmp(service,"host",4) != 0 && !switch_socket_transport()) {
        return false;
    }

    if(!writex(tmp, 4) || !writex(service, len)) {
        __adb_error = "write failure during connection";
        adb_close();
        return false;
    }

    return adb_status();
}
Exemplo n.º 16
0
static void listener_event_func(int _fd, unsigned ev, void *_l)
{
    alistener *l = _l;
    asocket *s;

    if(ev & FDE_READ) {
        struct sockaddr addr;
        socklen_t alen;
        int fd;

        alen = sizeof(addr);
        fd = adb_socket_accept(_fd, &addr, &alen);
        if(fd < 0) return;

        s = create_local_socket(fd);
        if(s) {
            s->transport = l->transport;
            connect_to_remote(s, l->connect_to);
            return;
        }

        adb_close(fd);
    }
}
/* A worker thread that monitors host connections, and registers a transport for
 * every new host connection. This thread replaces server_socket_thread on
 * condition that adbd daemon runs inside the emulator, and emulator uses QEMUD
 * pipe to communicate with adbd daemon inside the guest. This is done in order
 * to provide more robust communication channel between ADB host and guest. The
 * main issue with server_socket_thread approach is that it runs on top of TCP,
 * and thus is sensitive to network disruptions. For instance, the
 * ConnectionManager may decide to reset all network connections, in which case
 * the connection between ADB host and guest will be lost. To make ADB traffic
 * independent from the network, we use here 'adb' QEMUD service to transfer data
 * between the host, and the guest. See external/qemu/android/adb-*.* that
 * implements the emulator's side of the protocol. Another advantage of using
 * QEMUD approach is that ADB will be up much sooner, since it doesn't depend
 * anymore on network being set up.
 * The guest side of the protocol contains the following phases:
 * - Connect with adb QEMUD service. In this phase a handle to 'adb' QEMUD service
 *   is opened, and it becomes clear whether or not emulator supports that
 *   protocol.
 * - Wait for the ADB host to create connection with the guest. This is done by
 *   sending an 'accept' request to the adb QEMUD service, and waiting on
 *   response.
 * - When new ADB host connection is accepted, the connection with adb QEMUD
 *   service is registered as the transport, and a 'start' request is sent to the
 *   adb QEMUD service, indicating that the guest is ready to receive messages.
 *   Note that the guest will ignore messages sent down from the emulator before
 *   the transport registration is completed. That's why we need to send the
 *   'start' request after the transport is registered.
 */
static void *qemu_socket_thread(void * arg)
{
/* 'accept' request to the adb QEMUD service. */
static const char _accept_req[] = "accept";
/* 'start' request to the adb QEMUD service. */
static const char _start_req[]  = "start";
/* 'ok' reply from the adb QEMUD service. */
static const char _ok_resp[]    = "ok";

    const int port = (int) (uintptr_t) arg;
    int res, fd;
    char tmp[256];
    char con_name[32];

    D("transport: qemu_socket_thread() starting\n");

    /* adb QEMUD service connection request. */
    snprintf(con_name, sizeof(con_name), "qemud:adb:%d", port);

    /* Connect to the adb QEMUD service. */
    fd = qemu_pipe_open(con_name);
    if (fd < 0) {
        /* This could be an older version of the emulator, that doesn't
         * implement adb QEMUD service. Fall back to the old TCP way. */
        D("adb service is not available. Falling back to TCP socket.\n");
        adb_thread_create(server_socket_thread, arg);
        return 0;
    }

    for(;;) {
        /*
         * Wait till the host creates a new connection.
         */

        /* Send the 'accept' request. */
        res = adb_write(fd, _accept_req, strlen(_accept_req));
        if ((size_t)res == strlen(_accept_req)) {
            /* Wait for the response. In the response we expect 'ok' on success,
             * or 'ko' on failure. */
            res = adb_read(fd, tmp, sizeof(tmp));
            if (res != 2 || memcmp(tmp, _ok_resp, 2)) {
                D("Accepting ADB host connection has failed.\n");
                adb_close(fd);
            } else {
                /* Host is connected. Register the transport, and start the
                 * exchange. */
                register_socket_transport(fd, "host", port, 1);
                adb_write(fd, _start_req, strlen(_start_req));
            }

            /* Prepare for accepting of the next ADB host connection. */
            fd = qemu_pipe_open(con_name);
            if (fd < 0) {
                D("adb service become unavailable.\n");
                return 0;
            }
        } else {
            D("Unable to send the '%s' request to ADB service.\n", _accept_req);
            return 0;
        }
    }
    D("transport: qemu_socket_thread() exiting\n");
    return 0;
}
Exemplo n.º 18
0
static void remote_close(atransport *t)
{
    adb_close(t->fd);
}
Exemplo n.º 19
0
static void transport_registration_func(int _fd, unsigned ev, void *data)
{
    tmsg * m = addTMessage();
   int s[2];
    atransport *t;

    if(!(ev & FDE_READ)) {
        return;
    }

    if(transport_read_action(_fd, m)) {
        fatal_errno("cannot read transport registration socket");
    }

    t = m->transport;

    if(m->action == 0){
        D("transport: %s removing and free'ing %d\n", t->serial, t->transport_socket);

            /* IMPORTANT: the remove closes one half of the
            ** socket pair.  The close closes the other half.
            */
        fdevent_remove(&(t->transport_fde));
        adb_close(t->fd);

        adb_mutex_lock(&transport_lock);
        t->next->prev = t->prev;
        t->prev->next = t->next;
        adb_mutex_unlock(&transport_lock);

        run_transport_disconnects(t);

        if (t->product)
            free(t->product);
        if (t->serial)
            free(t->serial);
        if (t->model)
            free(t->model);
        if (t->device)
            free(t->device);
        if (t->devpath)
            free(t->devpath);

        memset(t,0xee,sizeof(atransport));
        free(t);

        update_transports();
        return;
    }

    /* don't create transport threads for inaccessible devices */
    if (t->connection_state != CS_NOPERM) {
      // adb_thread_t * output_thread_ptr = (adb_thread_t*)malloc(sizeof(adb_thread_t));
      // adb_thread_t * input_thread_ptr = (adb_thread_t*)malloc(sizeof(adb_thread_t));

        /* initial references are the two threads */
        t->ref_count = 2;

        if(adb_socketpair(s)) {
            fatal_errno("cannot open transport socketpair");
        }

        D("transport: %s (%d,%d) starting\n", t->serial, s[0], s[1]);

        t->transport_socket = s[0];
        t->fd = s[1];

        fdevent_install(&(t->transport_fde),
                        t->transport_socket,
                        transport_socket_events,
                        t);

        fdevent_set(&(t->transport_fde), FDE_READ);

        struct msg {
          atransport * t;
        };
        struct msg m = { t };
        send_js_msg("spawn-io-threads", &m);

        /*char i_tag[1024];
        char o_tag[1024];
        sprintf(i_tag, "I: %s_%d", t->serial, get_guid());
        sprintf(o_tag, "O: %s_%d", t->serial, get_guid());*/

        //dump_thread_tag();
        /*if(adb_thread_create(input_thread_ptr, input_thread, t, i_tag)){
            fatal_errno("cannot create input thread");
        }

        if(adb_thread_create(output_thread_ptr, output_thread, t, o_tag)){
            fatal_errno("cannot create output thread");
        }*/
    }
	
        /* put us on the master device list */
    adb_mutex_lock(&transport_lock);
    t->next = &transport_list;
    t->prev = transport_list.prev;
    t->next->prev = t;
    t->prev->next = t;
    adb_mutex_unlock(&transport_lock);

    t->disconnects.next = t->disconnects.prev = &t->disconnects;

    update_transports();
}
Exemplo n.º 20
0
int adb_connect(const char *service)
{
    // first query the adb server's version
    int fd = _adb_connect("host:version");

    D("adb_connect: service %s\n", service);
    if(fd == -2 && __adb_server_name) {
        fprintf(stderr,"** Cannot start server on remote host\n");
        return fd;
    } else if(fd == -2) {
        fprintf(stdout,"* daemon not running. starting it now on port %d *\n",
                __adb_server_port);
    start_server:
        if(launch_server(__adb_server_port)) {
            fprintf(stderr,"* failed to start daemon *\n");
            return -1;
        } else {
            fprintf(stdout,"* daemon started successfully *\n");
        }
        /* give the server some time to start properly and detect devices */
        adb_sleep_ms(3000);
        // fall through to _adb_connect
    } else {
        // if server was running, check its version to make sure it is not out of date
        char buf[100];
        size_t n;
        int version = ADB_SERVER_VERSION - 1;

        // if we have a file descriptor, then parse version result
        if(fd >= 0) {
            if(!ReadFdExactly(fd, buf, 4)) goto error;

            buf[4] = 0;
            n = strtoul(buf, 0, 16);
            if(n > sizeof(buf)) goto error;
            if(!ReadFdExactly(fd, buf, n)) goto error;
            adb_close(fd);

            if (sscanf(buf, "%04x", &version) != 1) goto error;
        } else {
            // if fd is -1, then check for "unknown host service",
            // which would indicate a version of adb that does not support the version command
            if (strcmp(__adb_error, "unknown host service") != 0)
                return fd;
        }

        if(version != ADB_SERVER_VERSION) {
            printf("adb server is out of date.  killing...\n");
            fd = _adb_connect("host:kill");
            adb_close(fd);

            /* XXX can we better detect its death? */
            adb_sleep_ms(2000);
            goto start_server;
        }
    }

    // if the command is start-server, we are done.
    if (!strcmp(service, "host:start-server"))
        return 0;

    fd = _adb_connect(service);
    if(fd == -1) {
        D("_adb_connect error: %s", __adb_error);
    } else if(fd == -2) {
        fprintf(stderr,"** daemon still not running\n");
    }
    D("adb_connect: return fd %d\n", fd);

    return fd;
error:
    adb_close(fd);
    return -1;
}
Exemplo n.º 21
0
void restart_usb_service(int fd, void *cookie) {
    android::base::SetProperty("service.adb.tcp.port", "0");
    WriteFdExactly(fd, "restarting in USB mode\n");
    adb_close(fd);
}
Exemplo n.º 22
0
int launch_server(int server_port)
{
#if defined(_WIN32)
    /* we need to start the server in the background                    */
    /* we create a PIPE that will be used to wait for the server's "OK" */
    /* message since the pipe handles must be inheritable, we use a     */
    /* security attribute                                               */
    HANDLE                pipe_read, pipe_write;
    HANDLE                stdout_handle, stderr_handle;
    SECURITY_ATTRIBUTES   sa;
    STARTUPINFO           startup;
    PROCESS_INFORMATION   pinfo;
    char                  program_path[ MAX_PATH ];
    int                   ret;

    sa.nLength = sizeof(sa);
    sa.lpSecurityDescriptor = NULL;
    sa.bInheritHandle = TRUE;

    /* create pipe, and ensure its read handle isn't inheritable */
    ret = CreatePipe( &pipe_read, &pipe_write, &sa, 0 );
    if (!ret) {
        fprintf(stderr, "CreatePipe() failure, error %ld\n", GetLastError() );
        return -1;
    }

    SetHandleInformation( pipe_read, HANDLE_FLAG_INHERIT, 0 );

    /* Some programs want to launch an adb command and collect its output by
     * calling CreateProcess with inheritable stdout/stderr handles, then
     * using read() to get its output. When this happens, the stdout/stderr
     * handles passed to the adb client process will also be inheritable.
     * When starting the adb server here, care must be taken to reset them
     * to non-inheritable.
     * Otherwise, something bad happens: even if the adb command completes,
     * the calling process is stuck while read()-ing from the stdout/stderr
     * descriptors, because they're connected to corresponding handles in the
     * adb server process (even if the latter never uses/writes to them).
     */
    stdout_handle = GetStdHandle( STD_OUTPUT_HANDLE );
    stderr_handle = GetStdHandle( STD_ERROR_HANDLE );
    if (stdout_handle != INVALID_HANDLE_VALUE) {
        SetHandleInformation( stdout_handle, HANDLE_FLAG_INHERIT, 0 );
    }
    if (stderr_handle != INVALID_HANDLE_VALUE) {
        SetHandleInformation( stderr_handle, HANDLE_FLAG_INHERIT, 0 );
    }

    ZeroMemory( &startup, sizeof(startup) );
    startup.cb = sizeof(startup);
    startup.hStdInput  = GetStdHandle( STD_INPUT_HANDLE );
    startup.hStdOutput = pipe_write;
    startup.hStdError  = GetStdHandle( STD_ERROR_HANDLE );
    startup.dwFlags    = STARTF_USESTDHANDLES;

    ZeroMemory( &pinfo, sizeof(pinfo) );

    /* get path of current program */
    GetModuleFileName( NULL, program_path, sizeof(program_path) );
    char args[64];
    snprintf(args, sizeof(args), "adb -P %d fork-server server",  server_port);
    ret = CreateProcess(
            program_path,                              /* program path  */
            args,
                                    /* the fork-server argument will set the
                                       debug = 2 in the child           */
            NULL,                   /* process handle is not inheritable */
            NULL,                    /* thread handle is not inheritable */
            TRUE,                          /* yes, inherit some handles */
            DETACHED_PROCESS, /* the new process doesn't have a console */
            NULL,                     /* use parent's environment block */
            NULL,                    /* use parent's starting directory */
            &startup,                 /* startup info, i.e. std handles */
            &pinfo );

    CloseHandle( pipe_write );

    if (!ret) {
        fprintf(stderr, "CreateProcess failure, error %ld\n", GetLastError() );
        CloseHandle( pipe_read );
        return -1;
    }

    CloseHandle( pinfo.hProcess );
    CloseHandle( pinfo.hThread );

    /* wait for the "OK\n" message */
    {
        char  temp[3];
        DWORD  count;

        ret = ReadFile( pipe_read, temp, 3, &count, NULL );
        CloseHandle( pipe_read );
        if ( !ret ) {
            fprintf(stderr, "could not read ok from ADB Server, error = %ld\n", GetLastError() );
            return -1;
        }
        if (count != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') {
            fprintf(stderr, "ADB server didn't ACK\n" );
            return -1;
        }
    }
#else /* !defined(_WIN32) */
    char    path[PATH_MAX];
    int     fd[2];

    // set up a pipe so the child can tell us when it is ready.
    // fd[0] will be parent's end, and fd[1] will get mapped to stderr in the child.
    if (pipe(fd)) {
        fprintf(stderr, "pipe failed in launch_server, errno: %d\n", errno);
        return -1;
    }
    get_my_path(path, PATH_MAX);
    pid_t pid = fork();
    if(pid < 0) return -1;

    if (pid == 0) {
        // child side of the fork

        // redirect stderr to the pipe
        // we use stderr instead of stdout due to stdout's buffering behavior.
        adb_close(fd[0]);
        dup2(fd[1], STDERR_FILENO);
        adb_close(fd[1]);

        char str_port[30];
        snprintf(str_port, sizeof(str_port), "%d",  server_port);
        // child process
        int result = execl(path, "adb", "-P", str_port, "fork-server", "server", NULL);
        // this should not return
        fprintf(stderr, "OOPS! execl returned %d, errno: %d\n", result, errno);
    } else  {
        // parent side of the fork

        char  temp[3];

        temp[0] = 'A'; temp[1] = 'B'; temp[2] = 'C';
        // wait for the "OK\n" message
        adb_close(fd[1]);
        int ret = adb_read(fd[0], temp, 3);
        int saved_errno = errno;
        adb_close(fd[0]);
        if (ret < 0) {
            fprintf(stderr, "could not read ok from ADB Server, errno = %d\n", saved_errno);
            return -1;
        }
        if (ret != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') {
            fprintf(stderr, "ADB server didn't ACK\n" );
            return -1;
        }

        setsid();
    }
#endif /* !defined(_WIN32) */
    return 0;
}
Exemplo n.º 23
0
int sync_recv(int fd, const char *rpath, const char *lpath, int show_progress)
{
    syncmsg msg;
    int len;
    int lfd = -1;
    char *buffer = send_buffer.data;
    unsigned id;
    unsigned long long size = 0;

    len = strlen(rpath);
    if(len > 1024) return -1;

    if (show_progress) {
        // Determine remote file size.
        syncmsg stat_msg;
        stat_msg.req.id = ID_STAT;
        stat_msg.req.namelen = htoll(len);

        if (writex(fd, &stat_msg.req, sizeof(stat_msg.req)) ||
            writex(fd, rpath, len)) {
            return -1;
        }

        if (readx(fd, &stat_msg.stat, sizeof(stat_msg.stat))) {
            return -1;
        }

        if (stat_msg.stat.id != ID_STAT) return -1;

        size = ltohl(stat_msg.stat.size);
    }

    msg.req.id = ID_RECV;
    msg.req.namelen = htoll(len);
    if(writex(fd, &msg.req, sizeof(msg.req)) ||
       writex(fd, rpath, len)) {
        return -1;
    }

    if(readx(fd, &msg.data, sizeof(msg.data))) {
        return -1;
    }
    id = msg.data.id;

    if((id == ID_DATA) || (id == ID_DONE)) {
        adb_unlink(lpath);
        mkdirs(lpath);
        lfd = adb_creat(lpath, 0644);
        if(lfd < 0) {
            fprintf(stderr,"cannot create '%s': %s\n", lpath, strerror(errno));
            return -1;
        }
        goto handle_data;
    } else {
        goto remote_error;
    }

    for(;;) {
        if(readx(fd, &msg.data, sizeof(msg.data))) {
            return -1;
        }
        id = msg.data.id;

    handle_data:
        len = ltohl(msg.data.size);
        if(id == ID_DONE) break;
        if(id != ID_DATA) goto remote_error;
        if(len > SYNC_DATA_MAX) {
            fprintf(stderr,"data overrun\n");
            adb_close(lfd);
            return -1;
        }

        if(readx(fd, buffer, len)) {
            adb_close(lfd);
            return -1;
        }

        if(writex(lfd, buffer, len)) {
            fprintf(stderr,"cannot write '%s': %s\n", rpath, strerror(errno));
            adb_close(lfd);
            return -1;
        }

        total_bytes += len;

        if (show_progress) {
            print_transfer_progress(total_bytes, size);
        }
    }

    adb_close(lfd);
    return 0;

remote_error:
    adb_close(lfd);
    adb_unlink(lpath);

    if(id == ID_FAIL) {
        len = ltohl(msg.data.size);
        if(len > 256) len = 256;
        if(readx(fd, buffer, len)) {
            return -1;
        }
        buffer[len] = 0;
    } else {
        memcpy(buffer, &id, 4);
        buffer[4] = 0;
//        strcpy(buffer,"unknown reason");
    }
    fprintf(stderr,"failed to copy '%s' to '%s': %s\n", rpath, lpath, buffer);
    return 0;
}
Exemplo n.º 24
0
static int sync_send(int fd, const char *lpath, const char *rpath,
                     unsigned mtime, mode_t mode, int show_progress)
{
    syncmsg msg;
    int len, r;
    syncsendbuf *sbuf = &send_buffer;
    char* file_buffer = NULL;
    int size = 0;
    char tmp[64];

    len = strlen(rpath);
    if(len > 1024) goto fail;

    snprintf(tmp, sizeof(tmp), ",%d", mode);
    r = strlen(tmp);

    msg.req.id = ID_SEND;
    msg.req.namelen = htoll(len + r);

    if(writex(fd, &msg.req, sizeof(msg.req)) ||
       writex(fd, rpath, len) || writex(fd, tmp, r)) {
        free(file_buffer);
        goto fail;
    }

    if (file_buffer) {
        write_data_buffer(fd, file_buffer, size, sbuf, show_progress);
        free(file_buffer);
    } else if (S_ISREG(mode))
        write_data_file(fd, lpath, sbuf, show_progress);
#ifdef HAVE_SYMLINKS
    else if (S_ISLNK(mode))
        write_data_link(fd, lpath, sbuf);
#endif
    else
        goto fail;

    msg.data.id = ID_DONE;
    msg.data.size = htoll(mtime);
    if(writex(fd, &msg.data, sizeof(msg.data)))
        goto fail;

    if(readx(fd, &msg.status, sizeof(msg.status)))
        return -1;

    if(msg.status.id != ID_OKAY) {
        if(msg.status.id == ID_FAIL) {
            len = ltohl(msg.status.msglen);
            if(len > 256) len = 256;
            if(readx(fd, sbuf->data, len)) {
                return -1;
            }
            sbuf->data[len] = 0;
        } else
            strcpy(sbuf->data, "unknown reason");

        fprintf(stderr,"failed to copy '%s' to '%s': %s\n", lpath, rpath, sbuf->data);
        return -1;
    }

    return 0;

fail:
    fprintf(stderr,"protocol failure\n");
    adb_close(fd);
    return -1;
}
Exemplo n.º 25
0
int launch_server(int server_port)
{
#ifdef HAVE_WIN32_PROC
    /* we need to start the server in the background                    */
    /* we create a PIPE that will be used to wait for the server's "OK" */
    /* message since the pipe handles must be inheritable, we use a     */
    /* security attribute                                               */
    HANDLE                pipe_read, pipe_write;
    SECURITY_ATTRIBUTES   sa;
    STARTUPINFO           startup;
    PROCESS_INFORMATION   pinfo;
    char                  program_path[ MAX_PATH ];
    int                   ret;

    sa.nLength = sizeof(sa);
    sa.lpSecurityDescriptor = NULL;
    sa.bInheritHandle = TRUE;

    /* create pipe, and ensure its read handle isn't inheritable */
    ret = CreatePipe( &pipe_read, &pipe_write, &sa, 0 );
    if (!ret) {
        fprintf(stderr, "CreatePipe() failure, error %ld\n", GetLastError() );
        return -1;
    }

    SetHandleInformation( pipe_read, HANDLE_FLAG_INHERIT, 0 );

    ZeroMemory( &startup, sizeof(startup) );
    startup.cb = sizeof(startup);
    startup.hStdInput  = GetStdHandle( STD_INPUT_HANDLE );
    startup.hStdOutput = pipe_write;
    startup.hStdError  = GetStdHandle( STD_ERROR_HANDLE );
    startup.dwFlags    = STARTF_USESTDHANDLES;

    ZeroMemory( &pinfo, sizeof(pinfo) );

    /* get path of current program */
    GetModuleFileName( NULL, program_path, sizeof(program_path) );

    ret = CreateProcess(
            program_path,                              /* program path  */
            "adb fork-server server",
                                    /* the fork-server argument will set the
                                       debug = 2 in the child           */
            NULL,                   /* process handle is not inheritable */
            NULL,                    /* thread handle is not inheritable */
            TRUE,                          /* yes, inherit some handles */
            DETACHED_PROCESS, /* the new process doesn't have a console */
            NULL,                     /* use parent's environment block */
            NULL,                    /* use parent's starting directory */
            &startup,                 /* startup info, i.e. std handles */
            &pinfo );

    CloseHandle( pipe_write );

    if (!ret) {
        fprintf(stderr, "CreateProcess failure, error %ld\n", GetLastError() );
        CloseHandle( pipe_read );
        return -1;
    }

    CloseHandle( pinfo.hProcess );
    CloseHandle( pinfo.hThread );

    /* wait for the "OK\n" message */
    {
        char  temp[3];
        DWORD  count;

        ret = ReadFile( pipe_read, temp, 3, &count, NULL );
        CloseHandle( pipe_read );
        if ( !ret ) {
            fprintf(stderr, "could not read ok from ADB Server, error = %ld\n", GetLastError() );
            return -1;
        }
        if (count != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') {
            fprintf(stderr, "ADB server didn't ACK\n" );
            return -1;
        }
    }
#elif defined(HAVE_FORKEXEC)
    char    path[PATH_MAX];
    int     fd[2];

    // set up a pipe so the child can tell us when it is ready.
    // fd[0] will be parent's end, and fd[1] will get mapped to stderr in the child.
    if (pipe(fd)) {
        fprintf(stderr, "pipe failed in launch_server, errno: %d\n", errno);
        return -1;
    }
    get_my_path(path, PATH_MAX);
    pid_t pid = fork();
    if(pid < 0) return -1;

    if (pid == 0) {
        // child side of the fork

        // redirect stderr to the pipe
        // we use stderr instead of stdout due to stdout's buffering behavior.
        adb_close(fd[0]);
        dup2(fd[1], STDERR_FILENO);
        adb_close(fd[1]);

        // child process
        int result = execl(path, "adb", "fork-server", "server", NULL);
        // this should not return
        fprintf(stderr, "OOPS! execl returned %d, errno: %d\n", result, errno);
    } else  {
        // parent side of the fork

        char  temp[3];

        temp[0] = 'A'; temp[1] = 'B'; temp[2] = 'C';
        // wait for the "OK\n" message
        adb_close(fd[1]);
        int ret = adb_read(fd[0], temp, 3);
        adb_close(fd[0]);
        if (ret < 0) {
            fprintf(stderr, "could not read ok from ADB Server, errno = %d\n", errno);
            return -1;
        }
        if (ret != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') {
            fprintf(stderr, "ADB server didn't ACK\n" );
            return -1;
        }

        setsid();
    }
#else
#error "cannot implement background server start on this platform"
#endif
    return 0;
}
int adb_connect(const std::string& service, std::string* error) {
    // first query the adb server's version
    int fd = _adb_connect("host:version", error);

    D("adb_connect: service %s", service.c_str());
    if (fd == -2 && __adb_server_name) {
        fprintf(stderr,"** Cannot start server on remote host\n");
        // error is the original network connection error
        return fd;
    } else if (fd == -2) {
        fprintf(stdout,"* daemon not running. starting it now on port %d *\n",
                __adb_server_port);
    start_server:
        if (launch_server(__adb_server_port)) {
            fprintf(stderr,"* failed to start daemon *\n");
            // launch_server() has already printed detailed error info, so just
            // return a generic error string about the overall adb_connect()
            // that the caller requested.
            *error = "cannot connect to daemon";
            return -1;
        } else {
            fprintf(stdout,"* daemon started successfully *\n");
        }
        /* give the server some time to start properly and detect devices */
        adb_sleep_ms(3000);
        // fall through to _adb_connect
    } else {
        // if server was running, check its version to make sure it is not out of date
        int version = ADB_SERVER_VERSION - 1;

        // if we have a file descriptor, then parse version result
        if (fd >= 0) {
            std::string version_string;
            if (!ReadProtocolString(fd, &version_string, error)) {
                goto error;
            }

            adb_close(fd);

            if (sscanf(&version_string[0], "%04x", &version) != 1) {
                *error = android::base::StringPrintf(
                        "cannot parse version string: %s",
                        version_string.c_str());
                return -1;
            }
        } else {
            // if fd is -1, then check for "unknown host service",
            // which would indicate a version of adb that does not support the
            // version command, in which case we should fall-through to kill it.
            if (*error != "unknown host service") {
                return fd;
            }
        }

        if (version != ADB_SERVER_VERSION) {
            printf("adb server is out of date.  killing...\n");
            fd = _adb_connect("host:kill", error);
            if (fd >= 0) {
                adb_close(fd);
            } else {
                // If we couldn't connect to the server or had some other error,
                // report it, but still try to start the server.
                fprintf(stderr, "error: %s\n", error->c_str());
            }

            /* XXX can we better detect its death? */
            adb_sleep_ms(2000);
            goto start_server;
        }
    }

    // if the command is start-server, we are done.
    if (service == "host:start-server") {
        return 0;
    }

    fd = _adb_connect(service, error);
    if (fd == -1) {
        D("_adb_connect error: %s", error->c_str());
    } else if(fd == -2) {
        fprintf(stderr,"** daemon still not running\n");
    }
    D("adb_connect: return fd %d", fd);

    return fd;
error:
    adb_close(fd);
    return -1;
}
Exemplo n.º 27
0
static void reconnect_service(int fd, void* arg) {
    WriteFdExactly(fd, "done");
    adb_close(fd);
    atransport* t = static_cast<atransport*>(arg);
    kick_transport(t);
}
Exemplo n.º 28
0
static void transport_registration_func(int _fd, unsigned ev, void *data)
{
    tmsg m;
    int s[2];
    atransport *t;

    if(!(ev & FDE_READ)) {
        return;
    }

    if(transport_read_action(_fd, &m)) {
        fatal_errno("cannot read transport registration socket");
    }

    t = m.transport;

    if (m.action == 0) {
        D("transport: %s removing and free'ing %d", t->serial, t->transport_socket);

            /* IMPORTANT: the remove closes one half of the
            ** socket pair.  The close closes the other half.
            */
        fdevent_remove(&(t->transport_fde));
        adb_close(t->fd);

        adb_mutex_lock(&transport_lock);
        transport_list.remove(t);
        adb_mutex_unlock(&transport_lock);

        if (t->product)
            free(t->product);
        if (t->serial)
            free(t->serial);
        if (t->model)
            free(t->model);
        if (t->device)
            free(t->device);
        if (t->devpath)
            free(t->devpath);

        delete t;

        update_transports();
        return;
    }

    /* don't create transport threads for inaccessible devices */
    if (t->connection_state != kCsNoPerm) {
        /* initial references are the two threads */
        t->ref_count = 2;

        if (adb_socketpair(s)) {
            fatal_errno("cannot open transport socketpair");
        }

        D("transport: %s socketpair: (%d,%d) starting", t->serial, s[0], s[1]);

        t->transport_socket = s[0];
        t->fd = s[1];

        fdevent_install(&(t->transport_fde),
                        t->transport_socket,
                        transport_socket_events,
                        t);

        fdevent_set(&(t->transport_fde), FDE_READ);

        if (!adb_thread_create(write_transport_thread, t)) {
            fatal_errno("cannot create write_transport thread");
        }

        if (!adb_thread_create(read_transport_thread, t)) {
            fatal_errno("cannot create read_transport thread");
        }
    }

    adb_mutex_lock(&transport_lock);
    pending_list.remove(t);
    transport_list.push_front(t);
    adb_mutex_unlock(&transport_lock);

    update_transports();
}
Exemplo n.º 29
0
void restart_usb_service(int fd, void *cookie) {
    property_set("service.adb.tcp.port", "0");
    WriteFdExactly(fd, "restarting in USB mode\n");
    adb_close(fd);
}
Exemplo n.º 30
0
static void transport_registration_func(int _fd, unsigned ev, void *data)
{
    tmsg m;
    adb_thread_t output_thread_ptr;
    adb_thread_t input_thread_ptr;
    int s[2];
    atransport *t;

    if(!(ev & FDE_READ))
	{
        return;
    }

    if(transport_read_action(_fd, &m))
	{
        fatal_errno("cannot read transport registration socket");
    }

    t = m.transport;
	//action0 ÒƳý action1 ²åÈë
    if(m.action == 0)
	{
        D("transport: %s removing and free'ing %d\n", t->serial, t->transport_socket);

            /* IMPORTANT: the remove closes one half of the
            ** socket pair.  The close closes the other half.
            */
        fdevent_remove(&(t->transport_fde));
        adb_close(t->fd);

        adb_mutex_lock(&transport_lock);
        t->next->prev = t->prev;
        t->prev->next = t->next;
        adb_mutex_unlock(&transport_lock);

        run_transport_disconnects(t);


		if (t->product)
			free(t->product);
		if (t->serial)
			free(t->serial);
		if (t->model)
			free(t->model);
		if (t->device)
			free(t->device);
		if (t->devpath)
			free(t->devpath);

        memset(t,0xee,sizeof(atransport));
        free(t);

        update_transports();
        return;
    }

    /* don't create transport threads for inaccessible devices */
    if (t->connection_state != CS_NOPERM) {
        /* initial references are the two threads */
        t->ref_count = 2;

        if(adb_socketpair(s)) {
            fatal_errno("cannot open transport socketpair");
        }

        D("transport: %s (%d,%d) starting\n", t->serial, s[0], s[1]);

        t->transport_socket = s[0];
        t->fd = s[1];

        fdevent_install(&(t->transport_fde),
                        t->transport_socket,
                        transport_socket_events,
                        t);

        fdevent_set(&(t->transport_fde), FDE_READ);

        if(adb_thread_create(&input_thread_ptr, input_thread, t)){
            fatal_errno("cannot create input thread");
        }

        if(adb_thread_create(&output_thread_ptr, output_thread, t)){
            fatal_errno("cannot create output thread");
        }
    }

    adb_mutex_lock(&transport_lock);
    /* remove from pending list */
    t->next->prev = t->prev;
    t->prev->next = t->next;
    /* put us on the master device list */
    t->next = &transport_list;
    t->prev = transport_list.prev;
    t->next->prev = t;
    t->prev->next = t;
    adb_mutex_unlock(&transport_lock);

    t->disconnects.next = t->disconnects.prev = &t->disconnects;

    update_transports();
}