/*
 * Copyright (C) 2007 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.
 */

#define LOG_TAG "Zygote"

#include <cutils/sockets.h>
#include <cutils/zygote.h>
#include <cutils/log.h>

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>

#define ZYGOTE_SOCKET "zygote"

#define ZYGOTE_RETRY_COUNT 1000
#define ZYGOTE_RETRY_MILLIS 500

static void replace_nl(char *str);

/*
 * 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
    // not supported on simulator targets
    //ALOGE("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 */
}

int zygote_run_wait(int argc, const char **argv, void (*post_run_func)(int))
{
    int fd;
    int pid;
    int err;
    const char *newargv[argc + 1];

    fd = socket_local_client(ZYGOTE_SOCKET, 
            ANDROID_SOCKET_NAMESPACE_RESERVED, AF_LOCAL);

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

    // The command socket is passed to the peer as close-on-exec
    // and will close when the peer dies
    newargv[0] = "--peer-wait";
    memcpy(newargv + 1, argv, argc * sizeof(*argv)); 

    pid = send_request(fd, 1, argc + 1, newargv);

    if (pid > 0 && post_run_func != NULL) {
        post_run_func(pid);
    }

    // Wait for socket to close
    do {
        int dummy;
        err = read(fd, &dummy, sizeof(dummy));
    } while ((err < 0 && errno == EINTR) || err != 0);

    do {
        err = close(fd);
    } while (err < 0 && errno == EINTR);

    return 0;
}

/**
 * Spawns a new dalvik instance via the Zygote process. The non-zygote
 * arguments are passed to com.android.internal.os.RuntimeInit(). The
 * first non-option argument should be a class name in the system class path.
 *
 * The arg list  may start with zygote params such as --set-uid.
 *
 * If sendStdio is non-zero, the current process's stdio file descriptors
 * will be sent and inherited by the spawned process.
 *
 * The pid of the child process is returned, or -1 if an error was 
 * encountered.
 *
 * zygote_run_oneshot waits up to ZYGOTE_RETRY_COUNT * 
 * ZYGOTE_RETRY_MILLIS for the zygote socket to be available.
 */
int zygote_run_oneshot(int sendStdio, int argc, const char **argv) 
{
    int fd = -1;
    int err;
    int i;
    int retries;
    int pid;
    const char **newargv = argv;
    const int newargc = argc;

    for (retries = 0; (fd < 0) && (retries < ZYGOTE_RETRY_COUNT); retries++) {
        if (retries > 0) { 
            struct timespec ts;

            memset(&ts, 0, sizeof(ts));
            ts.tv_nsec = ZYGOTE_RETRY_MILLIS * 1000 * 1000;

            do {
                err = nanosleep (&ts, &ts);
            } while (err < 0 && errno == EINTR);
        }
        fd = socket_local_client(ZYGOTE_SOCKET, AF_LOCAL, 
                ANDROID_SOCKET_NAMESPACE_RESERVED);
    }

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

    pid = send_request(fd, 0, newargc, newargv);

    do {
        err = close(fd);
    } while (err < 0 && errno == EINTR);

    return pid;
}

/**
 * Replaces all occurrances of newline with space.
 */
static void replace_nl(char *str)
{
    for(; *str; str++) {
        if (*str == '\n') {
            *str = ' ';
        }
    }
}



