]> code.citadel.org Git - citadel.git/blobdiff - citadel/sysdep.c
Created a routine to get a copy of the context list so that it can be
[citadel.git] / citadel / sysdep.c
index b89680c9eeda02ea3f001fd25cf54860a86b9869..bf77408ee4e80fbe305594be210ff93bc49f03cd 100644 (file)
@@ -155,7 +155,7 @@ void vlprintf(enum LogLevel loglevel, const char *format, va_list arg_ptr)
                                tim.tm_mday, tim.tm_hour, tim.tm_min,
                                tim.tm_sec, (long)tv.tv_usec);
                }
-               vsprintf(buf2, format, arg_ptr);   
+               vsnprintf(buf2, SIZ, format, arg_ptr);   
 
                fprintf(stderr, "%s%s", buf, buf2);
                fflush(stderr);
@@ -460,6 +460,24 @@ struct CitContext *CreateNewContext(void) {
 }
 
 
+struct CitContext *CtdlGetContextArray(int *count)
+{
+       int nContexts, i;
+       struct CitContext *nptr, *cptr;
+       
+       nContexts = num_sessions;
+       nptr = malloc(sizeof(struct CitContext) * nContexts);
+       if (!nptr)
+               return NULL;
+       begin_critical_section(S_SESSION_TABLE);
+       for (cptr = ContextList, i=0; cptr != NULL && i < nContexts; cptr = cptr->next, i++)
+               memcpy(&nptr[i], cptr, sizeof (struct CitContext));
+       end_critical_section (S_SESSION_TABLE);
+       
+       *count = i;
+       return nptr;
+}
+
 /*
  * The following functions implement output buffering. If the kernel supplies
  * native TCP buffering (Linux & *BSD), use that; otherwise, emulate it with
@@ -547,7 +565,9 @@ void client_write(char *buf, int nbytes)
 #ifndef HAVE_TCP_BUFFERING
        int old_buffer_len = 0;
 #endif
+       fd_set wset;
        t_context *Ctx;
+       int fdflags;
 
        Ctx = CC;
        if (Ctx->redirect_buffer != NULL) {
@@ -582,7 +602,23 @@ void client_write(char *buf, int nbytes)
        }
 #endif
 
+       fdflags = fcntl(Ctx->client_socket, F_GETFL);
+
        while (bytes_written < nbytes) {
+               if ((fdflags & O_NONBLOCK) == O_NONBLOCK) {
+                       FD_ZERO(&wset);
+                       FD_SET(Ctx->client_socket, &wset);
+                       if (select(1, NULL, &wset, NULL, NULL) == -1) {
+                               CtdlLogPrintf(CTDL_ERR,
+                                       "client_write(%d bytes) select failed: %s (%d)\n",
+                                       nbytes - bytes_written,
+                                       strerror(errno), errno);
+                               cit_backtrace();
+                               Ctx->kill_me = 1;
+                               return;
+                       }
+               }
+
                retval = write(Ctx->client_socket, &buf[bytes_written],
                        nbytes - bytes_written);
                if (retval < 1) {
@@ -883,11 +919,7 @@ void start_daemon(int unused) {
                else {
                        fp = fopen(file_pid_file, "w");
                        if (fp != NULL) {
-               /*
-                * NB.. The pid file contains the pid of the actual server.
-                * This is not the pid of the watcher process
-                */
-                               fprintf(fp, ""F_PID_T"\n", current_child);
+                               fprintf(fp, ""F_PID_T"\n", getpid());
                                fclose(fp);
                        }
                        waitpid(current_child, &status, 0);
@@ -1145,7 +1177,7 @@ do_select:        force_purge = 0;
                                CtdlLogPrintf(CTDL_EMERG, "Exiting (%s)\n", strerror(errno));
                                CtdlThreadStopAll();
                        } else if (!CtdlThreadCheckStop()) {
-                               CtdlLogPrintf(CTDL_DEBUG, "Un handled select failure.\n");
+                               CtdlLogPrintf(CTDL_DEBUG, "Interrupted select.\n");
                                goto do_select;
                        }
                }