diff options
Diffstat (limited to 'src/sh_err_console.c')
-rw-r--r-- | src/sh_err_console.c | 115 |
1 files changed, 106 insertions, 9 deletions
diff --git a/src/sh_err_console.c b/src/sh_err_console.c index c3a8269..c813039 100644 --- a/src/sh_err_console.c +++ b/src/sh_err_console.c @@ -32,8 +32,11 @@ #include <stdio.h> #include <sys/types.h> #include <fcntl.h> +#include <sys/stat.h> #include <unistd.h> #include <signal.h> +#include <sys/socket.h> +#include <sys/un.h> extern int OnlyStderr; @@ -140,7 +143,7 @@ static void remove_message() MSG_NOERROR|IPC_NOWAIT); } while (rc < 0 && errno == EINTR); - memset(&recv_msg, '\0', sizeof(recv_msg)); + memset(&recv_msg, 0, sizeof(recv_msg)); return; } @@ -189,7 +192,7 @@ static int push_message_queue (const char * msg) if (count > 1) { - memset(recv_msg, '\0', MY_MAX_MSG+1); + memset(recv_msg, 0, MY_MAX_MSG+1); SH_FREE(recv_msg); SL_RETURN(-1, _("push_message_queue")); } @@ -213,13 +216,13 @@ static int push_message_queue (const char * msg) } else { TPT(( 0, FIL__, __LINE__, _("msg=<msgsnd: %s> errno=<%d>\n"), sh_error_message(errno, errbuf, sizeof(errbuf)), errno)); - memset(recv_msg, '\0', MY_MAX_MSG+1); + memset(recv_msg, 0, MY_MAX_MSG+1); SH_FREE(recv_msg); SL_RETURN(-1, _("push_message_queue")); } } - memset(recv_msg, '\0', MY_MAX_MSG+1); + memset(recv_msg, 0, MY_MAX_MSG+1); SH_FREE(recv_msg); SL_RETURN(0, _("push_message_queue")); @@ -244,9 +247,19 @@ void close_ipc() { sh_sem_close(); return; } static int count_dev_console = 0; +typedef enum { SH_LOG_UNIX, SH_LOG_OTHER, SH_LOG_INDEF } sh_log_devtype; + +static sh_log_devtype dt[2] = { SH_LOG_INDEF, SH_LOG_INDEF }; +static int st[2] = { SOCK_DGRAM, SOCK_DGRAM }; + void reset_count_dev_console(void) { count_dev_console = 0; + dt[0] = SH_LOG_INDEF; + dt[1] = SH_LOG_INDEF; + st[0] = SOCK_DGRAM; + st[1] = SOCK_DGRAM; + return; } @@ -283,6 +296,88 @@ char * sh_log_console_name (void) #define STDERR_FILENO 2 #endif +static int find_socktype(const char * name) +{ +#ifdef SOCK_SEQPACKET + int socktypes[3] = { SOCK_DGRAM, SOCK_SEQPACKET, SOCK_STREAM }; + int try = 3; +#else + int socktypes[2] = { SOCK_DGRAM, SOCK_STREAM }; + int try = 2; +#endif + int i; + for (i = 0; i < try; ++i) { + struct sockaddr_un addr; + int fd; + + if ( (fd = socket(AF_UNIX, socktypes[i], 0)) == -1) { + return -1; + } + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + sl_strlcpy(addr.sun_path, name, sizeof(addr.sun_path)); + if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) == 0) { + close(fd); + return socktypes[i]; + } + close(fd); + } + return -1; +} + +int sh_log_console_open (const char * name, int slot) +{ + int fd = -1; + + if (dt[slot] == SH_LOG_INDEF) + { + struct stat sb; + if (retry_stat(FIL__, __LINE__, name, &sb) == 0) + { + if ((sb.st_mode & S_IFMT) == S_IFSOCK) + { + dt[slot] = SH_LOG_UNIX; + st[slot] = find_socktype(name); + if (st[slot] == -1) { + sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_E_SUBGEN, + _("Could not determine socket type."), + name); + } + } + else + dt[slot] = SH_LOG_OTHER; + } + } + + if (dt[slot] == SH_LOG_OTHER) { + fd = open ( name, O_WRONLY|O_APPEND|O_NOCTTY|O_NONBLOCK); + } + else if (dt[slot] == SH_LOG_UNIX && st[slot] != -1) { + struct sockaddr_un addr; + + if ( (fd = socket(AF_UNIX, st[slot], 0)) == -1) { + char ebuf[SH_ERRBUF_SIZE]; + int errnum = errno; + sh_error_handle ((-1), FIL__, __LINE__, errnum, MSG_E_SUBGEN, + sh_error_message(errnum, ebuf, sizeof(ebuf)), + name); + return -1; + } + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + sl_strlcpy(addr.sun_path, name, sizeof(addr.sun_path)); + if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) { + char ebuf[SH_ERRBUF_SIZE]; + int errnum = errno; + sh_error_handle ((-1), FIL__, __LINE__, errnum, MSG_E_SUBGEN, + sh_error_message(errnum, ebuf, sizeof(ebuf)), + name); + return -1; + } + } + return fd; +} + /* ---- Print out a message. ---- */ int sh_log_console (const /*@null@*/char *errmsg) @@ -335,11 +430,11 @@ int sh_log_console (const /*@null@*/char *errmsg) */ if ( OnlyStderr == S_FALSE ) { - fd[0] = open ( sh.srvcons.name, O_WRONLY|O_APPEND|O_NOCTTY|O_NONBLOCK); + fd[0] = sh_log_console_open ( sh.srvcons.name, 0); if (sh.srvcons.alt[0] != '\0') { - fd[1] = open (sh.srvcons.alt, O_WRONLY|O_APPEND|O_NOCTTY|O_NONBLOCK); + fd[1] = sh_log_console_open (sh.srvcons.alt, 1); ccMax = 2; } @@ -360,9 +455,11 @@ int sh_log_console (const /*@null@*/char *errmsg) do { val_return = write(fd[cc], errmsg, strlen(errmsg)); } while (val_return < 0 && errno == EINTR); - do { - val_return = write(fd[cc], "\r\n", 2); - } while (val_return < 0 && errno == EINTR); + if (dt[cc] != SH_LOG_UNIX || st[cc] == SOCK_STREAM) { + do { + val_return = write(fd[cc], "\r\n", 2); + } while (val_return < 0 && errno == EINTR); + } (void) sl_close_fd(FIL__, __LINE__, fd[cc]); service_failure[cc] = 0; } |