|
|
|
@ -348,23 +348,6 @@ typedef struct {
|
|
|
|
|
/* ok, we need a prototype */
|
|
|
|
|
static handler_t fcgi_handle_fdevent(server *srv, void *ctx, int revents);
|
|
|
|
|
|
|
|
|
|
#ifdef HAVE_FORK
|
|
|
|
|
static void reset_signals(void) {
|
|
|
|
|
#ifdef SIGTTOU
|
|
|
|
|
signal(SIGTTOU, SIG_DFL);
|
|
|
|
|
#endif
|
|
|
|
|
#ifdef SIGTTIN
|
|
|
|
|
signal(SIGTTIN, SIG_DFL);
|
|
|
|
|
#endif
|
|
|
|
|
#ifdef SIGTSTP
|
|
|
|
|
signal(SIGTSTP, SIG_DFL);
|
|
|
|
|
#endif
|
|
|
|
|
signal(SIGHUP, SIG_DFL);
|
|
|
|
|
signal(SIGPIPE, SIG_DFL);
|
|
|
|
|
signal(SIGUSR1, SIG_DFL);
|
|
|
|
|
}
|
|
|
|
|
#endif /* HAVE_FORK */
|
|
|
|
|
|
|
|
|
|
static void fastcgi_status_copy_procname(buffer *b, fcgi_extension_host *host, fcgi_proc *proc) {
|
|
|
|
|
buffer_copy_string_len(b, CONST_STR_LEN("fastcgi.backend."));
|
|
|
|
|
buffer_append_string_buffer(b, host->id);
|
|
|
|
@ -788,7 +771,7 @@ FREE_FUNC(mod_fastcgi_free) {
|
|
|
|
|
host = ex->hosts[n];
|
|
|
|
|
|
|
|
|
|
for (proc = host->first; proc; proc = proc->next) {
|
|
|
|
|
if (proc->pid != 0) {
|
|
|
|
|
if (proc->pid > 0) {
|
|
|
|
|
kill(proc->pid, host->kill_signal);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -799,7 +782,7 @@ FREE_FUNC(mod_fastcgi_free) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (proc = host->unused_procs; proc; proc = proc->next) {
|
|
|
|
|
if (proc->pid != 0) {
|
|
|
|
|
if (proc->pid > 0) {
|
|
|
|
|
kill(proc->pid, host->kill_signal);
|
|
|
|
|
}
|
|
|
|
|
if (proc->is_local &&
|
|
|
|
@ -826,7 +809,6 @@ FREE_FUNC(mod_fastcgi_free) {
|
|
|
|
|
return HANDLER_GO_ON;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef HAVE_FORK
|
|
|
|
|
static int env_add(char_array *env, const char *key, size_t key_len, const char *val, size_t val_len) {
|
|
|
|
|
char *dst;
|
|
|
|
|
size_t i;
|
|
|
|
@ -841,8 +823,7 @@ static int env_add(char_array *env, const char *key, size_t key_len, const char
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < env->used; i++) {
|
|
|
|
|
if (0 == strncmp(dst, env->ptr[i], key_len + 1)) {
|
|
|
|
|
/* don't care about free as we are in a forked child which is going to exec(...) */
|
|
|
|
|
/* free(env->ptr[i]); */
|
|
|
|
|
free(env->ptr[i]);
|
|
|
|
|
env->ptr[i] = dst;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
@ -916,21 +897,6 @@ static int parse_binpath(char_array *env, buffer *b) {
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
#endif /* HAVE_FORK */
|
|
|
|
|
|
|
|
|
|
#if !defined(HAVE_FORK)
|
|
|
|
|
static int fcgi_spawn_connection(server *srv,
|
|
|
|
|
plugin_data *p,
|
|
|
|
|
fcgi_extension_host *host,
|
|
|
|
|
fcgi_proc *proc) {
|
|
|
|
|
UNUSED(srv);
|
|
|
|
|
UNUSED(p);
|
|
|
|
|
UNUSED(host);
|
|
|
|
|
UNUSED(proc);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#else /* -> defined(HAVE_FORK) */
|
|
|
|
|
|
|
|
|
|
static int fcgi_spawn_connection(server *srv,
|
|
|
|
|
plugin_data *p,
|
|
|
|
@ -1071,8 +1037,12 @@ static int fcgi_spawn_connection(server *srv,
|
|
|
|
|
|
|
|
|
|
if (-1 == status) {
|
|
|
|
|
/* server is not up, spawn it */
|
|
|
|
|
pid_t child;
|
|
|
|
|
char_array env;
|
|
|
|
|
char_array arg;
|
|
|
|
|
buffer *bin_path = NULL;
|
|
|
|
|
size_t i;
|
|
|
|
|
int val;
|
|
|
|
|
int dfd = -1;
|
|
|
|
|
|
|
|
|
|
/* reopen socket */
|
|
|
|
|
if (-1 == (fcgi_fd = fdevent_socket_cloexec(fcgi_addr->sa_family, SOCK_STREAM, 0))) {
|
|
|
|
@ -1106,13 +1076,7 @@ static int fcgi_spawn_connection(server *srv,
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch ((child = fork())) {
|
|
|
|
|
case 0: {
|
|
|
|
|
size_t i = 0;
|
|
|
|
|
char *c;
|
|
|
|
|
char_array env;
|
|
|
|
|
char_array arg;
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
/* create environment */
|
|
|
|
|
env.ptr = NULL;
|
|
|
|
|
env.size = 0;
|
|
|
|
@ -1122,19 +1086,6 @@ static int fcgi_spawn_connection(server *srv,
|
|
|
|
|
arg.size = 0;
|
|
|
|
|
arg.used = 0;
|
|
|
|
|
|
|
|
|
|
if(fcgi_fd != FCGI_LISTENSOCK_FILENO) {
|
|
|
|
|
dup2(fcgi_fd, FCGI_LISTENSOCK_FILENO);
|
|
|
|
|
close(fcgi_fd);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
fdevent_clrfd_cloexec(fcgi_fd);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* we don't need the client socket */
|
|
|
|
|
for (i = 3; i < 256; i++) {
|
|
|
|
|
close(i);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* build clean environment */
|
|
|
|
|
if (host->bin_env_copy->used) {
|
|
|
|
|
for (i = 0; i < host->bin_env_copy->used; i++) {
|
|
|
|
@ -1175,44 +1126,35 @@ static int fcgi_spawn_connection(server *srv,
|
|
|
|
|
|
|
|
|
|
env.ptr[env.used] = NULL;
|
|
|
|
|
|
|
|
|
|
parse_binpath(&arg, host->bin_path);
|
|
|
|
|
|
|
|
|
|
/* chdir into the base of the bin-path,
|
|
|
|
|
* search for the last / */
|
|
|
|
|
if (NULL != (c = strrchr(arg.ptr[0], '/'))) {
|
|
|
|
|
*c = '\0';
|
|
|
|
|
|
|
|
|
|
/* change to the physical directory */
|
|
|
|
|
if (-1 == chdir(arg.ptr[0])) {
|
|
|
|
|
*c = '/';
|
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "sss", "chdir failed:", strerror(errno), arg.ptr[0]);
|
|
|
|
|
}
|
|
|
|
|
*c = '/';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
reset_signals();
|
|
|
|
|
bin_path = buffer_init_buffer(host->bin_path);
|
|
|
|
|
parse_binpath(&arg, bin_path);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* exec the cgi */
|
|
|
|
|
execve(arg.ptr[0], arg.ptr, env.ptr);
|
|
|
|
|
dfd = fdevent_open_dirname(arg.ptr[0]);
|
|
|
|
|
if (-1 == dfd) {
|
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "sss", "open dirname failed:", strerror(errno), arg.ptr[0]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* log_error_write(srv, __FILE__, __LINE__, "sbs",
|
|
|
|
|
"execve failed for:", host->bin_path, strerror(errno)); */
|
|
|
|
|
/*(FCGI_LISTENSOCK_FILENO == STDIN_FILENO == 0)*/
|
|
|
|
|
proc->pid = (dfd >= 0) ? fdevent_fork_execve(arg.ptr[0], arg.ptr, env.ptr, fcgi_fd, -1, -1, dfd) : -1;
|
|
|
|
|
|
|
|
|
|
_exit(errno);
|
|
|
|
|
for (i = 0; i < env.used; ++i) free(env.ptr[i]);
|
|
|
|
|
free(env.ptr);
|
|
|
|
|
/*(arg[] contains string references into bin_path)*/
|
|
|
|
|
/*for (i = 0; i < arg.used; ++i) free(arg.ptr[i]);*/
|
|
|
|
|
free(arg.ptr);
|
|
|
|
|
buffer_free(bin_path);
|
|
|
|
|
if (-1 != dfd) close(dfd);
|
|
|
|
|
close(fcgi_fd);
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
if (-1 == proc->pid) {
|
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "sb",
|
|
|
|
|
"fastcgi-backend failed to start:", host->bin_path);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
case -1:
|
|
|
|
|
/* error */
|
|
|
|
|
close(fcgi_fd);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
/* father */
|
|
|
|
|
close(fcgi_fd);
|
|
|
|
|
|
|
|
|
|
/* register process */
|
|
|
|
|
proc->is_local = 1;
|
|
|
|
|
proc->pid = child;
|
|
|
|
|
|
|
|
|
|
/* wait */
|
|
|
|
|
select(0, NULL, NULL, NULL, &tv);
|
|
|
|
@ -1226,9 +1168,6 @@ static int fcgi_spawn_connection(server *srv,
|
|
|
|
|
"If this is PHP, try removing the bytecode caches for now and try again.");
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
proc->is_local = 0;
|
|
|
|
|
proc->pid = 0;
|
|
|
|
@ -1244,8 +1183,6 @@ static int fcgi_spawn_connection(server *srv,
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif /* HAVE_FORK */
|
|
|
|
|
|
|
|
|
|
static fcgi_extension_host * unixsocket_is_dup(plugin_data *p, size_t used, buffer *unixsocket) {
|
|
|
|
|
size_t i, j, n;
|
|
|
|
|
for (i = 0; i < used; ++i) {
|
|
|
|
|