From 9d61c9a250667045d94b373863ab24c313bc249f Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Thu, 7 Apr 2005 20:16:46 +0000 Subject: [PATCH] * syslog.cc: Include sys/socket.h. (try_connect_guard): New static variable. (syslogd_inited): Ditto. (syslogd_sock): Ditto. (try_connect_syslogd): New function to connect and write syslog to local syslogd. (vsyslog): Log to stderr if LOG_PERROR flag has been given to openlog. Try logging to syslogd. Use Event Log resp. log file as fallback. (closelog): Close socket to syslogd. * include/sys/syslog.h (_PATH_LOG): Define. (INTERNAL_NOPRI): Define if SYSLOG_NAMES is defined. (INTERNAL_MARK): Ditto. (struct _code): Ditto. (prioritynames): Ditto. (facilitynames): Ditto. --- winsup/cygwin/ChangeLog | 18 +++++++ winsup/cygwin/include/sys/syslog.h | 58 +++++++++++++++++++++- winsup/cygwin/syslog.cc | 80 +++++++++++++++++++++++++++++- 3 files changed, 153 insertions(+), 3 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index fbfff6aa2..8dea2bcbc 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,21 @@ +2005-04-07 Corinna Vinschen + + * syslog.cc: Include sys/socket.h. + (try_connect_guard): New static variable. + (syslogd_inited): Ditto. + (syslogd_sock): Ditto. + (try_connect_syslogd): New function to connect and write syslog to + local syslogd. + (vsyslog): Log to stderr if LOG_PERROR flag has been given to openlog. + Try logging to syslogd. Use Event Log resp. log file as fallback. + (closelog): Close socket to syslogd. + * include/sys/syslog.h (_PATH_LOG): Define. + (INTERNAL_NOPRI): Define if SYSLOG_NAMES is defined. + (INTERNAL_MARK): Ditto. + (struct _code): Ditto. + (prioritynames): Ditto. + (facilitynames): Ditto. + 2005-04-06 Corinna Vinschen * fhandler_socket.cc (get_inet_addr): Add type parameter to return diff --git a/winsup/cygwin/include/sys/syslog.h b/winsup/cygwin/include/sys/syslog.h index a37b042d7..8b055177c 100644 --- a/winsup/cygwin/include/sys/syslog.h +++ b/winsup/cygwin/include/sys/syslog.h @@ -1,6 +1,6 @@ /* sys/syslog.h - Copyright 1996, 1998, 2001 Red Hat, Inc. + Copyright 1996, 1998, 2001, 2005 Red Hat, Inc. This file is part of Cygwin. @@ -14,6 +14,8 @@ details. */ #include #include +#define _PATH_LOG "/dev/log" + #define LOG_EMERG 0 #define LOG_ALERT 1 #define LOG_CRIT 2 @@ -55,6 +57,60 @@ details. */ #define LOG_FACMASK 0x03f8 #define LOG_FAC(p) (((p) & LOG_FACMASK) >> 3) +#ifdef SYSLOG_NAMES + +#define INTERNAL_NOPRI 0x10 /* Maps to "none" */ +#define INTERNAL_MARK LOG_MAKEPRI(LOG_NFACILITIES, 0) /* Maps to "mark" */ + +typedef struct _code { + char *c_name; + int c_val; +} CODE; + +CODE prioritynames[] = { + { "alert", LOG_ALERT }, + { "crit", LOG_CRIT }, + { "debug", LOG_DEBUG }, + { "emerg", LOG_EMERG }, + { "err", LOG_ERR }, + { "error", LOG_ERR }, /* Deprecated */ + { "info", LOG_INFO }, + { "none", INTERNAL_NOPRI }, + { "notice", LOG_NOTICE }, + { "panic", LOG_EMERG }, /* Deprecated */ + { "warn", LOG_WARNING }, /* Deprecated */ + { "warning", LOG_WARNING }, + { NULL, -1 } +}; + +CODE facilitynames[] = { + { "auth", LOG_AUTH }, + { "authpriv", LOG_AUTHPRIV }, + { "cron", LOG_CRON }, + { "daemon", LOG_DAEMON }, + { "ftp", LOG_FTP }, + { "kern", LOG_KERN }, + { "lpr", LOG_LPR }, + { "mail", LOG_MAIL }, + { "mark", INTERNAL_MARK }, + { "news", LOG_NEWS }, + { "security", LOG_AUTH }, /* Deprecated */ + { "syslog", LOG_SYSLOG }, + { "user", LOG_USER }, + { "uucp", LOG_UUCP }, + { "local0", LOG_LOCAL0 }, + { "local1", LOG_LOCAL1 }, + { "local2", LOG_LOCAL2 }, + { "local3", LOG_LOCAL3 }, + { "local4", LOG_LOCAL4 }, + { "local5", LOG_LOCAL5 }, + { "local6", LOG_LOCAL6 }, + { "local7", LOG_LOCAL7 }, + { NULL, -1 } +}; + +#endif /* SYSLOG_NAMES */ + #define LOG_MASK(pri) (1 << (pri)) #define LOG_UPTO(pri) ((1 << ((pri)+1)) - 1) diff --git a/winsup/cygwin/syslog.cc b/winsup/cygwin/syslog.cc index 01b38fab3..2ca97e05d 100644 --- a/winsup/cygwin/syslog.cc +++ b/winsup/cygwin/syslog.cc @@ -8,12 +8,15 @@ This software is a copyrighted work licensed under the terms of the Cygwin license. Please consult the file "CYGWIN_LICENSE" for details. */ +#define __INSIDE_CYGWIN_NET__ + #include "winsup.h" #include #include #include #include #include +#include #include "cygerrno.h" #include "security.h" #include "path.h" @@ -179,6 +182,66 @@ pass_handler::print_va (const char *fmt, va_list list) return -1; } +static NO_COPY muto try_connect_guard; +static bool syslogd_inited; +static int syslogd_sock = -1; +extern "C" int cygwin_socket (int, int, int); +extern "C" int cygwin_connect (int, const struct sockaddr *, int); + +static int +try_connect_syslogd (const char *msg, int len) +{ + try_connect_guard.init ("try_connect_guard")->acquire (); + if (!syslogd_inited) + { + struct __stat64 st; + int fd; + struct sockaddr sa; + + if (stat64 (_PATH_LOG, &st) || !S_ISSOCK (st.st_mode)) + goto out; + if ((fd = cygwin_socket (AF_LOCAL, SOCK_DGRAM, 0)) < 0) + goto out; + sa.sa_family = AF_LOCAL; + strncpy (sa.sa_data, _PATH_LOG, sizeof sa.sa_data); + if (cygwin_connect (fd, &sa, sizeof sa)) + { + if (get_errno () != EPROTOTYPE) + { + close (fd); + goto out; + } + /* Retry with SOCK_STREAM. */ + if ((fd = cygwin_socket (AF_LOCAL, SOCK_STREAM, 0)) < 0) + goto out; + if (cygwin_connect (fd, &sa, sizeof sa)) + { + close (fd); + goto out; + } + } + syslogd_sock = fd; + fcntl (syslogd_sock, F_SETFD, FD_CLOEXEC); + syslogd_inited = true; + } +out: + int ret = -1; + if (syslogd_sock >= 0) + { + ret = write (syslogd_sock, msg, len); + /* If write fails and LOG_CONS is set, return failure to vsyslog so + it falls back to the usual logging method for this OS. */ + if (ret >= 0 || !(_my_tls.locals.process_logopt & LOG_CONS)) + ret = syslogd_sock; + } +#ifdef EXC_GUARD + InterlockedExchange (&try_connect_guard, 2); +#else + try_connect_guard.release (); +#endif + return ret; +} + /* * syslog: creates the log message and writes to system * log (NT) or log file (95). FIXME. WinNT log error messages @@ -333,7 +396,13 @@ vsyslog (int priority, const char *message, va_list ap) msg_strings[0] = total_msg; - if (wincap.has_eventlog ()) + if (_my_tls.locals.process_logopt & LOG_PERROR) + write (STDERR_FILENO, total_msg, len + 1); + + int fd; + if ((fd = try_connect_syslogd (total_msg, len + 1)) >= 0) + ; + else if (wincap.has_eventlog ()) { /* For NT, open the event log and send the message */ HANDLE hEventSrc = RegisterEventSourceA (NULL, (_my_tls.locals.process_ident != NULL) ? @@ -399,5 +468,12 @@ syslog (int priority, const char *message, ...) extern "C" void closelog (void) { - ; + try_connect_guard.init ("try_connect_guard")->acquire (); + if (syslogd_inited && syslogd_sock >= 0) + { + close (syslogd_sock); + syslogd_sock = -1; + syslogd_inited = false; + } + try_connect_guard.release (); }