xref: /plan9/sys/src/libc/9sys/syslog.c (revision ff8c3af2f44d95267f67219afa20ba82ff6cf7e4)
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
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[ERRMAX];
43 
44 	err[0] = '\0';
45 	errstr(err, sizeof err);
46 	lock(&sl);
47 
48 	/*
49 	 *  paranoia makes us stat to make sure a fork+close
50 	 *  hasn't broken our fd's
51 	 */
52 	d = dirfstat(sl.fd);
53 	if(sl.fd < 0
54 	   || sl.name == nil
55 	   || strcmp(sl.name, logname)!=0
56 	   || sl.d == nil
57 	   || d == nil
58 	   || d->dev != sl.d->dev
59 	   || d->type != sl.d->type
60 	   || d->qid.path != sl.d->qid.path){
61 		free(sl.name);
62 		sl.name = strdup(logname);
63 		if(sl.name == nil)
64 			cons = 1;
65 		else{
66 			_syslogopen();
67 			if(sl.fd < 0)
68 				cons = 1;
69 			free(sl.d);
70 			sl.d = d;
71 			d = nil;	/* don't free it */
72 		}
73 	}
74 	free(d);
75 	if(cons){
76 		d = dirfstat(sl.consfd);
77 		if(sl.consfd < 0
78 		   || d == nil
79 		   || sl.consd == nil
80 		   || d->dev != sl.consd->dev
81 		   || d->type != sl.consd->type
82 		   || d->qid.path != sl.consd->qid.path){
83 			sl.consfd = open("#c/cons", OWRITE|OCEXEC);
84 			free(sl.consd);
85 			sl.consd = d;
86 			d = nil;	/* don't free it */
87 		}
88 		free(d);
89 	}
90 
91 	if(fmt == nil){
92 		unlock(&sl);
93 		return;
94 	}
95 
96 	ctim = ctime(time(0));
97 	werrstr(err);
98 	p = buf + snprint(buf, sizeof(buf)-1, "%s ", sysname());
99 	strncpy(p, ctim+4, 15);
100 	p += 15;
101 	*p++ = ' ';
102 	va_start(arg, fmt);
103 	p = vseprint(p, buf+sizeof(buf)-1, fmt, arg);
104 	va_end(arg);
105 	*p++ = '\n';
106 	n = p - buf;
107 
108 	if(sl.fd >= 0){
109 		seek(sl.fd, 0, 2);
110 		write(sl.fd, buf, n);
111 	}
112 
113 	if(cons && sl.consfd >=0)
114 		write(sl.consfd, buf, n);
115 
116 	unlock(&sl);
117 }
118