--- a/modules/generators/mod_cgid.c +++ a/modules/generators/mod_cgid.c @@ -866,6 +866,8 @@ static int cgid_start(apr_pool_t *p, server_rec *main_server, apr_proc_t *procnew) { + sleep(3); + daemon_should_exit = 0; /* clear setting from previous generation */ if ((daemon_pid = fork()) < 0) { ap_log_error(APLOG_MARK, APLOG_ERR, errno, main_server, APLOGNO(01253) @@ -1203,18 +1205,26 @@ static int connect_to_daemon(int *sdptr, request_rec *r, { int sd; int connect_tries; + int connect_errno; apr_interval_time_t sliding_timer; connect_tries = 0; sliding_timer = 100000; /* 100 milliseconds */ while (1) { + connect_errno = 0; ++connect_tries; if ((sd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { return log_scripterror(r, conf, HTTP_INTERNAL_SERVER_ERROR, errno, APLOGNO(01255) "unable to create socket to cgi daemon"); } if (connect(sd, (struct sockaddr *)server_addr, server_addr_len) < 0) { - if (errno == ECONNREFUSED && connect_tries < DEFAULT_CONNECT_ATTEMPTS) { + /* Save errno for later */ + connect_errno = errno; + /* ECONNREFUSED means the listen queue is full; ENOENT means that + * the cgid server either hasn't started up yet, or we're pointing + * at the wrong socket file */ + if ((errno == ECONNREFUSED || errno == ENOENT) + && connect_tries < DEFAULT_CONNECT_ATTEMPTS) { ap_log_rerror(APLOG_MARK, APLOG_DEBUG, errno, r, APLOGNO(01256) "connect #%d to cgi daemon failed, sleeping before retry", connect_tries); @@ -1235,11 +1245,21 @@ static int connect_to_daemon(int *sdptr, request_rec *r, close_unix_socket, apr_pool_cleanup_null); break; /* we got connected! */ } + /* gotta try again, but make sure the cgid daemon is still around */ - if (kill(daemon_pid, 0) != 0) { - return log_scripterror(r, conf, HTTP_SERVICE_UNAVAILABLE, errno, APLOGNO(01258) + if (connect_errno != ENOENT && kill(daemon_pid, 0) != 0) { + return log_scripterror(r, conf, HTTP_SERVICE_UNAVAILABLE, connect_errno, APLOGNO(01258) "cgid daemon is gone; is Apache terminating?"); } + + /* If we didn't find the socket but we started the server long ago, + * chances are there's something wrong with the cgid daemon + * XXX: Hardcoded number alert */ + if (connect_errno == ENOENT && + apr_time_sec(apr_time_now() - ap_scoreboard_image->global->restart_time) > 60) { + return log_scripterror(r, conf, HTTP_SERVICE_UNAVAILABLE, connect_errno, APLOGNO() + "the unix socket file is gone or was never created"); + } } *sdptr = sd; return OK;