[LWN Logo]

From: jafo-9804@tummy.com (Sean Reifschneider)
Subject: RFC: Syslog module bug-fix...
Date: 28 Apr 1998 23:18:12 -0600

Greetings.  Could some of you folks check out the patch for 1.5.1 I'm
including below?  Please mail success or failure reports and post
discussion on compatibility issues.

The documentation for syslog.openlog() states that specifying a facility
sets the default.  The syslog.syslog() documentation says that not
specifying a priority will cause the default of "(LOG_USER | LOG_INFO)"
to be used.  These two parts seem to be contradictory.

For example:

        openlog('testident', LOG_PID, LOG_LOCAL4)
        syslog('test message')

does *NOT* log a message to the local4 facility with the 1.5.1 release
module.

Also included are fixes for a small leak than can happen if
syslog.openlog() is called multiple times, some re-formatting of the
code, and docummentation/comment changes.

Thanks,
Sean
================
*** /usr/src/Python-1.5.1/Modules/syslogmodule.c        Mon Apr 27 14:17:49 1998
--- Python-1.5.1/Modules/syslogmodule.c Tue Apr 28 18:47:13 1998
***************
*** 26,31 ****
--- 26,37 ----
  
  Revision history:
  
+ 1998/04/28 (Sean Reifschneider)
+   - When facility not specified to syslog() method, use default from openlog()
+     (This is how it was claimed to work in the documentation)
+   - Potential resource leak of o_ident, now cleaned up in closelog()
+   - Minor comment accuracy fix.
+ 
  95/06/29 (Steve Clift)
    - Changed arg parsing to use PyArg_ParseTuple.
    - Added PyErr_Clear() call(s) where needed.
***************
*** 42,47 ****
--- 48,57 ----
  
  #include <syslog.h>
  
+ /*  only one instance, only one syslog, so globals should be ok  */
+ static PyObject *S_ident_o = NULL;                    /*  identifier, held by openlog()  */
+ 
+ 
  static PyObject * 
  syslog_openlog(self, args)
        PyObject * self;
***************
*** 50,69 ****
        long logopt = 0;
        long facility = LOG_USER;
  
-       static PyObject *ident_o = NULL;
  
!       Py_XDECREF(ident_o);
        if (!PyArg_ParseTuple(args,
                              "S|ll;ident string [, logoption [, facility]]",
!                             &ident_o, &logopt, &facility))
                return NULL;
  
        /* This is needed because openlog() does NOT make a copy
         * and syslog() later uses it.. cannot trash it.
         */
!       Py_INCREF(ident_o);
  
!       openlog(PyString_AsString(ident_o), logopt, facility);
  
        Py_INCREF(Py_None);
        return Py_None;
--- 60,78 ----
        long logopt = 0;
        long facility = LOG_USER;
  
  
!       Py_XDECREF(S_ident_o);
        if (!PyArg_ParseTuple(args,
                              "S|ll;ident string [, logoption [, facility]]",
!                             &S_ident_o, &logopt, &facility))
                return NULL;
  
        /* This is needed because openlog() does NOT make a copy
         * and syslog() later uses it.. cannot trash it.
         */
!       Py_INCREF(S_ident_o);
  
!       openlog(PyString_AsString(S_ident_o), logopt, facility);
  
        Py_INCREF(Py_None);
        return Py_None;
***************
*** 76,82 ****
        PyObject * args;
  {
        char *message;
!       int   priority = LOG_INFO | LOG_USER;
  
        if (!PyArg_ParseTuple(args, "is;[priority,] message string",
                              &priority, &message)) {
--- 85,91 ----
        PyObject * args;
  {
        char *message;
!       int   priority = LOG_INFO;
  
        if (!PyArg_ParseTuple(args, "is;[priority,] message string",
                              &priority, &message)) {
***************
*** 85,90 ****
--- 94,100 ----
                                      &message))
                        return NULL;
        }
+ 
        syslog(priority, "%s", message);
        Py_INCREF(Py_None);
        return Py_None;
***************
*** 98,103 ****
--- 108,115 ----
        if (!PyArg_ParseTuple(args, ""))
                return NULL;
        closelog();
+       Py_XDECREF(S_ident_o);
+       S_ident_o = NULL;
        Py_INCREF(Py_None);
        return Py_None;
  }
***************
*** 153,159 ****
        {NULL,          NULL,                   0}
  };
  
! /* Initialization function for the module */
  
  static void
  ins(d, s, x)
--- 165,171 ----
        {NULL,          NULL,                   0}
  };
  
! /* helper function for initialization function */
  
  static void
  ins(d, s, x)
***************
*** 168,173 ****
--- 180,186 ----
        }
  }
  
+ /* Initialization function for the module */
  
  void
  initsyslog()
***************
*** 205,229 ****
        ins(d, "LOG_MAIL",      LOG_MAIL);
        ins(d, "LOG_DAEMON",    LOG_DAEMON);
        ins(d, "LOG_AUTH",      LOG_AUTH);
! #ifdef LOG_SYSLOG
!       ins(d, "LOG_SYSLOG",    LOG_SYSLOG);
! #endif
!       ins(d, "LOG_LPR",       LOG_LPR);
! #ifdef LOG_NEWS
!       ins(d, "LOG_NEWS",      LOG_NEWS);
! #else
!       ins(d, "LOG_NEWS",      LOG_MAIL);
! #endif
! #ifdef LOG_UUCP
!       ins(d, "LOG_UUCP",      LOG_UUCP);
! #else
!       ins(d, "LOG_UUCP",      LOG_MAIL);
! #endif
! #ifdef LOG_CRON
!       ins(d, "LOG_CRON",      LOG_CRON);
! #else
!       ins(d, "LOG_CRON",      LOG_DAEMON);
! #endif
        ins(d, "LOG_LOCAL0",    LOG_LOCAL0);
        ins(d, "LOG_LOCAL1",    LOG_LOCAL1);
        ins(d, "LOG_LOCAL2",    LOG_LOCAL2);
--- 218,224 ----
        ins(d, "LOG_MAIL",      LOG_MAIL);
        ins(d, "LOG_DAEMON",    LOG_DAEMON);
        ins(d, "LOG_AUTH",      LOG_AUTH);
!       ins(d, "LOG_LPR",               LOG_LPR);
        ins(d, "LOG_LOCAL0",    LOG_LOCAL0);
        ins(d, "LOG_LOCAL1",    LOG_LOCAL1);
        ins(d, "LOG_LOCAL2",    LOG_LOCAL2);
***************
*** 232,237 ****
--- 227,250 ----
        ins(d, "LOG_LOCAL5",    LOG_LOCAL5);
        ins(d, "LOG_LOCAL6",    LOG_LOCAL6);
        ins(d, "LOG_LOCAL7",    LOG_LOCAL7);
+ 
+ #ifndef LOG_SYSLOG
+ #     define LOG_SYSLOG               LOG_DAEMON
+ #endif
+ #ifndef LOG_NEWS
+ #     define LOG_NEWS         LOG_MAIL
+ #endif
+ #ifndef LOG_UUCP
+ #     define LOG_UUCP         LOG_MAIL
+ #endif
+ #ifndef LOG_CRON
+ #     define LOG_CRON         LOG_DAEMON
+ #endif
+ 
+       ins(d, "LOG_SYSLOG",    LOG_SYSLOG);
+       ins(d, "LOG_CRON",      LOG_CRON);
+       ins(d, "LOG_UUCP",      LOG_UUCP);
+       ins(d, "LOG_NEWS",      LOG_NEWS);
  
        /* Check for errors */
        if (PyErr_Occurred())
*** /tmp/Python-1.5.1/Doc/libsyslog.tex Sat Apr  4 00:23:02 1998
--- Python-1.5.1/Doc/libsyslog.tex      Tue Apr 28 18:33:54 1998
***************
*** 15,21 ****
  Each message is tagged with a priority composed of a \var{facility} and
  a \var{level}.
  The optional \var{priority} argument, which defaults to
! \code{(LOG_USER | LOG_INFO)}, determines the message priority.
  \end{funcdesc}
  
  \begin{funcdesc}{openlog}{ident\optional{, logopt\optional{, facility}}}
--- 15,23 ----
  Each message is tagged with a priority composed of a \var{facility} and
  a \var{level}.
  The optional \var{priority} argument, which defaults to
! \code{LOG_INFO}, determines the message priority.  If the facility is
! not encoded in \var{priority} using logical-or (\code{LOG_INFO | LOG_USER}),
! the value given in the \code{openlog()} call is used.
  \end{funcdesc}
  
  \begin{funcdesc}{openlog}{ident\optional{, logopt\optional{, facility}}}
-- 
 "C'ptain, somebody replaced the Dilithium Crystals with FOLGER'S!"
                 -- Scotty (in Sean and Anne's demented minds)
Sean Reifschneider, Inimitably Superfluous <jafo-9804@tummy.com>
URL: <http://www.tummy.com/xvscan>; HP-UX/Linux/FreeBSD/BSDOS scanning software.