From 9771f29138d530e1a00f632fc2a7772fac1ee0f6 Mon Sep 17 00:00:00 2001 From: Jonas 'Sortie' Termansen Date: Sun, 19 Jan 2014 22:31:01 +0100 Subject: [PATCH] Add syslog(3). --- libc/Makefile | 6 +++ libc/include/syslog.h | 107 +++++++++++++++++++++++++++++++++++++ libc/syslog/closelog.cpp | 35 ++++++++++++ libc/syslog/connectlog.cpp | 31 +++++++++++ libc/syslog/openlog.cpp | 42 +++++++++++++++ libc/syslog/setlogmask.cpp | 33 ++++++++++++ libc/syslog/syslog.cpp | 34 ++++++++++++ libc/syslog/vsyslog.cpp | 78 +++++++++++++++++++++++++++ 8 files changed, 366 insertions(+) create mode 100644 libc/include/syslog.h create mode 100644 libc/syslog/closelog.cpp create mode 100644 libc/syslog/connectlog.cpp create mode 100644 libc/syslog/openlog.cpp create mode 100644 libc/syslog/setlogmask.cpp create mode 100644 libc/syslog/syslog.cpp create mode 100644 libc/syslog/vsyslog.cpp diff --git a/libc/Makefile b/libc/Makefile index f3bf5348..3290cb22 100644 --- a/libc/Makefile +++ b/libc/Makefile @@ -387,6 +387,12 @@ stdlib/unsetenv.o \ sys/display/dispmsg_issue.o \ sys/ioctl/ioctl.o \ sys/kernelinfo/kernelinfo.o \ +syslog/closelog.o \ +syslog/connectlog.o \ +syslog/openlog.o \ +syslog/setlogmask.o \ +syslog/syslog.o \ +syslog/vsyslog.o \ sys/mman/mmap.o \ sys/mman/mprotect.o \ sys/mman/munmap.o \ diff --git a/libc/include/syslog.h b/libc/include/syslog.h new file mode 100644 index 00000000..32865fc0 --- /dev/null +++ b/libc/include/syslog.h @@ -0,0 +1,107 @@ +/******************************************************************************* + + Copyright(C) Jonas 'Sortie' Termansen 2014. + + This file is part of the Sortix C Library. + + The Sortix C Library is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or (at your + option) any later version. + + The Sortix C Library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with the Sortix C Library. If not, see . + + syslog.h + System error logging facility. + +*******************************************************************************/ + +#ifndef INCLUDE_SYSLOG_H +#define INCLUDE_SYSLOG_H + +#include + +#include + +__BEGIN_DECLS + +#define LOG_PRISHIFT 0 +#define LOG_PRIBITS 3 +#define LOG_FACSHIFT LOG_PRIBITS +#define LOG_FACBITS (31 - LOG_PRIBITS) + +#define LOG_PRIMASK (((1 << LOG_PRIBITS) - 1) << LOG_PRISHIFT) +#define LOG_FACMASK (((1 << LOG_FACBITS) - 1) << LOG_FACSHIFT) +#define LOG_PRI(x) ((x) >> LOG_PRISHIFT & LOG_PRIMASK) +#define LOG_FAC(x) ((x) >> LOG_FACSHIFT & LOG_FACMASK) + +#define LOG_MAKEPRI(fac, pri) ((fac) << LOG_FACSHIFT | (pri) << LOG_PRISHIFT) + +#define LOG_EMERG 0 +#define LOG_ALERT 1 +#define LOG_CRIT 2 +#define LOG_ERR 3 +#define LOG_WARNING 4 +#define LOG_NOTICE 5 +#define LOG_INFO 6 +#define LOG_DEBUG 7 + +#define LOG_MASK(pri) (1 << ((pri) >> LOG_PRISHIFT)) +#define LOG_UPTO(pri) ((1 << (((pri) >> LOG_PRISHIFT) + 1)) - 1) + +#define LOG_KERN (0 << LOG_FACSHIFT) +#define LOG_USER (1 << LOG_FACSHIFT) +#define LOG_MAIL (2 << LOG_FACSHIFT) +#define LOG_DAEMON (3 << LOG_FACSHIFT) +#define LOG_AUTH (4 << LOG_FACSHIFT) +#define LOG_SYSLOG (5 << LOG_FACSHIFT) +#define LOG_LPR (6 << LOG_FACSHIFT) +#define LOG_NEWS (7 << LOG_FACSHIFT) +#define LOG_UUCP (8 << LOG_FACSHIFT) +#define LOG_CRON (9 << LOG_FACSHIFT) +#define LOG_AUTHPRIV (10 << LOG_FACSHIFT) +#define LOG_FTP (11 << LOG_FACSHIFT) +/* 12 through 15 are reserved */ +#define LOG_LOCAL0 (16 << LOG_FACSHIFT) +#define LOG_LOCAL1 (17 << LOG_FACSHIFT) +#define LOG_LOCAL2 (18 << LOG_FACSHIFT) +#define LOG_LOCAL3 (19 << LOG_FACSHIFT) +#define LOG_LOCAL4 (20 << LOG_FACSHIFT) +#define LOG_LOCAL5 (21 << LOG_FACSHIFT) +#define LOG_LOCAL6 (22 << LOG_FACSHIFT) +#define LOG_LOCAL7 (23 << LOG_FACSHIFT) +#define LOG_NFACILITIES 24 + +#define LOG_CONS (1 << 0) +#define LOG_NDELAY (1 << 1) +#define LOG_NOWAIT (1 << 2) +#define LOG_ODELAY (1 << 3) +#define LOG_PERROR (1 << 4) +#define LOG_PID (1 << 5) + +#if defined(__is_sortix_libc) +extern char* __syslog_identity; +extern int __syslog_facility; +extern int __syslog_fd; +extern int __syslog_mask; +extern int __syslog_option; +#endif + +void closelog(void); +int connectlog(void); +void openlog(const char*, int, int); +int setlogmask(int); +__attribute__ ((__format__ (__printf__, 2, 3))) +void syslog(int, const char*, ...); +__attribute__ ((__format__ (__printf__, 2, 0))) +void vsyslog(int, const char*, va_list); + +__END_DECLS + +#endif diff --git a/libc/syslog/closelog.cpp b/libc/syslog/closelog.cpp new file mode 100644 index 00000000..b2ed2b85 --- /dev/null +++ b/libc/syslog/closelog.cpp @@ -0,0 +1,35 @@ +/******************************************************************************* + + Copyright(C) Jonas 'Sortie' Termansen 2014. + + This file is part of the Sortix C Library. + + The Sortix C Library is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or (at your + option) any later version. + + The Sortix C Library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with the Sortix C Library. If not, see . + + syslog/closelog.cpp + Closes the connection to the system log. + +*******************************************************************************/ + +#include +#include + +extern "C" void closelog(void) +{ + if ( 0 <= __syslog_fd ) + { + close(__syslog_fd); + __syslog_fd = -1; + } +} diff --git a/libc/syslog/connectlog.cpp b/libc/syslog/connectlog.cpp new file mode 100644 index 00000000..19de04dd --- /dev/null +++ b/libc/syslog/connectlog.cpp @@ -0,0 +1,31 @@ +/******************************************************************************* + + Copyright(C) Jonas 'Sortie' Termansen 2014. + + This file is part of the Sortix C Library. + + The Sortix C Library is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or (at your + option) any later version. + + The Sortix C Library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with the Sortix C Library. If not, see . + + syslog/connectlog.cpp + Returns a file descriptor to the system log. + +*******************************************************************************/ + +#include +#include + +extern "C" int connectlog(void) +{ + return open("/dev/tty", O_WRONLY | O_CLOEXEC); +} diff --git a/libc/syslog/openlog.cpp b/libc/syslog/openlog.cpp new file mode 100644 index 00000000..9d1ae790 --- /dev/null +++ b/libc/syslog/openlog.cpp @@ -0,0 +1,42 @@ +/******************************************************************************* + + Copyright(C) Jonas 'Sortie' Termansen 2014. + + This file is part of the Sortix C Library. + + The Sortix C Library is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or (at your + option) any later version. + + The Sortix C Library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with the Sortix C Library. If not, see . + + syslog/openlog.cpp + Opens the connection to the system log. + +*******************************************************************************/ + +#include +#include +#include + +extern "C" void openlog(const char* identity, int option, int facility) +{ + // Remember the identity to report in the system log events. + free(__syslog_identity); + __syslog_identity = identity ? strdup(identity) : (char*) NULL; + + // Remember the option and facility parameters for later use. + __syslog_option = option; + __syslog_facility = facility; + + // Connect to the system more immediately if we are asked to and need to. + if ( (option & LOG_NDELAY) && __syslog_fd < 0 ) + __syslog_fd = connectlog(); +} diff --git a/libc/syslog/setlogmask.cpp b/libc/syslog/setlogmask.cpp new file mode 100644 index 00000000..58a9a986 --- /dev/null +++ b/libc/syslog/setlogmask.cpp @@ -0,0 +1,33 @@ +/******************************************************************************* + + Copyright(C) Jonas 'Sortie' Termansen 2014. + + This file is part of the Sortix C Library. + + The Sortix C Library is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or (at your + option) any later version. + + The Sortix C Library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with the Sortix C Library. If not, see . + + syslog/setlogmask.cpp + Sets the log priority mask. + +*******************************************************************************/ + +#include + +extern "C" int setlogmask(int mask) +{ + int previous_mask = __syslog_mask; + if ( mask ) + __syslog_mask = mask; + return previous_mask; +} diff --git a/libc/syslog/syslog.cpp b/libc/syslog/syslog.cpp new file mode 100644 index 00000000..8ff0e76e --- /dev/null +++ b/libc/syslog/syslog.cpp @@ -0,0 +1,34 @@ +/******************************************************************************* + + Copyright(C) Jonas 'Sortie' Termansen 2014. + + This file is part of the Sortix C Library. + + The Sortix C Library is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or (at your + option) any later version. + + The Sortix C Library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with the Sortix C Library. If not, see . + + syslog/syslog.cpp + Logs a condition to the system log. + +*******************************************************************************/ + +#include +#include + +extern "C" void syslog(int priority, const char* format, ...) +{ + va_list ap; + va_start(ap, format); + vsyslog(priority, format, ap); + va_end(ap); +} diff --git a/libc/syslog/vsyslog.cpp b/libc/syslog/vsyslog.cpp new file mode 100644 index 00000000..9041bc7c --- /dev/null +++ b/libc/syslog/vsyslog.cpp @@ -0,0 +1,78 @@ +/******************************************************************************* + + Copyright(C) Jonas 'Sortie' Termansen 2014. + + This file is part of the Sortix C Library. + + The Sortix C Library is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or (at your + option) any later version. + + The Sortix C Library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with the Sortix C Library. If not, see . + + syslog/vsyslog.cpp + Logs a condition to the system log. + +*******************************************************************************/ + +#include +#include +#include +#include +#include +#include + +extern "C" { char* __syslog_identity = NULL; } +extern "C" { int __syslog_facility = LOG_USER; } +extern "C" { int __syslog_fd = -1; } +extern "C" { int __syslog_mask = LOG_UPTO(LOG_DEBUG); } +extern "C" { int __syslog_option = 0; } + +// TODO: The transmitted string might be delivered in chunks using this dprintf +// approach (plus there are multiple dprintf calls). We should buffer the +// string fully before transmitting it. + +// TODO: The log entry format here is just whatever some other system does. We +// should work out the Sortix system log semantics and adapt this to that. + +extern "C" void vsyslog(int priority, const char* format, va_list ap) +{ + // Drop the event if it doesn't fit the current priority mask. + if ( !(LOG_MASK(LOG_PRI(priority)) & __syslog_mask) ) + return; + + // Connect to the system log if a connection hasn't yet been established. + if ( __syslog_fd < 0 && (__syslog_fd = connectlog()) < 0 ) + return; + + // If no facility is given we'll use the default facility from openlog. + if ( !LOG_FAC(priority) ) + priority |= __syslog_facility; + + // Prepare a timestamp for the log event. + struct timespec now; + clock_gettime(CLOCK_REALTIME, &now); + struct tm tm; + gmtime_r(&now.tv_sec, &tm); + char timestamp[32]; + strftime(timestamp, sizeof(timestamp), "%b %e %T", &tm); + + // Include the process id of the current process if requested. + pid_t pid = (__syslog_option & LOG_PID) ? getpid() : 0; + + // Transmit the event to the system log. + dprintf(__syslog_fd, "<%d>%s %s%s%.0jd%s: ", + priority, + timestamp, + __syslog_identity ? __syslog_identity : "", + "[" + !pid, (intmax_t) pid, "]" + !pid); + vdprintf(__syslog_fd, format, ap); + dprintf(__syslog_fd, "\n"); +}