From 8584a9df5f3767dcc060188718c6dae92e14807b Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 2 Jan 2006 13:05:57 +0000 Subject: [PATCH] * syslog.cc: Include sys/un.h instead of sys/socket.h. (syslogd_inited): Convert to enum type noting the exact result of trying to connect to syslog daemon. Use this way throughout. (connect_syslogd): New static function taking over the task to connect to syslog socket. Use correct struct sockaddr_un instead of struct sockaddr. (try_connect_syslogd): Call connect_syslogd. If write fails on connection oriented socket, try to reconnect to syslog socket and try to write again. --- winsup/cygwin/ChangeLog | 12 +++++ winsup/cygwin/syslog.cc | 102 +++++++++++++++++++++++++--------------- 2 files changed, 75 insertions(+), 39 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 1ed4182f2..789620aa1 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,15 @@ +2006-01-02 Corinna Vinschen + + * syslog.cc: Include sys/un.h instead of sys/socket.h. + (syslogd_inited): Convert to enum type noting the exact result of + trying to connect to syslog daemon. Use this way throughout. + (connect_syslogd): New static function taking over the task to + connect to syslog socket. Use correct struct sockaddr_un instead of + struct sockaddr. + (try_connect_syslogd): Call connect_syslogd. If write fails on + connection oriented socket, try to reconnect to syslog socket and + try to write again. + 2006-01-01 Christopher Faylor * pinfo.cc (pinfo::exit): Swap signal and normal exit value when not diff --git a/winsup/cygwin/syslog.cc b/winsup/cygwin/syslog.cc index ea59ba812..3c43c3552 100644 --- a/winsup/cygwin/syslog.cc +++ b/winsup/cygwin/syslog.cc @@ -17,7 +17,7 @@ details. */ #include #include #include -#include +#include #include #include "cygerrno.h" #include "security.h" @@ -185,49 +185,65 @@ pass_handler::print_va (const char *fmt, va_list list) } static NO_COPY muto try_connect_guard; -static bool syslogd_inited; +static enum { + not_inited, + inited_failed, + inited_dgram, + inited_stream +} 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 void +connect_syslogd () +{ + struct __stat64 st; + int fd; + struct sockaddr_un sun; + + if (syslogd_inited != not_inited && syslogd_sock >= 0) + close (syslogd_sock); + syslogd_inited = inited_failed; + syslogd_sock = -1; + if (stat64 (_PATH_LOG, &st) || !S_ISSOCK (st.st_mode)) + return; + if ((fd = cygwin_socket (AF_LOCAL, SOCK_DGRAM, 0)) < 0) + return; + sun.sun_family = AF_LOCAL; + strncpy (sun.sun_path, _PATH_LOG, sizeof sun.sun_path); + if (cygwin_connect (fd, (struct sockaddr *) &sun, sizeof sun)) + { + if (get_errno () != EPROTOTYPE) + { + close (fd); + return; + } + /* Retry with SOCK_STREAM. */ + if ((fd = cygwin_socket (AF_LOCAL, SOCK_STREAM, 0)) < 0) + return; + if (cygwin_connect (fd, (struct sockaddr *) &sun, sizeof sun)) + { + close (fd); + return; + } + syslogd_inited = inited_stream; + } + else + syslogd_inited = inited_dgram; + syslogd_sock = fd; + fcntl (syslogd_sock, F_SETFD, FD_CLOEXEC); + return; +} + static int try_connect_syslogd (int priority, 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: ssize_t ret = -1; + + try_connect_guard.init ("try_connect_guard")->acquire (); + if (syslogd_inited == not_inited) + connect_syslogd (); if (syslogd_sock >= 0) { char pribuf[16]; @@ -238,8 +254,16 @@ out: { (char *) msg, len } }; - ret = writev (syslogd_sock, iv, 2); + /* If the syslog daemon has been restarted and /dev/log was + a stream socket, the connection is broken. In this case, + try to reopen the socket and try again. */ + if (ret < 0 && syslogd_inited == inited_stream) + { + connect_syslogd (); + if (syslogd_sock >= 0) + ret = writev (syslogd_sock, iv, 2); + } /* 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)) @@ -515,11 +539,11 @@ extern "C" void closelog (void) { try_connect_guard.init ("try_connect_guard")->acquire (); - if (syslogd_inited && syslogd_sock >= 0) + if (syslogd_inited != not_inited && syslogd_sock >= 0) { close (syslogd_sock); syslogd_sock = -1; - syslogd_inited = false; + syslogd_inited = not_inited; } try_connect_guard.release (); }