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 )