| #include <u.h> |
| #include <libc.h> |
| |
| static struct |
| { |
| int fd; |
| int consfd; |
| char *name; |
| Dir *d; |
| Dir *consd; |
| Lock lk; |
| } sl = |
| { |
| -1, -1, |
| }; |
| |
| static void |
| _syslogopen(void) |
| { |
| char buf[1024], *p; |
| |
| if(sl.fd >= 0) |
| close(sl.fd); |
| snprint(buf, sizeof(buf), "#9/log/%s", sl.name); |
| p = unsharp(buf); |
| sl.fd = open(p, OWRITE|OCEXEC|OAPPEND); |
| free(p); |
| } |
| |
| /* |
| * Print |
| * sysname: time: mesg |
| * on /sys/log/logname. |
| * If cons or log file can't be opened, print on the system console, too. |
| */ |
| void |
| syslog(int cons, char *logname, char *fmt, ...) |
| { |
| char buf[1024]; |
| char *ctim, *p; |
| va_list arg; |
| int n; |
| Dir *d; |
| char err[ERRMAX]; |
| |
| err[0] = '\0'; |
| errstr(err, sizeof err); |
| lock(&sl.lk); |
| |
| /* |
| * paranoia makes us stat to make sure a fork+close |
| * hasn't broken our fd's |
| */ |
| d = dirfstat(sl.fd); |
| if(sl.fd < 0 |
| || sl.name == nil |
| || strcmp(sl.name, logname)!=0 |
| || sl.d == nil |
| || d == nil |
| || d->dev != sl.d->dev |
| || d->type != sl.d->type |
| || d->qid.path != sl.d->qid.path){ |
| free(sl.name); |
| sl.name = strdup(logname); |
| if(sl.name == nil) |
| cons = 1; |
| else{ |
| _syslogopen(); |
| if(sl.fd < 0) |
| cons = 1; |
| free(sl.d); |
| sl.d = d; |
| d = nil; /* don't free it */ |
| } |
| } |
| free(d); |
| if(cons){ |
| d = dirfstat(sl.consfd); |
| if(sl.consfd < 0 |
| || d == nil |
| || sl.consd == nil |
| || d->dev != sl.consd->dev |
| || d->type != sl.consd->type |
| || d->qid.path != sl.consd->qid.path){ |
| sl.consfd = open("/dev/tty", OWRITE|OCEXEC); |
| free(sl.consd); |
| sl.consd = d; |
| d = nil; /* don't free it */ |
| } |
| free(d); |
| } |
| |
| if(fmt == nil){ |
| unlock(&sl.lk); |
| return; |
| } |
| |
| ctim = ctime(time(0)); |
| werrstr(err); |
| p = buf + snprint(buf, sizeof(buf)-1, "%s ", sysname()); |
| strncpy(p, ctim+4, 15); |
| p += 15; |
| *p++ = ' '; |
| va_start(arg, fmt); |
| p = vseprint(p, buf+sizeof(buf)-1, fmt, arg); |
| va_end(arg); |
| *p++ = '\n'; |
| n = p - buf; |
| |
| if(sl.fd >= 0){ |
| seek(sl.fd, 0, 2); |
| write(sl.fd, buf, n); |
| } |
| |
| if(cons && sl.consfd >=0) |
| write(sl.consfd, buf, n); |
| |
| unlock(&sl.lk); |
| } |