Ignore:
Timestamp:
Oct 31, 2020, 11:39:37 PM (4 years ago)
Author:
katerina
Message:

Fix for ticket #448 (logging to unix domain socket).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/sh_err_console.c

    r541 r559  
    3333#include <sys/types.h>
    3434#include <fcntl.h>
     35#include <sys/stat.h>
    3536#include <unistd.h>
    3637#include <signal.h>
     38#include <sys/socket.h>
     39#include <sys/un.h>
    3740
    3841extern int  OnlyStderr;
     
    245248static int count_dev_console = 0;
    246249
     250typedef enum { SH_LOG_UNIX, SH_LOG_OTHER, SH_LOG_INDEF } sh_log_devtype;
     251
     252static sh_log_devtype dt[2] = { SH_LOG_INDEF, SH_LOG_INDEF };
     253static int            st[2] = { SOCK_DGRAM, SOCK_DGRAM };
     254
    247255void reset_count_dev_console(void)
    248256{
    249257  count_dev_console = 0;
     258  dt[0] = SH_LOG_INDEF;
     259  dt[1] = SH_LOG_INDEF;
     260  st[0] = SOCK_DGRAM;
     261  st[1] = SOCK_DGRAM;
     262 
    250263  return;
    251264}
     
    283296#define STDERR_FILENO   2
    284297#endif
     298
     299static int  find_socktype(const char * name)
     300{
     301#ifdef SOCK_SEQPACKET
     302    int socktypes[3] = { SOCK_DGRAM, SOCK_SEQPACKET, SOCK_STREAM };
     303    int try = 3;
     304#else
     305    int socktypes[2] = { SOCK_DGRAM, SOCK_STREAM };
     306    int try = 2;
     307#endif
     308    int i;
     309    for (i = 0; i < try; ++i) {
     310        struct sockaddr_un addr;
     311        int fd;
     312   
     313        if ( (fd = socket(AF_UNIX, socktypes[i], 0)) == -1) {
     314            return -1;
     315        }
     316        memset(&addr, 0, sizeof(addr));
     317        addr.sun_family = AF_UNIX;
     318        sl_strlcpy(addr.sun_path, name, sizeof(addr.sun_path));
     319        if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) == 0) {
     320            close(fd);
     321            return socktypes[i];
     322        }
     323        close(fd);
     324    }
     325    return -1;
     326}
     327
     328int sh_log_console_open (const char * name, int slot)
     329{
     330  int fd = -1;
     331
     332  if (dt[slot] == SH_LOG_INDEF)
     333    {
     334      struct stat sb;
     335      if (retry_stat(FIL__, __LINE__, name, &sb) == 0)
     336        {
     337          if ((sb.st_mode & S_IFMT) == S_IFSOCK)
     338            {
     339              dt[slot] = SH_LOG_UNIX;
     340              st[slot] = find_socktype(name);
     341              if (st[slot] == -1) {
     342                sh_error_handle ((-1), FIL__, __LINE__, 0, MSG_E_SUBGEN,
     343                   _("Could not determine socket type."), 
     344                   name);
     345              }
     346            }
     347          else
     348            dt[slot] = SH_LOG_OTHER;
     349        }
     350    }
     351     
     352  if (dt[slot] == SH_LOG_OTHER) {
     353    fd = open ( name, O_WRONLY|O_APPEND|O_NOCTTY|O_NONBLOCK);
     354  }
     355  else if (dt[slot] == SH_LOG_UNIX && st[slot] != -1) {
     356    struct sockaddr_un addr;
     357   
     358    if ( (fd = socket(AF_UNIX, st[slot], 0)) == -1) {
     359          char ebuf[SH_ERRBUF_SIZE];
     360          int  errnum = errno;
     361          sh_error_handle ((-1), FIL__, __LINE__, errnum, MSG_E_SUBGEN,
     362            sh_error_message(errnum, ebuf, sizeof(ebuf)), 
     363            name);
     364      return -1;
     365    }
     366    memset(&addr, 0, sizeof(addr));
     367    addr.sun_family = AF_UNIX;
     368    sl_strlcpy(addr.sun_path, name, sizeof(addr.sun_path));
     369    if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
     370          char ebuf[SH_ERRBUF_SIZE];
     371          int  errnum = errno;
     372          sh_error_handle ((-1), FIL__, __LINE__, errnum, MSG_E_SUBGEN,
     373            sh_error_message(errnum, ebuf, sizeof(ebuf)),
     374            name);
     375      return -1;
     376    }
     377  }
     378  return fd;
     379}
    285380
    286381/* ---- Print out a message. ----
     
    336431  if ( OnlyStderr == S_FALSE )
    337432    {
    338       fd[0] = open ( sh.srvcons.name, O_WRONLY|O_APPEND|O_NOCTTY|O_NONBLOCK);
     433      fd[0] = sh_log_console_open ( sh.srvcons.name, 0);
    339434
    340435      if (sh.srvcons.alt[0] != '\0')
    341436        {
    342           fd[1] = open (sh.srvcons.alt, O_WRONLY|O_APPEND|O_NOCTTY|O_NONBLOCK);
     437          fd[1] = sh_log_console_open (sh.srvcons.alt, 1);
    343438          ccMax = 2;
    344439        }
     
    361456                val_return = write(fd[cc], errmsg, strlen(errmsg));
    362457              } while (val_return < 0 && errno == EINTR);
    363               do {
    364                 val_return = write(fd[cc], "\r\n",              2);
    365               } while (val_return < 0 && errno == EINTR);
     458              if (dt[cc] != SH_LOG_UNIX || st[cc] == SOCK_STREAM) {
     459                do {
     460                  val_return = write(fd[cc], "\r\n",              2);
     461                } while (val_return < 0 && errno == EINTR);
     462              }
    366463              (void) sl_close_fd(FIL__, __LINE__, fd[cc]);
    367464              service_failure[cc] = 0;
Note: See TracChangeset for help on using the changeset viewer.