xref: /plan9-contrib/sys/src/libc/9sys/syslog.c (revision 7dd7cddf99dd7472612f1413b4da293630e6b1bc)
1 #include <u.h>
2 #include <libc.h>
3 
4 static struct
5 {
6 	int	fd;
7 	int	consfd;
8 	char	name[NAMELEN];
9 	Dir	d;
10 	Dir	consd;
11 	Lock;
12 } sl =
13 {
14 	-1, -1,
15 };
16 
17 static 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 /*
29  * Print
30  *  sysname: time: mesg
31  * on /sys/log/logname.
32  * If cons or log file can't be opened, print on the system console, too.
33  */
34 void
35 syslog(int cons, char *logname, char *fmt, ...)
36 {
37 	char buf[1024];
38 	char *ctim, *p;
39 	va_list arg;
40 	int n;
41 	Dir d;
42 	char err[ERRLEN];
43 
44 	errstr(err);
45 	lock(&sl);
46 
47 	/*
48 	 *  paranoia makes us stat to make sure a fork+close
49 	 *  hasn't broken our fd's
50 	 */
51 	if(sl.fd < 0
52 	   || strcmp(sl.name, logname)!=0
53 	   || dirfstat(sl.fd, &d) < 0
54 	   || d.dev != sl.d.dev
55 	   || d.type != sl.d.type
56 	   || d.qid.path != sl.d.qid.path){
57 		strncpy(sl.name, logname, NAMELEN-1);
58 		_syslogopen();
59 		if(sl.fd < 0)
60 			cons = 1;
61 		sl.d = d;
62 	}
63 	if(cons)
64 		if(sl.consfd < 0
65 		   || dirfstat(sl.consfd, &d) < 0
66 		   || d.dev != sl.consd.dev
67 		   || d.type != sl.consd.type
68 		   || d.qid.path != sl.consd.qid.path){
69 			sl.consfd = open("#c/cons", OWRITE|OCEXEC);
70 			sl.consd = d;
71 		}
72 
73 	if(fmt == nil){
74 		unlock(&sl);
75 		return;
76 	}
77 
78 	ctim = ctime(time(0));
79 	werrstr(err);
80 	p = buf + snprint(buf, sizeof(buf)-1, "%s ", sysname());
81 	strncpy(p, ctim+4, 15);
82 	p += 15;
83 	*p++ = ' ';
84 	va_start(arg, fmt);
85 	p = doprint(p, buf+sizeof(buf)-1, fmt, arg);
86 	va_end(arg);
87 	*p++ = '\n';
88 	n = p - buf;
89 
90 	if(sl.fd >= 0){
91 		seek(sl.fd, 0, 2);
92 		write(sl.fd, buf, n);
93 	}
94 
95 	if(cons && sl.consfd >=0)
96 		write(sl.consfd, buf, n);
97 
98 	unlock(&sl);
99 }
100