about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--doc/s6-log.html12
-rw-r--r--src/daemontools-extras/s6-log.c26
2 files changed, 29 insertions, 9 deletions
diff --git a/doc/s6-log.html b/doc/s6-log.html
index 5142fa8..6538017 100644
--- a/doc/s6-log.html
+++ b/doc/s6-log.html
@@ -27,7 +27,7 @@ with full POSIX regular expression support.
 <h2> Interface </h2>
 
 <pre>
-     s6-log [ -q | -v ] [ -b ] [ -p ] [ -t ] [ -e ] [ -l linelimit ] <em>logging script</em>
+     s6-log [ -d <em>notif</em> ] [ -q | -v ] [ -b ] [ -p ] [ -t ] [ -e ] [ -l <em>linelimit</em> ] <em>logging script</em>
 </pre>
 
 <p>
@@ -41,6 +41,13 @@ it receives a SIGTERM or a SIGHUP.
 <h2> Options </h2>
 
 <ul>
+ <li> <tt>-d&nbsp;<em>notif</em></tt>&nbsp;:
+<a href="notifywhenup.html">readiness notification.</a>
+With this option, s6-log writes a newline character to file descriptor
+<em>notif</em> when it is <em>ready</em>, i.e. when it has successfully
+parsed its logging script and initialized all its necessary resources
+such as the logdirs defined in the script, and is now listening to stdin
+in order to process log lines. </li>
  <li> <tt>-b</tt>&nbsp;: blocking mode. With this option, s6-log stops
 reading its standard input while it has unflushed buffers. This ensures that
 every log line has been fully processed before reading the next one; this is also
@@ -71,8 +78,7 @@ Currently supported verbosity levels:
 may appear anywhere after <em>linelimit</em> or more bytes. <em>linelimit</em>
 cannot be less than 48. Using this option ensures that an ill-formatted log
 stream will not make s6-log uncontrollably eat memory by trying to read and
-process an extremely long line in one go. The default is no cap on line
-length. </li>
+process an extremely long line in one go. The default is 8192 bytes. </li>
 </ul>
 
 <h2> Logdirs </h2>
diff --git a/src/daemontools-extras/s6-log.c b/src/daemontools-extras/s6-log.c
index 04cfe8c..b849f53 100644
--- a/src/daemontools-extras/s6-log.c
+++ b/src/daemontools-extras/s6-log.c
@@ -1,5 +1,6 @@
 /* ISC license. */
 
+#include <fcntl.h>
 #include <sys/stat.h>
 #include <sys/wait.h>
 #include <stdint.h>
@@ -10,6 +11,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <regex.h>
+
 #include <skalibs/posixplz.h>
 #include <skalibs/uint64.h>
 #include <skalibs/types.h>
@@ -31,9 +33,10 @@
 #include <skalibs/siovec.h>
 #include <skalibs/skamisc.h>
 #include <skalibs/environ.h>
+
 #include <execline/config.h>
 
-#define USAGE "s6-log [ -q | -v ] [ -b ] [ -p ] [ -t ] [ -e ] [ -l linelimit ] logging_script"
+#define USAGE "s6-log [ -d notif ] [ -q | -v ] [ -b ] [ -p ] [ -t ] [ -e ] [ -l linelimit ] logging_script"
 #define dieusage() strerr_dieusage(100, USAGE)
 #define dienomem() strerr_diefu1sys(111, "stralloc_catb")
 
@@ -611,9 +614,7 @@ static inline void logdir_init (unsigned int index, uint32_t s, uint32_t n, uint
   if (finish(ldp, "current", 'u') < 0)
     strerr_diefu2sys(111, "finish current .u for logdir ", ldp->dir) ;
   memcpy(x + dirlen + 1, "state", 6) ;
-  ldp->fd = open_trunc(x) ;
-  if (ldp->fd < 0) strerr_diefu2sys(111, "open_trunc ", x) ;
-  fd_close(ldp->fd) ;
+  if (truncate(x, 0) == -1) strerr_diefu2sys(111, "truncate ", x) ;
   st.st_size = 0 ;
   memcpy(x + dirlen + 1, "current", 8) ;
  opencurrent:
@@ -1141,14 +1142,17 @@ static inline void handle_signals (void)
 int main (int argc, char const *const *argv)
 {
   unsigned int sellen, actlen, scriptlen ;
-  unsigned int linelimit = 0, gflags = 0, compat_gflags = 0 ;
+  unsigned int linelimit = 8192 ;
+  unsigned int notif = 0 ;
+  unsigned int gflags = 0 ;
+  unsigned int compat_gflags = 0 ;
   int flagblock = 0 ;
   PROG = "s6-log" ;
   {
     subgetopt_t l = SUBGETOPT_ZERO ;
     for (;;)
     {
-      int opt = subgetopt_r(argc, argv, "qvbptel:", &l) ;
+      int opt = subgetopt_r(argc, argv, "qvbptel:d:", &l) ;
       if (opt == -1) break ;
       switch (opt)
       {
@@ -1159,6 +1163,11 @@ int main (int argc, char const *const *argv)
         case 't' : gflags |= 1 ; compat_gflags |= 1 ; break ;
         case 'e' : gflags |= 1 ; compat_gflags |= 2 ; break ;
         case 'l' : if (!uint0_scan(l.arg, &linelimit)) dieusage() ; break ;
+        case 'd' :
+          if (!uint0_scan(l.arg, &notif)) dieusage() ;
+          if (notif < 3) strerr_dief1x(100, "notification fd must be 3 or more") ;
+          if (fcntl(notif, F_GETFD) < 0) strerr_dief1sys(100, "invalid notification fd") ;
+          break ;
         default : dieusage() ;
       }
     }
@@ -1194,6 +1203,11 @@ int main (int argc, char const *const *argv)
         strerr_diefu1sys(111, "selfpipe_trapset") ;
     }
     x[0].events = IOPAUSE_READ ;
+    if (notif)
+    {
+      fd_write(notif, "\n", 1) ;
+      fd_close(notif) ;
+    }
 
     for (;;)
     {