Bug #1825 » r2632.mod_fastcgi.patch
mod_fastcgi.c 2009-10-14 16:25:27.000000000 -0500 | ||
---|---|---|
#include <sys/types.h>
|
||
#include <unistd.h>
|
||
#include <errno.h>
|
||
#include <fcntl.h>
|
||
#include <string.h>
|
||
#include <stdlib.h>
|
||
#include <ctype.h>
|
||
#include <assert.h>
|
||
#include <signal.h>
|
||
#include "buffer.h"
|
||
#include "server.h"
|
||
#include "keyvalue.h"
|
||
... | ... | |
#include "stat_cache.h"
|
||
#include "status_counter.h"
|
||
#include <sys/types.h>
|
||
#include <unistd.h>
|
||
#include <errno.h>
|
||
#include <fcntl.h>
|
||
#include <string.h>
|
||
#include <stdlib.h>
|
||
#include <ctype.h>
|
||
#include <assert.h>
|
||
#include <signal.h>
|
||
#ifdef HAVE_FASTCGI_FASTCGI_H
|
||
#include <fastcgi/fastcgi.h>
|
||
# include <fastcgi/fastcgi.h>
|
||
#else
|
||
#ifdef HAVE_FASTCGI_H
|
||
#include <fastcgi.h>
|
||
#else
|
||
#include "fastcgi.h"
|
||
#endif
|
||
# ifdef HAVE_FASTCGI_H
|
||
# include <fastcgi.h>
|
||
# else
|
||
# include "fastcgi.h"
|
||
# endif
|
||
#endif /* HAVE_FASTCGI_FASTCGI_H */
|
||
#include <stdio.h>
|
||
#ifdef HAVE_SYS_FILIO_H
|
||
... | ... | |
*
|
||
*/
|
||
unsigned short min_procs;
|
||
unsigned short max_procs;
|
||
size_t num_procs; /* how many procs are started */
|
||
size_t active_procs; /* how many of them are really running */
|
||
unsigned short max_load_per_proc;
|
||
/*
|
||
* kick the process from the list if it was not
|
||
* used for idle_timeout until min_procs is
|
||
* reached. this helps to get the processlist
|
||
* small again we had a small peak load.
|
||
*
|
||
*/
|
||
unsigned short idle_timeout;
|
||
/*
|
||
* time after a disabled remote connection is tried to be re-enabled
|
||
*
|
||
... | ... | |
/* ok, we need a prototype */
|
||
static handler_t fcgi_handle_fdevent(void *s, void *ctx, int revents);
|
||
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);
|
||
}
|
||
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);
|
||
... | ... | |
close(fcgi_fd);
|
||
}
|
||
openDevNull(STDERR_FILENO);
|
||
/* we don't need the client socket */
|
||
for (i = 3; i < 256; i++) {
|
||
close(i);
|
||
... | ... | |
*c = '/';
|
||
}
|
||
reset_signals();
|
||
/* exec the cgi */
|
||
execve(arg.ptr[0], arg.ptr, env.ptr);
|
||
... | ... | |
{ "check-local", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 5 */
|
||
{ "port", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 6 */
|
||
{ "min-procs-not-working", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 7 this is broken for now */
|
||
{ "max-procs", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 8 */
|
||
{ "max-load-per-proc", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 9 */
|
||
{ "idle-timeout", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 10 */
|
||
{ "disable-time", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 11 */
|
||
{ "bin-environment", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 12 */
|
||
{ "bin-copy-environment", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 13 */
|
||
{ "broken-scriptfilename", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 14 */
|
||
{ "allow-x-send-file", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 15 */
|
||
{ "strip-request-uri", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 16 */
|
||
{ "kill-signal", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 17 */
|
||
{ "fix-root-scriptname", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 18 */
|
||
{ "max-procs", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 7 */
|
||
{ "disable-time", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 8 */
|
||
{ "bin-environment", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 9 */
|
||
{ "bin-copy-environment", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 10 */
|
||
{ "broken-scriptfilename", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 11 */
|
||
{ "allow-x-send-file", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 12 */
|
||
{ "strip-request-uri", NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION }, /* 13 */
|
||
{ "kill-signal", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION }, /* 14 */
|
||
{ "fix-root-scriptname", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 15 */
|
||
{ NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
|
||
};
|
||
... | ... | |
buffer_copy_string_buffer(host->id, da_host->key);
|
||
host->check_local = 1;
|
||
host->min_procs = 4;
|
||
host->max_procs = 4;
|
||
host->max_load_per_proc = 1;
|
||
host->idle_timeout = 60;
|
||
host->mode = FCGI_RESPONDER;
|
||
host->disable_time = 60;
|
||
host->disable_time = 1;
|
||
host->break_scriptfilename_for_php = 0;
|
||
host->allow_xsendfile = 0; /* handle X-LIGHTTPD-send-file */
|
||
host->kill_signal = SIGTERM;
|
||
... | ... | |
fcv[5].destination = &(host->check_local);
|
||
fcv[6].destination = &(host->port);
|
||
fcv[7].destination = &(host->min_procs);
|
||
fcv[8].destination = &(host->max_procs);
|
||
fcv[9].destination = &(host->max_load_per_proc);
|
||
fcv[10].destination = &(host->idle_timeout);
|
||
fcv[11].destination = &(host->disable_time);
|
||
fcv[12].destination = host->bin_env;
|
||
fcv[13].destination = host->bin_env_copy;
|
||
fcv[14].destination = &(host->break_scriptfilename_for_php);
|
||
fcv[15].destination = &(host->allow_xsendfile);
|
||
fcv[16].destination = host->strip_request_uri;
|
||
fcv[17].destination = &(host->kill_signal);
|
||
fcv[18].destination = &(host->fix_root_path_name);
|
||
fcv[7].destination = &(host->max_procs);
|
||
fcv[8].destination = &(host->disable_time);
|
||
fcv[9].destination = host->bin_env;
|
||
fcv[10].destination = host->bin_env_copy;
|
||
fcv[11].destination = &(host->break_scriptfilename_for_php);
|
||
fcv[12].destination = &(host->allow_xsendfile);
|
||
fcv[13].destination = host->strip_request_uri;
|
||
fcv[14].destination = &(host->kill_signal);
|
||
fcv[15].destination = &(host->fix_root_path_name);
|
||
if (0 != config_insert_values_internal(srv, da_host->value, fcv)) {
|
||
return HANDLER_ERROR;
|
||
... | ... | |
/* a local socket + self spawning */
|
||
size_t pno;
|
||
/* HACK: just to make sure the adaptive spawing is disabled */
|
||
host->min_procs = host->max_procs;
|
||
if (host->min_procs > host->max_procs) host->max_procs = host->min_procs;
|
||
if (host->max_load_per_proc < 1) host->max_load_per_proc = 0;
|
||
if (s->debug) {
|
||
log_error_write(srv, __FILE__, __LINE__, "ssbsdsbsdsd",
|
||
log_error_write(srv, __FILE__, __LINE__, "ssbsdsbsd",
|
||
"--- fastcgi spawning local",
|
||
"\n\tproc:", host->bin_path,
|
||
"\n\tport:", host->port,
|
||
"\n\tsocket", host->unixsocket,
|
||
"\n\tmin-procs:", host->min_procs,
|
||
"\n\tmax-procs:", host->max_procs);
|
||
}
|
||
for (pno = 0; pno < host->min_procs; pno++) {
|
||
for (pno = 0; pno < host->max_procs; pno++) {
|
||
fcgi_proc *proc;
|
||
proc = fastcgi_process_init();
|
||
... | ... | |
"--- fastcgi spawning",
|
||
"\n\tport:", host->port,
|
||
"\n\tsocket", host->unixsocket,
|
||
"\n\tcurrent:", pno, "/", host->min_procs);
|
||
"\n\tcurrent:", pno, "/", host->max_procs);
|
||
}
|
||
if (fcgi_spawn_connection(srv, p, host, proc)) {
|
||
... | ... | |
host->first = proc;
|
||
host->min_procs = 1;
|
||
host->max_procs = 1;
|
||
}
|
||
... | ... | |
log_error_write(srv, __FILE__, __LINE__, "ssbsdsd",
|
||
"--- fastcgi spawning",
|
||
"\n\tsocket", proc->connection_name,
|
||
"\n\tcurrent:", 1, "/", host->min_procs);
|
||
"\n\tcurrent:", 1, "/", host->max_procs);
|
||
}
|
||
if (fcgi_spawn_connection(srv, p, host, proc)) {
|
||
... | ... | |
* - tcp socket (do not check host->host->uses, as it may be not set which means INADDR_LOOPBACK)
|
||
* - unix socket
|
||
*/
|
||
if (!host ||
|
||
(!host->port && !host->unixsocket->used)) {
|
||
log_error_write(srv, __FILE__, __LINE__, "sxddd",
|
||
"write-req: error",
|
||
host,
|
||
host->host->used,
|
||
host->port,
|
||
host->unixsocket->used);
|
||
hctx->proc->disabled_until = srv->cur_ts + 10;
|
||
hctx->proc->state = PROC_STATE_DIED;
|
||
if (!host) {
|
||
log_error_write(srv, __FILE__, __LINE__, "s", "fatal error: host = NULL");
|
||
return HANDLER_ERROR;
|
||
}
|
||
if ((!host->port && !host->unixsocket->used)) {
|
||
log_error_write(srv, __FILE__, __LINE__, "s", "fatal error: neither host->port nor host->unixsocket is set");
|
||
return HANDLER_ERROR;
|
||
}
|
||
... | ... | |
log_error_write(srv, __FILE__, __LINE__, "ss",
|
||
"getsockopt failed:", strerror(errno));
|
||
hctx->proc->disabled_until = srv->cur_ts + 10;
|
||
hctx->proc->state = PROC_STATE_DIED;
|
||
if (hctx->host->disable_time) {
|
||
hctx->proc->disabled_until = srv->cur_ts + hctx->host->disable_time;
|
||
hctx->proc->state = PROC_STATE_DIED;
|
||
}
|
||
return HANDLER_ERROR;
|
||
}
|
||
... | ... | |
"socket:", hctx->proc->connection_name);
|
||
}
|
||
hctx->proc->disabled_until = srv->cur_ts + 5;
|
||
if (hctx->proc->is_local) {
|
||
hctx->proc->state = PROC_STATE_DIED_WAIT_FOR_PID;
|
||
} else {
|
||
if (hctx->host->disable_time) {
|
||
hctx->proc->disabled_until = srv->cur_ts + hctx->host->disable_time;
|
||
hctx->proc->state = PROC_STATE_DIED;
|
||
}
|
||
hctx->proc->state = PROC_STATE_DIED;
|
||
fastcgi_status_copy_procname(p->statuskey, hctx->host, hctx->proc);
|
||
buffer_append_string_len(p->statuskey, CONST_STR_LEN(".died"));
|
||
... | ... | |
/* cool down the backend, it is overloaded
|
||
* -> EAGAIN */
|
||
log_error_write(srv, __FILE__, __LINE__, "ssdsd",
|
||
"backend is overloaded; we'll disable it for 2 seconds and send the request to another backend instead:",
|
||
"reconnects:", hctx->reconnects,
|
||
"load:", host->load);
|
||
if (hctx->host->disable_time) {
|
||
log_error_write(srv, __FILE__, __LINE__, "sdssdsd",
|
||
"backend is overloaded; we'll disable it for", hctx->host->disable_time, "seconds and send the request to another backend instead:",
|
||
"reconnects:", hctx->reconnects,
|
||
"load:", host->load);
|
||
hctx->proc->disabled_until = srv->cur_ts + 2;
|
||
hctx->proc->state = PROC_STATE_OVERLOADED;
|
||
hctx->proc->disabled_until = srv->cur_ts + hctx->host->disable_time;
|
||
hctx->proc->state = PROC_STATE_OVERLOADED;
|
||
}
|
||
fastcgi_status_copy_procname(p->statuskey, hctx->host, hctx->proc);
|
||
buffer_append_string_len(p->statuskey, CONST_STR_LEN(".overloaded"));
|
||
... | ... | |
* - ECONNREFUSED for tcp-ip sockets
|
||
* - ENOENT for unix-domain-sockets
|
||
*
|
||
* for check if the host is back in 5 seconds
|
||
* for check if the host is back in hctx->host->disable_time seconds
|
||
* */
|
||
hctx->proc->disabled_until = srv->cur_ts + 5;
|
||
if (hctx->proc->is_local) {
|
||
hctx->proc->state = PROC_STATE_DIED_WAIT_FOR_PID;
|
||
} else {
|
||
hctx->proc->state = PROC_STATE_DIED;
|
||
}
|
||
if (hctx->host->disable_time) {
|
||
hctx->proc->disabled_until = srv->cur_ts + hctx->host->disable_time;
|
||
if (hctx->proc->is_local) {
|
||
hctx->proc->state = PROC_STATE_DIED_WAIT_FOR_PID;
|
||
} else {
|
||
hctx->proc->state = PROC_STATE_DIED;
|
||
}
|
||
log_error_write(srv, __FILE__, __LINE__, "ssdsd",
|
||
"backend died; we'll disable it for 5 seconds and send the request to another backend instead:",
|
||
"reconnects:", hctx->reconnects,
|
||
"load:", host->load);
|
||
log_error_write(srv, __FILE__, __LINE__, "sdssdsd",
|
||
"backend died; we'll disable it for", hctx->host->disable_time, "seconds and send the request to another backend instead:",
|
||
"reconnects:", hctx->reconnects,
|
||
"load:", host->load);
|
||
}
|
||
fastcgi_status_copy_procname(p->statuskey, hctx->host, hctx->proc);
|
||
buffer_append_string_len(p->statuskey, CONST_STR_LEN(".died"));
|
||
... | ... | |
"reconnect attempts:", hctx->reconnects);
|
||
return HANDLER_ERROR;
|
||
case EAGAIN:
|
||
case EINTR:
|
||
fdevent_event_add(srv->ev, &(hctx->fde_ndx), hctx->fd, FDEVENT_OUT);
|
||
return HANDLER_WAIT_FOR_EVENT;
|
||
default:
|
||
log_error_write(srv, __FILE__, __LINE__, "ssd",
|
||
"write failed:", strerror(errno), errno);
|
||
... | ... | |
log_error_write(srv, __FILE__, __LINE__, "ssbsdsd",
|
||
"--- fastcgi spawning",
|
||
"\n\tsocket", proc->connection_name,
|
||
"\n\tcurrent:", 1, "/", host->min_procs);
|
||
"\n\tcurrent:", 1, "/", host->max_procs);
|
||
}
|
||
if (fcgi_spawn_connection(srv, p, host, proc)) {
|
||
... | ... | |
hctx->reconnects < 5) {
|
||
fcgi_reconnect(srv, hctx);
|
||
log_error_write(srv, __FILE__, __LINE__, "ssbsbs",
|
||
log_error_write(srv, __FILE__, __LINE__, "ssbsBSBs",
|
||
"response not received, request not sent",
|
||
"on socket:", proc->connection_name,
|
||
"for", con->uri.path, ", reconnecting");
|
||
"for", con->uri.path, "?", con->uri.query, ", reconnecting");
|
||
return HANDLER_WAIT_FOR_FD;
|
||
}
|
||
log_error_write(srv, __FILE__, __LINE__, "sosbsbs",
|
||
log_error_write(srv, __FILE__, __LINE__, "sosbsBSBs",
|
||
"response not received, request sent:", hctx->wb->bytes_out,
|
||
"on socket:", proc->connection_name,
|
||
"for", con->uri.path, ", closing connection");
|
||
"for", con->uri.path, "?", con->uri.query, ", closing connection");
|
||
fcgi_connection_close(srv, hctx);
|
||
... | ... | |
/* response might have been already started, kill the connection */
|
||
fcgi_connection_close(srv, hctx);
|
||
log_error_write(srv, __FILE__, __LINE__, "ssbsbs",
|
||
log_error_write(srv, __FILE__, __LINE__, "ssbsBSBs",
|
||
"response already sent out, but backend returned error",
|
||
"on socket:", proc->connection_name,
|
||
"for", con->uri.path, ", terminating connection");
|
||
"for", con->uri.path, "?", con->uri.query, ", terminating connection");
|
||
connection_set_state(srv, con, CON_STATE_ERROR);
|
||
}
|
||
... | ... | |
* even if the FCGI_FIN packet is not received yet
|
||
*/
|
||
} else {
|
||
log_error_write(srv, __FILE__, __LINE__, "sbsbsd",
|
||
log_error_write(srv, __FILE__, __LINE__, "sBSbsbsd",
|
||
"error: unexpected close of fastcgi connection for",
|
||
con->uri.path,
|
||
con->uri.path, "?", con->uri.query,
|
||
"(no fastcgi process on socket:", proc->connection_name, "?)",
|
||
hctx->state);
|
||
... | ... | |
/* check if extension matches */
|
||
for (k = 0; k < p->conf.exts->used; k++) {
|
||
size_t ct_len; /* length of the config entry */
|
||
fcgi_extension *ext = p->conf.exts->exts[k];
|
||
extension = p->conf.exts->exts[k];
|
||
if (ext->key->used == 0) continue;
|
||
if (extension->key->used == 0) continue;
|
||
ct_len = extension->key->used - 1;
|
||
ct_len = ext->key->used - 1;
|
||
/* check _url_ in the form "/fcgi_pattern" */
|
||
if (extension->key->ptr[0] == '/') {
|
||
if (ext->key->ptr[0] == '/') {
|
||
if ((ct_len <= con->uri.path->used -1) &&
|
||
(strncmp(con->uri.path->ptr, extension->key->ptr, ct_len) == 0))
|
||
(strncmp(con->uri.path->ptr, ext->key->ptr, ct_len) == 0)) {
|
||
extension = ext;
|
||
break;
|
||
} else if ((ct_len <= s_len) && (0 == strncmp(fn->ptr + s_len - ct_len, extension->key->ptr, ct_len))) {
|
||
}
|
||
} else if ((ct_len <= s_len) && (0 == strncmp(fn->ptr + s_len - ct_len, ext->key->ptr, ct_len))) {
|
||
/* check extension in the form ".fcg" */
|
||
extension = ext;
|
||
break;
|
||
}
|
||
}
|
||
/* extension doesn't match */
|
||
if (k == p->conf.exts->used) {
|
||
if (NULL == extension) {
|
||
return HANDLER_GO_ON;
|
||
}
|
||
}
|
||
... | ... | |
if (!extension->note_is_sent) {
|
||
extension->note_is_sent = 1;
|
||
log_error_write(srv, __FILE__, __LINE__, "sbsbs",
|
||
"all handlers for ", con->uri.path,
|
||
log_error_write(srv, __FILE__, __LINE__, "sBSbsbs",
|
||
"all handlers for", con->uri.path, "?", con->uri.query,
|
||
"on", extension->key,
|
||
"are down.");
|
||
}
|
||
... | ... | |
for (n = 0; n < ex->used; n++) {
|
||
fcgi_proc *proc;
|
||
unsigned long sum_load = 0;
|
||
fcgi_extension_host *host;
|
||
host = ex->hosts[n];
|
||
fcgi_restart_dead_procs(srv, p, host);
|
||
for (proc = host->first; proc; proc = proc->next) {
|
||
sum_load += proc->load;
|
||
}
|
||
if (host->num_procs &&
|
||
host->num_procs < host->max_procs &&
|
||
(sum_load / host->num_procs) > host->max_load_per_proc) {
|
||
/* overload, spawn new child */
|
||
if (p->conf.debug) {
|
||
log_error_write(srv, __FILE__, __LINE__, "s",
|
||
"overload detected, spawning a new child");
|
||
}
|
||
for (proc = host->unused_procs; proc && proc->pid != 0; proc = proc->next);
|
||
if (proc) {
|
||
if (proc == host->unused_procs) host->unused_procs = proc->next;
|
||
if (proc->next) proc->next->prev = NULL;
|
||
host->max_id++;
|
||
} else {
|
||
proc = fastcgi_process_init();
|
||
proc->id = host->max_id++;
|
||
}
|
||
host->num_procs++;
|
||
if (buffer_is_empty(host->unixsocket)) {
|
||
proc->port = host->port + proc->id;
|
||
} else {
|
||
buffer_copy_string_buffer(proc->unixsocket, host->unixsocket);
|
||
buffer_append_string_len(proc->unixsocket, CONST_STR_LEN("-"));
|
||
buffer_append_long(proc->unixsocket, proc->id);
|
||
}
|
||
if (fcgi_spawn_connection(srv, p, host, proc)) {
|
||
log_error_write(srv, __FILE__, __LINE__, "s",
|
||
"ERROR: spawning fcgi failed.");
|
||
return HANDLER_ERROR;
|
||
}
|
||
proc->prev = NULL;
|
||
proc->next = host->first;
|
||
if (host->first) {
|
||
host->first->prev = proc;
|
||
}
|
||
host->first = proc;
|
||
}
|
||
for (proc = host->first; proc; proc = proc->next) {
|
||
if (proc->load != 0) break;
|
||
if (host->num_procs <= host->min_procs) break;
|
||
if (proc->pid == 0) continue;
|
||
if (srv->cur_ts - proc->last_used > host->idle_timeout) {
|
||
/* a proc is idling for a long time now,
|
||
* terminate it */
|
||
if (p->conf.debug) {
|
||
log_error_write(srv, __FILE__, __LINE__, "ssbsd",
|
||
"idle-timeout reached; terminating child:",
|
||
"socket:", proc->connection_name,
|
||
"pid", proc->pid);
|
||
}
|
||
if (proc->next) proc->next->prev = proc->prev;
|
||
if (proc->prev) proc->prev->next = proc->next;
|
||
if (proc->prev == NULL) host->first = proc->next;
|
||
proc->prev = NULL;
|
||
proc->next = host->unused_procs;
|
||
if (host->unused_procs) host->unused_procs->prev = proc;
|
||
host->unused_procs = proc;
|
||
kill(proc->pid, SIGTERM);
|
||
proc->state = PROC_STATE_KILLED;
|
||
log_error_write(srv, __FILE__, __LINE__, "ssbsd",
|
||
"killed:",
|
||
"socket:", proc->connection_name,
|
||
"pid", proc->pid);
|
||
host->num_procs--;
|
||
/* proc is now in unused, let the next second handle the next process */
|
||
break;
|
||
}
|
||
}
|
||
for (proc = host->unused_procs; proc; proc = proc->next) {
|
||
int status;
|
||