Blob
1 #include <u.h>2 #include <libc.h>4 static struct5 {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 };17 static void18 _syslogopen(void)19 {20 char buf[1024], *p;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 }30 /*31 * Print32 * sysname: time: mesg33 * on /sys/log/logname.34 * If cons or log file can't be opened, print on the system console, too.35 */36 void37 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];46 err[0] = '\0';47 errstr(err, sizeof err);48 lock(&sl.lk);50 /*51 * paranoia makes us stat to make sure a fork+close52 * hasn't broken our fd's53 */54 d = dirfstat(sl.fd);55 if(sl.fd < 056 || sl.name == nil57 || strcmp(sl.name, logname)!=058 || sl.d == nil59 || d == nil60 || d->dev != sl.d->dev61 || d->type != sl.d->type62 || 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 < 080 || d == nil81 || sl.consd == nil82 || d->dev != sl.consd->dev83 || d->type != sl.consd->type84 || 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 }93 if(fmt == nil){94 unlock(&sl.lk);95 return;96 }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;110 if(sl.fd >= 0){111 seek(sl.fd, 0, 2);112 write(sl.fd, buf, n);113 }115 if(cons && sl.consfd >=0)116 write(sl.consfd, buf, n);118 unlock(&sl.lk);119 }