Back to index

glibc  2.9
Defines | Functions | Variables
syslog.c File Reference
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/syslog.h>
#include <sys/uio.h>
#include <sys/un.h>
#include <netdb.h>
#include <errno.h>
#include <fcntl.h>
#include <paths.h>
#include <stdio.h>
#include <stdio_ext.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <stdlib.h>
#include <bits/libc-lock.h>
#include <signal.h>
#include <locale.h>
#include <varargs.h>
#include <libio/iolibio.h>
#include <math_ldbl_opt.h>
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Defines

#define ftell(s)   INTUSE(_IO_ftell) (s)
#define send_flags   0
#define INTERNALLOG   LOG_ERR|LOG_CONS|LOG_PERROR|LOG_PID

Functions

 __libc_lock_define_initialized (static, syslog_lock)
static void cancel_handler (void *ptr)
void __syslog (int pri, const char *fmt,...)
 ldbl_hidden_def (ldbl_strong_alias(__syslog, syslog)
void __vsyslog_chk (int pri, int flag, const char *fmt, va_list ap)
 libc_hidden_def (__vsyslog_chk)
 ldbl_hidden_def (ldbl_strong_alias(__vsyslog, vsyslog)
void openlog (const char *ident, int logstat, int logfac)
static void sigpipe_handler (int signo)
static void closelog_internal ()
void closelog ()
int setlogmask (int pmask)

Variables

static int LogType = SOCK_DGRAM
static int LogFile = -1
static int connected
static int LogStat
static const char * LogTag
static int LogFacility = LOG_USER
static int LogMask = 0xff
char * __progname

Define Documentation

#define ftell (   s)    INTUSE(_IO_ftell) (s)

Definition at line 63 of file syslog.c.

#define send_flags   0

Function Documentation

__libc_lock_define_initialized ( static  ,
syslog_lock   
)

Definition at line 75 of file syslog.c.

{
  void *buf;
  struct sigaction *oldaction;
};
void __syslog ( int  pri,
const char *  fmt,
  ... 
)

Definition at line 114 of file syslog.c.

{
       va_list ap;

       va_start(ap, fmt);
       __vsyslog_chk(pri, -1, fmt, ap);
       va_end(ap);
}

Here is the call graph for this function:

void __vsyslog_chk ( int  pri,
int  flag,
const char *  fmt,
va_list  ap 
)

Definition at line 136 of file syslog.c.

{
       struct tm now_tm;
       time_t now;
       int fd;
       FILE *f;
       char *buf = 0;
       size_t bufsize = 0;
       size_t prioff, msgoff;
#ifndef NO_SIGPIPE
       struct sigaction action, oldaction;
       int sigpipe;
#endif
       int saved_errno = errno;
       char failbuf[3 * sizeof (pid_t) + sizeof "out of memory []"];

#define       INTERNALLOG   LOG_ERR|LOG_CONS|LOG_PERROR|LOG_PID
       /* Check for invalid bits. */
       if (pri & ~(LOG_PRIMASK|LOG_FACMASK)) {
              syslog(INTERNALLOG,
                  "syslog: unknown facility/priority: %x", pri);
              pri &= LOG_PRIMASK|LOG_FACMASK;
       }

       /* Check priority against setlogmask values. */
       if ((LOG_MASK (LOG_PRI (pri)) & LogMask) == 0)
              return;

       /* Set default facility if none specified. */
       if ((pri & LOG_FACMASK) == 0)
              pri |= LogFacility;

       /* Build the message in a memory-buffer stream.  */
       f = open_memstream (&buf, &bufsize);
       if (f == NULL)
         {
           /* We cannot get a stream.  There is not much we can do but
              emitting an error messages.  */
           char numbuf[3 * sizeof (pid_t)];
           char *nump;
           char *endp = __stpcpy (failbuf, "out of memory [");
           pid_t pid = __getpid ();

           nump = numbuf + sizeof (numbuf);
           /* The PID can never be zero.  */
           do
             *--nump = '0' + pid % 10;
           while ((pid /= 10) != 0);

           endp = __mempcpy (endp, nump, (numbuf + sizeof (numbuf)) - nump);
           *endp++ = ']';
           *endp = '\0';
           buf = failbuf;
           bufsize = endp - failbuf;
           msgoff = 0;
         }
       else
         {
           __fsetlocking (f, FSETLOCKING_BYCALLER);
           prioff = fprintf (f, "<%d>", pri);
           (void) time (&now);
           f->_IO_write_ptr += __strftime_l (f->_IO_write_ptr,
                                         f->_IO_write_end
                                         - f->_IO_write_ptr,
                                         "%h %e %T ",
                                         __localtime_r (&now, &now_tm),
                                         _nl_C_locobj_ptr);
           msgoff = ftell (f);
           if (LogTag == NULL)
             LogTag = __progname;
           if (LogTag != NULL)
             fputs_unlocked (LogTag, f);
           if (LogStat & LOG_PID)
             fprintf (f, "[%d]", (int) __getpid ());
           if (LogTag != NULL)
             {
              putc_unlocked (':', f);
              putc_unlocked (' ', f);
             }

           /* Restore errno for %m format.  */
           __set_errno (saved_errno);

           /* We have the header.  Print the user's format into the
               buffer.  */
           if (flag == -1)
             vfprintf (f, fmt, ap);
           else
             __vfprintf_chk (f, flag, fmt, ap);

           /* Close the memory stream; this will finalize the data
              into a malloc'd buffer in BUF.  */
           fclose (f);
         }

       /* Output to stderr if requested. */
       if (LogStat & LOG_PERROR) {
              struct iovec iov[2];
              register struct iovec *v = iov;

              v->iov_base = buf + msgoff;
              v->iov_len = bufsize - msgoff;
              /* Append a newline if necessary.  */
              if (buf[bufsize - 1] != '\n')
                {
                  ++v;
                  v->iov_base = (char *) "\n";
                  v->iov_len = 1;
                }

              __libc_cleanup_push (free, buf == failbuf ? NULL : buf);

              /* writev is a cancellation point.  */
              (void)__writev(STDERR_FILENO, iov, v - iov + 1);

              __libc_cleanup_pop (0);
       }

       /* Prepare for multiple users.  We have to take care: open and
          write are cancellation points.  */
       struct cleanup_arg clarg;
       clarg.buf = buf;
       clarg.oldaction = NULL;
       __libc_cleanup_push (cancel_handler, &clarg);
       __libc_lock_lock (syslog_lock);

#ifndef NO_SIGPIPE
       /* Prepare for a broken connection.  */
       memset (&action, 0, sizeof (action));
       action.sa_handler = sigpipe_handler;
       sigemptyset (&action.sa_mask);
       sigpipe = __sigaction (SIGPIPE, &action, &oldaction);
       if (sigpipe == 0)
         clarg.oldaction = &oldaction;
#endif

       /* Get connected, output the message to the local logger. */
       if (!connected)
              openlog_internal(LogTag, LogStat | LOG_NDELAY, 0);

       /* If we have a SOCK_STREAM connection, also send ASCII NUL as
          a record terminator.  */
       if (LogType == SOCK_STREAM)
         ++bufsize;

       if (!connected || __send(LogFile, buf, bufsize, send_flags) < 0)
         {
           if (connected)
             {
              /* Try to reopen the syslog connection.  Maybe it went
                 down.  */
              closelog_internal ();
              openlog_internal(LogTag, LogStat | LOG_NDELAY, 0);
             }

           if (!connected || __send(LogFile, buf, bufsize, send_flags) < 0)
             {
              closelog_internal ();       /* attempt re-open next time */
              /*
               * Output the message to the console; don't worry
               * about blocking, if console blocks everything will.
               * Make sure the error reported is the one from the
               * syslogd failure.
               */
              if (LogStat & LOG_CONS &&
                  (fd = __open(_PATH_CONSOLE, O_WRONLY|O_NOCTTY, 0)) >= 0)
                {
                  dprintf (fd, "%s\r\n", buf + msgoff);
                  (void)__close(fd);
                }
             }
         }

#ifndef NO_SIGPIPE
       if (sigpipe == 0)
              __sigaction (SIGPIPE, &oldaction, (struct sigaction *) NULL);
#endif

       /* End of critical section.  */
       __libc_cleanup_pop (0);
       __libc_lock_unlock (syslog_lock);

       if (buf != failbuf)
              free (buf);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void cancel_handler ( void *  ptr) [static]

Definition at line 94 of file syslog.c.

{
#ifndef NO_SIGPIPE
  /* Restore the old signal handler.  */
  struct cleanup_arg *clarg = (struct cleanup_arg *) ptr;

  if (clarg != NULL && clarg->oldaction != NULL)
    __sigaction (SIGPIPE, clarg->oldaction, NULL);
#endif

  /* Free the lock.  */
  __libc_lock_unlock (syslog_lock);
}

Here is the caller graph for this function:

void closelog ( void  )

Definition at line 441 of file syslog.c.

{
  /* Protect against multiple users and cancellation.  */
  __libc_cleanup_push (cancel_handler, NULL);
  __libc_lock_lock (syslog_lock);

  closelog_internal ();
  LogTag = NULL;
  LogType = SOCK_DGRAM; /* this is the default */

  /* Free the lock.  */
  __libc_cleanup_pop (1);
}

Here is the call graph for this function:

static void closelog_internal ( ) [static]

Definition at line 430 of file syslog.c.

{
  if (!connected)
    return;

  __close (LogFile);
  LogFile = -1;
  connected = 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

ldbl_hidden_def ( ldbl_strong_alias __syslog,
syslog   
)

Definition at line 122 of file syslog.c.

{
       va_list ap;

       va_start(ap, fmt);
       __vsyslog_chk(pri, flag, fmt, ap);
       va_end(ap);
}

Here is the call graph for this function:

ldbl_hidden_def ( ldbl_strong_alias __vsyslog,
vsyslog   
)

Definition at line 328 of file syslog.c.

{
       if (ident != NULL)
              LogTag = ident;
       LogStat = logstat;
       if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0)
              LogFacility = logfac;

       int retry = 0;
       while (retry < 2) {
              if (LogFile == -1) {
                     SyslogAddr.sun_family = AF_UNIX;
                     (void)strncpy(SyslogAddr.sun_path, _PATH_LOG,
                                  sizeof(SyslogAddr.sun_path));
                     if (LogStat & LOG_NDELAY) {
#ifdef SOCK_CLOEXEC
# ifndef __ASSUME_SOCK_CLOEXEC
                            if (__have_sock_cloexec >= 0) {
# endif
                                   LogFile = __socket(AF_UNIX,
                                                    LogType
                                                    | SOCK_CLOEXEC, 0);
# ifndef __ASSUME_SOCK_CLOEXEC
                                   if (__have_sock_cloexec == 0)
                                          __have_sock_cloexec
                                            = ((LogFile != -1
                                                || errno != EINVAL)
                                               ? 1 : -1);
                            }
# endif
#endif
#ifndef __ASSUME_SOCK_CLOEXEC
# ifdef SOCK_CLOEXEC
                            if (__have_sock_cloexec < 0)
# endif
                              LogFile = __socket(AF_UNIX, LogType, 0);
#endif
                            if (LogFile == -1)
                                   return;
#ifndef __ASSUME_SOCK_CLOEXEC
# ifdef SOCK_CLOEXEC
                            if (__have_sock_cloexec < 0)
# endif
                                   __fcntl(LogFile, F_SETFD, FD_CLOEXEC);
#endif
                     }
              }
              if (LogFile != -1 && !connected)
              {
                     int old_errno = errno;
                     if (__connect(LogFile, &SyslogAddr, sizeof(SyslogAddr))
                         == -1)
                     {
                            int saved_errno = errno;
                            int fd = LogFile;
                            LogFile = -1;
                            (void)__close(fd);
                            __set_errno (old_errno);
                            if (saved_errno == EPROTOTYPE)
                            {
                                   /* retry with the other type: */
                                   LogType = (LogType == SOCK_DGRAM
                                             ? SOCK_STREAM : SOCK_DGRAM);
                                   ++retry;
                                   continue;
                            }
                     } else
                            connected = 1;
              }
              break;
       }
}

Here is the call graph for this function:

Definition at line 321 of file syslog.c.

{
  __vsyslog_chk (pri, -1, fmt, ap);
}

Here is the call graph for this function:

void openlog ( const char *  ident,
int  logstat,
int  logfac 
)

Definition at line 410 of file syslog.c.

{
  /* Protect against multiple users and cancellation.  */
  __libc_cleanup_push (cancel_handler, NULL);
  __libc_lock_lock (syslog_lock);

  openlog_internal (ident, logstat, logfac);

  __libc_cleanup_pop (1);
}

Here is the call graph for this function:

int setlogmask ( int  pmask)

Definition at line 457 of file syslog.c.

{
       int omask;

       omask = LogMask;
       if (pmask != 0)
              LogMask = pmask;
       return (omask);
}
static void sigpipe_handler ( int  signo) [static]

Definition at line 423 of file syslog.c.

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

char* __progname

Definition at line 24 of file init-misc.c.

int connected [static]

Definition at line 67 of file syslog.c.

int LogFacility = LOG_USER [static]

Definition at line 70 of file syslog.c.

int LogFile = -1 [static]

Definition at line 66 of file syslog.c.

int LogMask = 0xff [static]

Definition at line 71 of file syslog.c.

int LogStat [static]

Definition at line 68 of file syslog.c.

const char* LogTag [static]

Definition at line 69 of file syslog.c.

int LogType = SOCK_DGRAM [static]

Definition at line 65 of file syslog.c.