aboutsummaryrefslogtreecommitdiff
path: root/src/lib9/syslog.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib9/syslog.c')
-rw-r--r--src/lib9/syslog.c119
1 files changed, 119 insertions, 0 deletions
diff --git a/src/lib9/syslog.c b/src/lib9/syslog.c
new file mode 100644
index 00000000..8bb602eb
--- /dev/null
+++ b/src/lib9/syslog.c
@@ -0,0 +1,119 @@
+#include <u.h>
+#include <libc.h>
+
+static struct
+{
+ int fd;
+ int consfd;
+ char *name;
+ Dir *d;
+ Dir *consd;
+ Lock lk;
+} sl =
+{
+ -1, -1,
+};
+
+static void
+_syslogopen(void)
+{
+ char buf[1024], *p;
+
+ if(sl.fd >= 0)
+ close(sl.fd);
+ snprint(buf, sizeof(buf), "#9/log/%s", sl.name);
+ p = unsharp(buf);
+ sl.fd = open(p, OWRITE|OCEXEC|OAPPEND);
+ free(p);
+}
+
+/*
+ * Print
+ * sysname: time: mesg
+ * on /sys/log/logname.
+ * If cons or log file can't be opened, print on the system console, too.
+ */
+void
+syslog(int cons, char *logname, 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);
+ lock(&sl.lk);
+
+ /*
+ * paranoia makes us stat to make sure a fork+close
+ * hasn't broken our fd's
+ */
+ d = dirfstat(sl.fd);
+ if(sl.fd < 0
+ || sl.name == nil
+ || strcmp(sl.name, logname)!=0
+ || sl.d == nil
+ || d == nil
+ || d->dev != sl.d->dev
+ || d->type != sl.d->type
+ || d->qid.path != sl.d->qid.path){
+ free(sl.name);
+ sl.name = strdup(logname);
+ if(sl.name == nil)
+ cons = 1;
+ else{
+ _syslogopen();
+ if(sl.fd < 0)
+ cons = 1;
+ free(sl.d);
+ sl.d = d;
+ d = nil; /* don't free it */
+ }
+ }
+ free(d);
+ if(cons){
+ d = dirfstat(sl.consfd);
+ if(sl.consfd < 0
+ || d == nil
+ || sl.consd == nil
+ || d->dev != sl.consd->dev
+ || d->type != sl.consd->type
+ || d->qid.path != sl.consd->qid.path){
+ sl.consfd = open("/dev/tty", OWRITE|OCEXEC);
+ free(sl.consd);
+ sl.consd = d;
+ d = nil; /* don't free it */
+ }
+ free(d);
+ }
+
+ if(fmt == nil){
+ unlock(&sl.lk);
+ return;
+ }
+
+ ctim = ctime(time(0));
+ werrstr(err);
+ p = buf + snprint(buf, sizeof(buf)-1, "%s ", sysname());
+ strncpy(p, ctim+4, 15);
+ p += 15;
+ *p++ = ' ';
+ va_start(arg, fmt);
+ p = 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);
+
+ unlock(&sl.lk);
+}