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 }