syslog.c - 9base - revived minimalist port of Plan 9 userland to Unix
 (HTM) git clone git://git.suckless.org/9base
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
       syslog.c (2001B)
       ---
            1 #include <u.h>
            2 #include <libc.h>
            3 
            4 static struct
            5 {
            6         int        fd;
            7         int        consfd;
            8         char        *name;
            9         Dir        *d;
           10         Dir        *consd;
           11         Lock        lk;
           12 } sl =
           13 {
           14         -1, -1,
           15 };
           16 
           17 static void
           18 _syslogopen(void)
           19 {
           20         char buf[1024], *p;
           21 
           22         if(sl.fd >= 0)
           23                 close(sl.fd);
           24         snprint(buf, sizeof(buf), "#9/log/%s", sl.name);
           25         p = unsharp(buf);
           26         sl.fd = open(p, OWRITE|OCEXEC|OAPPEND);
           27         free(p);
           28 }
           29 
           30 /*
           31  * Print
           32  *  sysname: time: mesg
           33  * on /sys/log/logname.
           34  * If cons or log file can't be opened, print on the system console, too.
           35  */
           36 void
           37 syslog(int cons, char *logname, char *fmt, ...)
           38 {
           39         char buf[1024];
           40         char *ctim, *p;
           41         va_list arg;
           42         int n;
           43         Dir *d;
           44         char err[ERRMAX];
           45 
           46         err[0] = '\0';
           47         errstr(err, sizeof err);
           48         lock(&sl.lk);
           49 
           50         /*
           51          *  paranoia makes us stat to make sure a fork+close
           52          *  hasn't broken our fd's
           53          */
           54         d = dirfstat(sl.fd);
           55         if(sl.fd < 0
           56            || sl.name == nil
           57            || strcmp(sl.name, logname)!=0
           58            || sl.d == nil
           59            || d == nil
           60            || d->dev != sl.d->dev
           61            || d->type != sl.d->type
           62            || d->qid.path != sl.d->qid.path){
           63                 free(sl.name);
           64                 sl.name = strdup(logname);
           65                 if(sl.name == nil)
           66                         cons = 1;
           67                 else{
           68                         _syslogopen();
           69                         if(sl.fd < 0)
           70                                 cons = 1;
           71                         free(sl.d);
           72                         sl.d = d;
           73                         d = nil;        /* don't free it */
           74                 }
           75         }
           76         free(d);
           77         if(cons){
           78                 d = dirfstat(sl.consfd);
           79                 if(sl.consfd < 0
           80                    || d == nil
           81                    || sl.consd == nil
           82                    || d->dev != sl.consd->dev
           83                    || d->type != sl.consd->type
           84                    || d->qid.path != sl.consd->qid.path){
           85                         sl.consfd = open("/dev/tty", OWRITE|OCEXEC);
           86                         free(sl.consd);
           87                         sl.consd = d;
           88                         d = nil;        /* don't free it */
           89                 }
           90                 free(d);
           91         }
           92 
           93         if(fmt == nil){
           94                 unlock(&sl.lk);
           95                 return;
           96         }
           97 
           98         ctim = ctime(time(0));
           99         werrstr(err);
          100         p = buf + snprint(buf, sizeof(buf)-1, "%s ", sysname());
          101         strncpy(p, ctim+4, 15);
          102         p += 15;
          103         *p++ = ' ';
          104         va_start(arg, fmt);
          105         p = vseprint(p, buf+sizeof(buf)-1, fmt, arg);
          106         va_end(arg);
          107         *p++ = '\n';
          108         n = p - buf;
          109 
          110         if(sl.fd >= 0){
          111                 seek(sl.fd, 0, 2);
          112                 write(sl.fd, buf, n);
          113         }
          114 
          115         if(cons && sl.consfd >=0)
          116                 write(sl.consfd, buf, n);
          117 
          118         unlock(&sl.lk);
          119 }