libcutils/zygote.c
static int send_request(int fd, int sendStdio, int argc, const char **argv)
{
#ifndef HAVE_ANDROID_OS
    // not supported on simulator targets
    //LOGE("zygote_* not supported on simulator targets");
    return -1;
#else /* HAVE_ANDROID_OS */
    uint32_t pid;
    int i;
    struct iovec ivs[2];
    struct msghdr msg;
    char argc_buffer[12];
    const char *newline_string = "\n";
    struct cmsghdr *cmsg;
    char msgbuf[CMSG_SPACE(sizeof(int) * 3)];
    int *cmsg_payload;
    ssize_t ret;

    memset(&msg, 0, sizeof(msg));
    memset(&ivs, 0, sizeof(ivs));

    // First line is arg count 
    snprintf(argc_buffer, sizeof(argc_buffer), "%d\n", argc);

    ivs[0].iov_base = argc_buffer;
    ivs[0].iov_len = strlen(argc_buffer);

    msg.msg_iov = ivs;
    msg.msg_iovlen = 1;

    if (sendStdio != 0) {
        // Pass the file descriptors with the first write
        msg.msg_control = msgbuf;
        msg.msg_controllen = sizeof msgbuf;

        cmsg = CMSG_FIRSTHDR(&msg);

        cmsg->cmsg_len = CMSG_LEN(3 * sizeof(int));
        cmsg->cmsg_level = SOL_SOCKET;
        cmsg->cmsg_type = SCM_RIGHTS;

        cmsg_payload = (int *)CMSG_DATA(cmsg);
        cmsg_payload[0] = STDIN_FILENO;
        cmsg_payload[1] = STDOUT_FILENO;
        cmsg_payload[2] = STDERR_FILENO;
    }

    do {
        ret = sendmsg(fd, &msg, MSG_NOSIGNAL);
    } while (ret < 0 && errno == EINTR);

    if (ret < 0) {
        return -1;
    }

    // Only send the fd's once
    msg.msg_control = NULL;
    msg.msg_controllen = 0;

    // replace any newlines with spaces and send the args
    for (i = 0; i < argc; i++) {
        char *tofree = NULL;
        const char *toprint;

        toprint = argv[i];

        if (strchr(toprint, '\n') != NULL) {
            tofree = strdup(toprint);
            toprint = tofree;
            replace_nl(tofree);
        }

        ivs[0].iov_base = (char *)toprint;
        ivs[0].iov_len = strlen(toprint);
        ivs[1].iov_base = (char *)newline_string;
        ivs[1].iov_len = 1;

        msg.msg_iovlen = 2;

        do {
            ret = sendmsg(fd, &msg, MSG_NOSIGNAL);
        } while (ret < 0 && errno == EINTR);

        if (tofree != NULL) {
            free(tofree);
        }

        if (ret < 0) {
            return -1;
        }
    }

    // Read the pid, as a 4-byte network-order integer

    ivs[0].iov_base = &pid;
    ivs[0].iov_len = sizeof(pid);
    msg.msg_iovlen = 1;

    do {
        do {
            ret = recvmsg(fd, &msg, MSG_NOSIGNAL | MSG_WAITALL);
        } while (ret < 0 && errno == EINTR);

        if (ret < 0) {
            return -1;
        }

        ivs[0].iov_len -= ret;
        ivs[0].iov_base += ret;
    } while (ivs[0].iov_len > 0);

    pid = ntohl(pid);

    return pid;
#endif /* HAVE_ANDROID_OS */
}
/*
 * If sendStdio is non-zero, the current process's stdio file descriptors
 * will be sent and inherited by the spawned process.
 */
If sendStdio is non-zero, the current process's stdio file descriptors
will be sent and inherited by the spawned process.
If sendStdio is non - zero the current process ' s stdio file descriptors will be sent and inherited by the spawned process .
static int send_request(int fd, int sendStdio, int argc, const char **argv)
{
#ifndef HAVE_ANDROID_OS
    return -1;
#else 
    uint32_t pid;
    int i;
    struct iovec ivs[2];
    struct msghdr msg;
    char argc_buffer[12];
    const char *newline_string = "\n";
    struct cmsghdr *cmsg;
    char msgbuf[CMSG_SPACE(sizeof(int) * 3)];
    int *cmsg_payload;
    ssize_t ret;
    memset(&msg, 0, sizeof(msg));
    memset(&ivs, 0, sizeof(ivs));
    snprintf(argc_buffer, sizeof(argc_buffer), "%d\n", argc);
    ivs[0].iov_base = argc_buffer;
    ivs[0].iov_len = strlen(argc_buffer);
    msg.msg_iov = ivs;
    msg.msg_iovlen = 1;
    if (sendStdio != 0) {
        msg.msg_control = msgbuf;
        msg.msg_controllen = sizeof msgbuf;
        cmsg = CMSG_FIRSTHDR(&msg);
        cmsg->cmsg_len = CMSG_LEN(3 * sizeof(int));
        cmsg->cmsg_level = SOL_SOCKET;
        cmsg->cmsg_type = SCM_RIGHTS;
        cmsg_payload = (int *)CMSG_DATA(cmsg);
        cmsg_payload[0] = STDIN_FILENO;
        cmsg_payload[1] = STDOUT_FILENO;
        cmsg_payload[2] = STDERR_FILENO;
    }
    do {
        ret = sendmsg(fd, &msg, MSG_NOSIGNAL);
    } while (ret < 0 && errno == EINTR);
    if (ret < 0) {
        return -1;
    }
    msg.msg_control = NULL;
    msg.msg_controllen = 0;
    for (i = 0; i < argc; i++) {
        char *tofree = NULL;
        const char *toprint;
        toprint = argv[i];
        if (strchr(toprint, '\n') != NULL) {
            tofree = strdup(toprint);
            toprint = tofree;
            replace_nl(tofree);
        }
        ivs[0].iov_base = (char *)toprint;
        ivs[0].iov_len = strlen(toprint);
        ivs[1].iov_base = (char *)newline_string;
        ivs[1].iov_len = 1;
        msg.msg_iovlen = 2;
        do {
            ret = sendmsg(fd, &msg, MSG_NOSIGNAL);
        } while (ret < 0 && errno == EINTR);
        if (tofree != NULL) {
            free(tofree);
        }
        if (ret < 0) {
            return -1;
        }
    }
    ivs[0].iov_base = &pid;
    ivs[0].iov_len = sizeof(pid);
    msg.msg_iovlen = 1;
    do {
        do {
            ret = recvmsg(fd, &msg, MSG_NOSIGNAL | MSG_WAITALL);
        } while (ret < 0 && errno == EINTR);
        if (ret < 0) {
            return -1;
        }
        ivs[0].iov_len -= ret;
        ivs[0].iov_base += ret;
    } while (ivs[0].iov_len > 0);
    pid = ntohl(pid);
    return pid;
#endif 
}
static int send_request ( int fd , int sendStdio , int argc , const char * * argv ) { #ifndef HAVE_ANDROID_OS return -1 ; #else uint32_t pid ; int i ; struct iovec ivs [ 2 ] ; struct msghdr msg ; char argc_buffer [ 12 ] ; const char * newline_string = " \n " ; struct cmsghdr * cmsg ; char msgbuf [ CMSG_SPACE ( sizeof ( int ) * 3 ) ] ; int * cmsg_payload ; ssize_t ret ; memset ( & msg , 0 , sizeof ( msg ) ) ; memset ( & ivs , 0 , sizeof ( ivs ) ) ; snprintf ( argc_buffer , sizeof ( argc_buffer ) , " \n " , argc ) ; ivs [ 0 ] . iov_base = argc_buffer ; ivs [ 0 ] . iov_len = strlen ( argc_buffer ) ; msg . msg_iov = ivs ; msg . msg_iovlen = 1 ; if ( sendStdio != 0 ) { msg . msg_control = msgbuf ; msg . msg_controllen = sizeof msgbuf ; cmsg = CMSG_FIRSTHDR ( & msg ) ; cmsg -> cmsg_len = CMSG_LEN ( 3 * sizeof ( int ) ) ; cmsg -> cmsg_level = SOL_SOCKET ; cmsg -> cmsg_type = SCM_RIGHTS ; cmsg_payload = ( int * ) CMSG_DATA ( cmsg ) ; cmsg_payload [ 0 ] = STDIN_FILENO ; cmsg_payload [ 1 ] = STDOUT_FILENO ; cmsg_payload [ 2 ] = STDERR_FILENO ; } do { ret = sendmsg ( fd , & msg , MSG_NOSIGNAL ) ; } while ( ret < 0 && errno == EINTR ) ; if ( ret < 0 ) { return -1 ; } msg . msg_control = NULL ; msg . msg_controllen = 0 ; for ( i = 0 ; i < argc ; i ++ ) { char * tofree = NULL ; const char * toprint ; toprint = argv [ i ] ; if ( strchr ( toprint , ' \n ' ) != NULL ) { tofree = strdup ( toprint ) ; toprint = tofree ; replace_nl ( tofree ) ; } ivs [ 0 ] . iov_base = ( char * ) toprint ; ivs [ 0 ] . iov_len = strlen ( toprint ) ; ivs [ 1 ] . iov_base = ( char * ) newline_string ; ivs [ 1 ] . iov_len = 1 ; msg . msg_iovlen = 2 ; do { ret = sendmsg ( fd , & msg , MSG_NOSIGNAL ) ; } while ( ret < 0 && errno == EINTR ) ; if ( tofree != NULL ) { free ( tofree ) ; } if ( ret < 0 ) { return -1 ; } } ivs [ 0 ] . iov_base = & pid ; ivs [ 0 ] . iov_len = sizeof ( pid ) ; msg . msg_iovlen = 1 ; do { do { ret = recvmsg ( fd , & msg , MSG_NOSIGNAL | MSG_WAITALL ) ; } while ( ret < 0 && errno == EINTR ) ; if ( ret < 0 ) { return -1 ; } ivs [ 0 ] . iov_len -= ret ; ivs [ 0 ] . iov_base += ret ; } while ( ivs [ 0 ] . iov_len > 0 ) ; pid = ntohl ( pid ) ; return pid ; #endif }
If sendStdio is non-zero, the current process's stdio file descriptors
 will be sent and inherited by the spawned process.
If sendStdio is non - zero the current process ' s stdio file descriptors will be sent and inherited by the spawned process .
// not supported on simulator targets //LOGE("zygote_* not supported on simulator targets"); /* HAVE_ANDROID_OS */ // First line is arg count  // Pass the file descriptors with the first write // Only send the fd's once // replace any newlines with spaces and send the args // Read the pid, as a 4-byte network-order integer /* HAVE_ANDROID_OS */