diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2005-04-07 20:16:46 +0000 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2005-04-07 20:16:46 +0000 |
commit | 9d61c9a250667045d94b373863ab24c313bc249f (patch) | |
tree | c2220e6a4ca381274e2461244b1c93a95a7a6c7a /winsup/cygwin/syslog.cc | |
parent | a5bfc6871275ec3962208e23756f051f2d38350d (diff) | |
download | cygnal-9d61c9a250667045d94b373863ab24c313bc249f.tar.gz cygnal-9d61c9a250667045d94b373863ab24c313bc249f.tar.bz2 cygnal-9d61c9a250667045d94b373863ab24c313bc249f.zip |
* 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.
Diffstat (limited to 'winsup/cygwin/syslog.cc')
-rw-r--r-- | winsup/cygwin/syslog.cc | 80 |
1 files changed, 78 insertions, 2 deletions
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 <stdlib.h> #include <stdio.h> #include <syslog.h> #include <stdarg.h> #include <unistd.h> +#include <sys/socket.h> #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 (); } |