if (serviceptr->tcp_port > 0)
{
- syslog(LOG_INFO, "Closing listener on port %d\n",
- serviceptr->tcp_port);
+ syslog(LOG_INFO, "Closing %d listener on port %d\n",
+ serviceptr->msock,
+ serviceptr->tcp_port);
serviceptr->tcp_port = 0;
}
if (serviceptr->sockpath != NULL)
- syslog(LOG_INFO, "Closing listener on '%s'\n",
- serviceptr->sockpath);
-
- close(serviceptr->msock);
+ syslog(LOG_INFO, "Closing %d listener on '%s'\n",
+ serviceptr->msock,
+ serviceptr->sockpath);
+ if (serviceptr->msock != -1)
+ close(serviceptr->msock);
/* If it's a Unix domain socket, remove the file. */
if (serviceptr->sockpath != NULL) {
unlink(serviceptr->sockpath);
CtdlDestroyServiceHook();
CtdlDestroyRoomHooks();
CtdlDestroySearchHooks();
+ CtdlDestroyDebugTable();
#ifdef HAVE_BACKTRACE
/// eCrash_Uninit();
#endif
"factor.\n \n"
" You can obtain more information about this by enabling core dumps.\n \n"
" For more information, please see:\n \n"
- " http://citadel.org/doku.php/faq:mastering_your_os:gdb#how.do.i.make.my.system.produce.core-files"
+ " http://citadel.org/doku.php?id=faq:mastering_your_os:gdb#how.do.i.make.my.system.produce.core-files"
"\n \n"
" If you have already done this, the core dump is likely to be found at %score.%d\n"
int retval = 0;
struct timeval tv;
int force_purge = 0;
+ struct ServiceFunctionHook *serviceptr;
+ int ssock; /* Descriptor for client socket */
+ CitContext *con = NULL; /* Temporary context pointer */
+ int i;
++num_workers;
FD_ZERO(&readfds);
highest = 0;
+ /* First, add the various master sockets to the fdset. */
+ for (serviceptr = ServiceHookTable; serviceptr != NULL; serviceptr = serviceptr->next ) {
+ FD_SET(serviceptr->msock, &readfds);
+ if (serviceptr->msock > highest) {
+ highest = serviceptr->msock;
+ }
+ }
+
+ /* Next, add all of the client sockets. */
begin_critical_section(S_SESSION_TABLE);
for (ptr = ContextList; ptr != NULL; ptr = ptr->next) {
if ((ptr->state == CON_SYS) && (ptr->client_socket == 0))
}
}
+ /* Next, check to see if it's a new client connecting * on a master socket. */
+
+ else if ((retval > 0) && (!server_shutting_down)) for (serviceptr = ServiceHookTable; serviceptr != NULL; serviceptr = serviceptr->next) {
+
+ if (FD_ISSET(serviceptr->msock, &readfds)) {
+ ssock = accept(serviceptr->msock, NULL, 0);
+ if (ssock >= 0) {
+ syslog(LOG_DEBUG, "New client socket %d", ssock);
+
+ /* The master socket is non-blocking but the client
+ * sockets need to be blocking, otherwise certain
+ * operations barf on FreeBSD. Not a fatal error.
+ */
+ if (fcntl(ssock, F_SETFL, 0) < 0) {
+ syslog(LOG_EMERG,
+ "citserver: Can't set socket to blocking: %s\n",
+ strerror(errno));
+ }
+
+ /* New context will be created already
+ * set up in the CON_EXECUTING state.
+ */
+ con = CreateNewContext();
+
+ /* Assign our new socket number to it. */
+ con->tcp_port = serviceptr->tcp_port;
+ con->client_socket = ssock;
+ con->h_command_function = serviceptr->h_command_function;
+ con->h_async_function = serviceptr->h_async_function;
+ con->h_greeting_function = serviceptr->h_greeting_function;
+ con->ServiceName = serviceptr->ServiceName;
+
+ /* Determine whether it's a local socket */
+ if (serviceptr->sockpath != NULL) {
+ con->is_local_socket = 1;
+ }
+
+ /* Set the SO_REUSEADDR socket option */
+ i = 1;
+ setsockopt(ssock, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i));
+ con->state = CON_GREETING;
+ retval--;
+ if (retval == 0)
+ break;
+ }
+ }
+ }
+
/* It must be a client socket. Find a context that has data
* waiting on its socket *and* is in the CON_IDLE state. Any
* active sockets other than our chosen one are marked as
-
-/*
- * A function to handle selecting on master sockets.
- * In other words it handles new connections.
- * It is a thread.
- */
-void *select_on_master(void *blah)
-{
- struct ServiceFunctionHook *serviceptr;
- fd_set master_fds;
- int highest;
- struct timeval tv;
- int ssock; /* Descriptor for client socket */
- CitContext *con = NULL; /* Temporary context pointer */
- int m;
- int i;
- int retval;
-
- while (!server_shutting_down) {
- /* Initialize the fdset. */
- FD_ZERO(&master_fds);
- highest = 0;
-
- /* First, add the various master sockets to the fdset. */
- for (serviceptr = ServiceHookTable; serviceptr != NULL;
- serviceptr = serviceptr->next ) {
- m = serviceptr->msock;
- FD_SET(m, &master_fds);
- if (m > highest) {
- highest = m;
- }
- }
-
- if (!server_shutting_down) {
- tv.tv_sec = 60; /* wake up every second if no input */
- tv.tv_usec = 0;
- retval = select(highest + 1, &master_fds, NULL, NULL, &tv);
- }
- else {
- retval = -1 ;
- }
-
- /* Now figure out who made this select() unblock.
- * First, check for an error or exit condition.
- */
- if (retval < 0) {
- if (errno == EBADF) {
- syslog(LOG_NOTICE, "select() failed: (%s)\n",
- strerror(errno));
- continue;
- }
- if (errno != EINTR) {
- syslog(LOG_EMERG, "Exiting (%s)\n", strerror(errno));
- server_shutting_down = 1;
- } else {
-#if 0
- syslog(LOG_DEBUG, "Interrupted CtdlThreadSelect.\n");
-#endif
- if (server_shutting_down) return(NULL);
- continue;
- }
- }
-
- /* Next, check to see if it's a new client connecting
- * on a master socket.
- */
- else if ((retval > 0) && (!server_shutting_down)) for (serviceptr = ServiceHookTable; serviceptr != NULL; serviceptr = serviceptr->next) {
-
- if (FD_ISSET(serviceptr->msock, &master_fds)) {
- ssock = accept(serviceptr->msock, NULL, 0);
- if (ssock >= 0) {
- syslog(LOG_DEBUG, "New client socket %d\n", ssock);
-
- /* The master socket is non-blocking but the client
- * sockets need to be blocking, otherwise certain
- * operations barf on FreeBSD. Not a fatal error.
- */
- if (fcntl(ssock, F_SETFL, 0) < 0) {
- syslog(LOG_EMERG,
- "citserver: Can't set socket to blocking: %s\n",
- strerror(errno));
- }
-
- /* New context will be created already
- * set up in the CON_EXECUTING state.
- */
- con = CreateNewContext();
-
- /* Assign our new socket number to it. */
- con->client_socket = ssock;
- con->h_command_function = serviceptr->h_command_function;
- con->h_async_function = serviceptr->h_async_function;
- con->h_greeting_function = serviceptr->h_greeting_function;
- con->ServiceName = serviceptr->ServiceName;
-
- /* Determine whether it's a local socket */
- if (serviceptr->sockpath != NULL) {
- con->is_local_socket = 1;
- }
-
- /* Set the SO_REUSEADDR socket option */
- i = 1;
- setsockopt(ssock, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i));
- con->state = CON_GREETING;
- retval--;
- if (retval == 0)
- break;
- }
- }
- }
- }
- return NULL;
-}
-
-
-
/*
* SyslogFacility()
* Translate text facility name to syslog.h defined value.