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