CGI-SpeedyCGI

 view release on metacpan or  search on metacpan

src/speedy_main.c  view on Meta::CPAN


#define CB_IN	(cb[0])
#define CB_OUT	(cb[1])
#define CB_ERR	(cb[2])

extern char **environ;

static CopyBuf cb[NUMFDS];
static int got_stdout, stop_sock_reads, read_stopped[NUMFDS];

/* See if done copying through this buf */
static int my_copydone(const CopyBuf *b) {
    return speedy_cb_copydone(b) &&
	(got_stdout || b != &CB_OUT || speedy_cb_eof(b));
}

/* See if we can read into this buf */
static int my_canread(const CopyBuf *b) {
    return
	!((b) != &CB_IN && stop_sock_reads && read_stopped[(b)-&CB_IN]) &&
	(speedy_cb_canread(b) ||
	    (!got_stdout && b == &CB_OUT && !speedy_cb_eof(b)));
}

/* Try to close this copy buf */
static void try_close(const CopyBuf *b) {
    if (my_copydone(b)) {
	fd_change(b->rdfd, FD_CLOSE);
	fd_change(b->wrfd, FD_CLOSE);
    }
}

static void doit(const char * const *argv, int *exit_on_sig, int *exit_val)
{
    PollInfo pi;
    SpeedyBuf ibuf;
    int backend_exited = 0, am_child = 0, in_is_tty;
    int socks[NUMFDS];
    register int i;
    slotnum_t fslotnum;

    got_stdout = stop_sock_reads = 0;

    /* Initialize file descriptors */
    fd_init(0, O_RDONLY, STDIN_INITIAL_STATE);
    for (i = 1; i <= 2; ++i)
	fd_init(i, O_WRONLY, FD_NOBLOCK);

    /* Is stdin a tty? */
    in_is_tty = fd_open(0) ? isatty(0) : 0;

    /* Initialize options */
    DO_OPT_INIT(argv, (const char * const *)environ);

#   ifdef IAMSUID
	if (speedy_util_geteuid() == 0) {
	    int new_uid;

	    /* Set group-id */
	    if (speedy_script_getstat()->st_mode & S_ISGID) {
		if (setegid(speedy_script_getstat()->st_gid) == -1)
		    speedy_util_die("setegid");
	    }

	    /* Must set euid to something - either the script owner
	     * or the real-uid
	     */
	    if (speedy_script_getstat()->st_mode & S_ISUID) {
		new_uid = speedy_script_getstat()->st_uid;
	    } else {
		new_uid = speedy_util_getuid();
	    }
	    if (speedy_util_seteuid(new_uid) == -1)
		speedy_util_die("seteuid");
	}
#   endif

    /* Create buffer with env/argv data to send */
    speedy_frontend_mkenv(
	(const char * const *)environ, speedy_opt_script_argv(), 0, &ibuf, 0
    );

    /* Allocate buffers for copying below: */
    /*	fd0 -> cb[0] -> s	*/
    speedy_cb_init(
	&CB_IN,
	max(OPTVAL_BUFSIZPOST, ibuf.alloced),
	0,
	-1,
	&ibuf
    );

    /* Read as much as possible from stdin, then make it non-blocking */
#ifdef FILL_STDIN_BUF
    if (fd_open(0)) {
	speedy_cb_read(&CB_IN);
	fd_change(0, FD_NOBLOCK);
    }
#endif

    /* Connect up with a backend */
    if (!speedy_frontend_connect(socks, &fslotnum))
	DIE_QUIET("Cannot spawn backend process");

    /* Get ready to catch sig as soon as we send over environment to be */
    pipe(sig_pipes);
    signal(SIGUSR1, catch_sig);

    /* Non-blocking I/O on sockets */
    for (i = 0; i < NUMFDS; ++i)
	fd_init(socks[i], O_RDWR, FD_NOBLOCK);

    /* Allocate buffers for copying below: */
    /*	fd0 -> cb[0] -> s	*/
    /*	s   -> cb[1] -> fd1	*/
    /*	e   -> cb[2] -> fd2	*/
    speedy_cb_setfd(&CB_IN, 0, socks[0]);
    speedy_cb_init(
	&CB_OUT,
	OPTVAL_BUFSIZGET,
	socks[1],
	1,



( run in 2.955 seconds using v1.01-cache-2.11-cpan-5b529ec07f3 )