xref: /plan9/sys/src/libc/9sys/syslog.c (revision 679a83a8d7e0f9e893634d11f642af4ee1846fd5)
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