| syslog.c - 9base - revived minimalist port of Plan 9 userland to Unix | |
| git clone git://git.suckless.org/9base | |
| Log | |
| Files | |
| Refs | |
| README | |
| 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 } |