126 lines
2.5 KiB
C
126 lines
2.5 KiB
C
/*
|
|
* This file is part of the UCB release of Plan 9. It is subject to the license
|
|
* terms in the LICENSE file found in the top-level directory of this
|
|
* distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
|
|
* part of the UCB release of Plan 9, including this file, may be copied,
|
|
* modified, propagated, or distributed except according to the terms contained
|
|
* in the LICENSE file.
|
|
*/
|
|
|
|
#include <u.h>
|
|
#include <libc.h>
|
|
|
|
static struct
|
|
{
|
|
int fd;
|
|
int consfd;
|
|
char *name;
|
|
Dir *d;
|
|
Dir *consd;
|
|
Lock;
|
|
} sl =
|
|
{
|
|
-1, -1,
|
|
};
|
|
|
|
static void
|
|
_syslogopen(void)
|
|
{
|
|
char buf[1024];
|
|
|
|
if(sl.fd >= 0)
|
|
close(sl.fd);
|
|
jehanne_snprint(buf, sizeof(buf), "/sys/log/%s", sl.name);
|
|
sl.fd = open(buf, OWRITE|OCEXEC);
|
|
}
|
|
|
|
static int
|
|
eqdirdev(Dir *a, Dir *b)
|
|
{
|
|
return a != nil && b != nil &&
|
|
a->dev == b->dev && a->type == b->type &&
|
|
a->qid.path == b->qid.path;
|
|
}
|
|
|
|
/*
|
|
* Print
|
|
* sysname: time: mesg
|
|
* on /sys/log/logname.
|
|
* If cons or log file can't be opened, print on the system console, too.
|
|
*/
|
|
void
|
|
jehanne_syslog(int cons, const char *logname, const char *fmt, ...)
|
|
{
|
|
char buf[1024];
|
|
char *ctim, *p;
|
|
va_list arg;
|
|
int n;
|
|
Dir *d;
|
|
char err[ERRMAX];
|
|
|
|
err[0] = '\0';
|
|
errstr(err, sizeof err);
|
|
jehanne_lock(&sl);
|
|
|
|
/*
|
|
* paranoia makes us stat to make sure a fork+close
|
|
* hasn't broken our fd's
|
|
*/
|
|
d = jehanne_dirfstat(sl.fd);
|
|
if(sl.fd < 0 || sl.name == nil || jehanne_strcmp(sl.name, logname) != 0 ||
|
|
!eqdirdev(d, sl.d)){
|
|
jehanne_free(sl.name);
|
|
sl.name = jehanne_strdup(logname);
|
|
if(sl.name == nil)
|
|
cons = 1;
|
|
else{
|
|
jehanne_free(sl.d);
|
|
sl.d = nil;
|
|
_syslogopen();
|
|
if(sl.fd < 0)
|
|
cons = 1;
|
|
else
|
|
sl.d = jehanne_dirfstat(sl.fd);
|
|
}
|
|
}
|
|
jehanne_free(d);
|
|
if(cons){
|
|
d = jehanne_dirfstat(sl.consfd);
|
|
if(sl.consfd < 0 || !eqdirdev(d, sl.consd)){
|
|
jehanne_free(sl.consd);
|
|
sl.consd = nil;
|
|
sl.consfd = open("#c/cons", OWRITE|OCEXEC);
|
|
if(sl.consfd >= 0)
|
|
sl.consd = jehanne_dirfstat(sl.consfd);
|
|
}
|
|
jehanne_free(d);
|
|
}
|
|
|
|
if(fmt == nil){
|
|
jehanne_unlock(&sl);
|
|
return;
|
|
}
|
|
|
|
ctim = jehanne_ctime(jehanne_time(0));
|
|
p = buf + jehanne_snprint(buf, sizeof(buf)-1, "%s ", jehanne_sysname());
|
|
jehanne_strncpy(p, ctim+4, 15);
|
|
p += 15;
|
|
*p++ = ' ';
|
|
errstr(err, sizeof err);
|
|
va_start(arg, fmt);
|
|
p = jehanne_vseprint(p, buf+sizeof(buf)-1, fmt, arg);
|
|
va_end(arg);
|
|
*p++ = '\n';
|
|
n = p - buf;
|
|
|
|
if(sl.fd >= 0){
|
|
seek(sl.fd, 0, 2);
|
|
write(sl.fd, buf, n);
|
|
}
|
|
|
|
if(cons && sl.consfd >=0)
|
|
write(sl.consfd, buf, n);
|
|
|
|
jehanne_unlock(&sl);
|
|
}
|