chiark / gitweb /
buffer: Provide buffer_destroy
[secnet.git] / log.c
diff --git a/log.c b/log.c
index 326a891955fed55f07a21d9db86fda216a12f1c9..cbe4a85bf013fd8d2c432ba510b1f9ac301bb1d6 100644 (file)
--- a/log.c
+++ b/log.c
@@ -189,6 +189,59 @@ static void log_vmulti(void *sst, int class, const char *message, va_list args)
     }
 }
 
+void lg_vperror(struct log_if *lg, const char *desc, struct cloc *loc,
+               int class, int errnoval, const char *fmt, va_list al)
+{
+    int status=current_phase;
+    int esave=errno;
+
+    if (!lg)
+       lg=system_log;
+
+    if (class & M_FATAL)
+       enter_phase(PHASE_SHUTDOWN);
+
+    slilog_part(lg,class,"%s",desc);
+    if (loc)
+       slilog_part(lg,class," (%s:%d)",loc->file,loc->line);
+    slilog_part(lg,class,": ");
+    vslilog_part(lg,class,fmt,al);
+    if (errnoval)
+       slilog_part(lg,class,": %s",strerror(errnoval));
+    slilog_part(lg,class,"\n");
+
+    if (class & M_FATAL)
+       exit(status);
+
+    errno=esave;
+}
+
+void lg_perror(struct log_if *lg, const char *desc, struct cloc *loc,
+              int class, int errnoval, const char *fmt, ...)
+{
+    va_list al;
+    va_start(al,fmt);
+    lg_vperror(lg,desc,loc,class,errnoval,fmt,al);
+    va_end(al);
+}
+
+void lg_exitstatus(struct log_if *lg, const char *desc, struct cloc *loc,
+                  int class, int status, const char *progname)
+{
+    if (!status)
+       lg_perror(lg,desc,loc,class,0,"%s exited",progname);
+    else if (WIFEXITED(status))
+       lg_perror(lg,desc,loc,class,0,"%s exited with error exit status %d",
+                 progname,WEXITSTATUS(status));
+    else if (WIFSIGNALED(status))
+       lg_perror(lg,desc,loc,class,0,"%s died due to fatal signal %s (%d)%s",
+                 progname,strsignal(WTERMSIG(status)),WTERMSIG(status),
+                 WCOREDUMP(status)?" (core dumped)":"");
+    else
+       lg_perror(lg,desc,loc,class,0,"%s died with unknown wait status %d",
+                 progname,status);
+}
+
 struct log_if *init_log(list_t *ll)
 {
     int i=0;
@@ -485,9 +538,11 @@ static int log_from_fd_beforepoll(void *sst, struct pollfd *fds, int *nfds_io,
 {
     struct fdlog *st=sst;
     if (!st->finished) {
-       *nfds_io=1;
+       BEFOREPOLL_WANT_FDS(1);
        fds[0].fd=st->fd;
        fds[0].events=POLLIN;
+    } else {
+       BEFOREPOLL_WANT_FDS(0);
     }
     return 0;
 }
@@ -524,6 +579,7 @@ static void log_from_fd_afterpoll(void *sst, struct pollfd *fds, int nfds)
                    i=-1;
                }
            }
+       } else if (errno==EINTR || iswouldblock(errno)) {
        } else {
            Message(M_WARNING,"log_from_fd: %s\n",strerror(errno));
            st->finished=True;
@@ -543,7 +599,9 @@ void log_from_fd(int fd, cstring_t prefix, struct log_if *log)
     st->i=0;
     st->finished=False;
 
-    register_for_poll(st,log_from_fd_beforepoll,log_from_fd_afterpoll,1,
+    setnonblock(st->fd);
+
+    register_for_poll(st,log_from_fd_beforepoll,log_from_fd_afterpoll,
                      prefix);
 }