Ejemplo n.º 1
0
static int run(const char * const who, const char * const file,
               const int upload_pipe_fd)
{
    struct stat st;
    pid_t pid;

    if (script == NULL || *script == 0 ||
        file == NULL || *file == 0 ||
        lstat(file, &st) < 0 ||
        !S_ISREG(st.st_mode)) {
        return -1;
    }
    pid = fork();
    if (pid == (pid_t) 0) {
        /* Yes, there's already the cloexec flag on this fd,
         * but it's really important to close it. Be paranoid.
         */
        if (close(upload_pipe_fd) < 0 || closedesc_all(1) < 0) {
            _exit(EXIT_FAILURE);
        }
        fillenv(who, &st);
        execl(script, script, file, (char *) NULL);
        _exit(EXIT_FAILURE);
    } else if (pid != (pid_t) -1) {
#ifdef HAVE_WAITPID
        (void) waitpid(pid, NULL, 0);
#else
        {
            pid_t foundpid;

            while ((foundpid = wait3(NULL, 0, NULL)) != (pid_t) -1 &&
                   foundpid != pid);
        }
#endif
    }

    return 0;
}
Ejemplo n.º 2
0
Archivo: cgi.c Proyecto: yuruiz/Liso
int cgihandle(response_t *resp) {

    /*************** BEGIN VARIABLE DECLARATIONS **************/
    pid_t pid;
    int stdin_pipe[2];
    int stdout_pipe[2];
    char buf[BUF_SIZE];
    int readret;
    char** envp;
    /*************** END VARIABLE DECLARATIONS **************/

    logging("now in cgi handling routine\n");
    /*************** BEGIN PIPE **************/
    /* 0 can be read from, 1 can be written to */
    if (pipe(stdin_pipe) < 0) {
        logging("Error piping for stdin.\n");
        return -1;
    }

    if (pipe(stdout_pipe) < 0) {
        logging("Error piping for stdout.\n");
        return -1;
    }
    /*************** END PIPE **************/

    logging("start building the environment array\n");
    buildEnvp(resp);

    logging("Start Filling envrionment array\n");
    if ((envp = fillenv(resp)) == NULL) {
        return -1;
    }

    logging("Filling environment array successed!\n");
    /*************** BEGIN FORK **************/
    pid = fork();
    /* not good */
    if (pid < 0) {
        logging("Something really bad happened when forking.\n");
        return -1;
    }

    /* child, setup environment, execve */
    if (pid == 0) {
        /*************** BEGIN EXECVE ****************/
        close(stdout_pipe[0]);
        close(stdin_pipe[1]);
        dup2(stdout_pipe[1], fileno(stdout));
        dup2(stdin_pipe[0], fileno(stdin));
//        dup2(getlogfd(), fileno(stderr));

        /* pretty much no matter what, if it returns bad things happened... */

        if (execve(_cgipath, ARGV, envp)) {
            execve_error_handler();
            logging("Error executing execve syscall.\n");
            exit(EXIT_FAILURE);
        }
        /*************** END EXECVE ****************/
    }

    if (pid > 0) {
        logging("Parent: Heading to select() loop.\n");
        close(stdout_pipe[1]);
        close(stdin_pipe[0]);

        int i = 0;
        for (i = 0; i < CGI_HEADER_LEN; ++i) {
            free(envp[i]);
        }

        if (resp->method == POST) {
            if (write(stdin_pipe[1], resp->postbody, resp->postlen) < 0) {
                logging( "Error writing to spawned CGI program.\n");
                close(stdin_pipe[1]);
                return -1;
            }
        }
        close(stdin_pipe[1]); /* finished writing to spawn */

        resp->cgiNode = malloc(sizeof(cgi_node));
        resp->cgiNode->connfd = stdout_pipe[0];
        resp->cgiNode->pid = pid;
    }
    /*************** END FORK **************/

    return 0;
}