|  | #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); | 
|  | } |