tech-userlevel archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Add support for fifo files (mkfifo(2)) to syslogd(8)
Hi,
I would find it useful if syslogd(8) would handle writes to FIFO files in
addition to existing support for regular files.
I found some old discussion about this (see
http://mail-index.netbsd.org/tech-userlevel/2008/06/09/msg000742.html
and follow-ups), but this did not seem to reach a consensus
I just spent a few minutes adding support for FIFO to syslogd(8) with a
slightly different approach than in the thread above. AFAIK I did not introduce
any compatibility issue. My patch just tests if a file specified in a
syslog.conf is a FIFO or a regular file, and acts accordingly.
The patch is small enough so that I attach it below.
Would it be acceptable for integration into NetBSD?
--
Anthony
PS: The main reason for my request is not really fundamental, but I recently
figured out that since Linux kernel 2.6, Linux has broken^Wrestricted
/dev/console and the use of TIOCCONS to root. (and thus broken xconsole, xterm
-C etc.). I have a homemade ~20 lines script written in TCL that can watch
console messages on Linux by polling a FIFO file in /dev/xconsole (note the
'x'), which is what Linux found to unbreak xconsole and the like.
Watching /dev/console (the real one) from TCL on NetBSD is a bit hard, since
this requires some C code to send the proper TIOCCONS ioctl(2), and well
... this defeats the purpose of using some scripting language. All in all, I
finally find the use of a FIFO not that bad.
Index: syslogd.c
===================================================================
RCS file: /cvsroot/src/usr.sbin/syslogd/syslogd.c,v
retrieving revision 1.115
diff -u -r1.115 syslogd.c
--- syslogd.c 27 May 2013 23:15:51 -0000 1.115
+++ syslogd.c 7 Nov 2013 17:20:21 -0000
@@ -70,6 +70,7 @@
* TLS, syslog-protocol, and syslog-sign code by Martin Schuette.
*/
#define SYSLOG_NAMES
+#include <sys/stat.h>
#include <poll.h>
#include "syslogd.h"
#include "extern.h"
@@ -133,7 +134,8 @@
#define F_USERS 5 /* list of users */
#define F_WALL 6 /* everyone logged on */
#define F_PIPE 7 /* pipe to program */
-#define F_TLS 8
+#define F_FIFO 8 /* mkfifo(2) file */
+#define F_TLS 9
struct TypeInfo {
const char *name;
@@ -155,6 +157,7 @@
{"USERS", NULL, "0", NULL, "0", 0, 0, 1024},
{"WALL", NULL, "0", NULL, "0", 0, 0, 1024},
{"PIPE", NULL, "1024", NULL, "1M", 0, 0, 16384},
+ {"FIFO", NULL, "1024", NULL, "1M", 0, 0, 16384},
#ifndef DISABLE_TLS
{"TLS", NULL, "-1", NULL, "16M", 0, 0, 16384}
#endif /* !DISABLE_TLS */
@@ -2187,7 +2190,8 @@
|| (f->f_type == F_TTY)
|| (f->f_type == F_CONSOLE)
|| (f->f_type == F_USERS)
- || (f->f_type == F_WALL))) {
+ || (f->f_type == F_WALL)
+ || (f->f_type == F_FIFO))) {
DELREF(buffer);
return;
}
@@ -2196,7 +2200,8 @@
if (qentry
&& (f->f_type != F_TLS)
&& (f->f_type != F_PIPE)
- && (f->f_type != F_FILE)) {
+ && (f->f_type != F_FILE)
+ && (f->f_type != F_FIFO)) {
errno = 0;
logerror("Warning: unexpected message type %d in buffer",
f->f_type);
@@ -2253,6 +2258,7 @@
len = linelen - tlsprefixlen;
break;
case F_PIPE:
+ case F_FIFO:
case F_FILE: /* fallthrough */
if (f->f_flags & FFLAG_FULL) {
v->iov_base = line + tlsprefixlen;
@@ -2453,6 +2459,48 @@
}
break;
+ case F_FIFO:
+ DPRINTF(D_MISC, "Logging to %s %s\n",
+ TypeInfo[f->f_type].name, f->f_un.f_fname);
+ if (f->f_file < 0) {
+ f->f_file =
+ open(f->f_un.f_fname, O_WRONLY|O_NONBLOCK, 0);
+ e = errno;
+ if (f->f_file < 0 && e == ENXIO) {
+ /* Drop messages with no reader */
+ if (qentry)
+ message_queue_remove(f, qentry);
+ break;
+ }
+ }
+
+ if (f->f_file >= 0 && writev(f->f_file, iov, v - iov) < 0) {
+ e = errno;
+ close(f->f_file);
+ f->f_file = -1;
+
+ /* Drop messages with no reader */
+ if (e == EAGAIN || e == EPIPE) {
+ if (qentry)
+ message_queue_remove(f, qentry);
+ break;
+ }
+ }
+
+ if (f->f_file < 0) {
+ f->f_type = F_UNUSED;
+ errno = e;
+ f->f_lasterror = e;
+ logerror("%s", f->f_un.f_fname);
+ message_queue_freeall(f);
+ break;
+ }
+
+ f->f_lasterror = 0;
+ if (qentry) /* sent buffered msg */
+ message_queue_remove(f, qentry);
+ break;
+
case F_USERS:
case F_WALL:
DPRINTF(D_MISC, "Logging to %s\n", TypeInfo[f->f_type].name);
@@ -3622,6 +3670,7 @@
const char *p, *q;
char *bp;
char buf[MAXLINE];
+ struct stat sb;
DPRINTF((D_CALL|D_PARSE),
"cfline(%zu, \"%s\", f, \"%s\", \"%s\")\n",
@@ -3832,6 +3881,17 @@
f->f_flags |= FFLAG_SIGN;
#endif /* !DISABLE_SIGN */
(void)strlcpy(f->f_un.f_fname, p, sizeof(f->f_un.f_fname));
+ if (stat(p, &sb)) {
+ f->f_type = F_UNUSED;
+ logerror("%s", p);
+ break;
+ }
+ if (S_ISFIFO(sb.st_mode)) {
+ f->f_file = -1;
+ f->f_type = F_FIFO;
+ break;
+ }
+
if ((f->f_file = open(p, O_WRONLY|O_APPEND, 0)) < 0) {
f->f_type = F_UNUSED;
logerror("%s", p);
Home |
Main Index |
Thread Index |
Old Index