syslog(3): unbreak log generation using fabricated PID
Recover application ability to supply fabricated PID embedded into ident that was lost when libc switched to generation of RFC 5424 log messages, for example: logger -t "ident[$$]" -p user.notice "test" It is essential for long running scripts. Also, this change unbreaks matching resulted entries by ident in syslog.conf: !ident *.* /var/log/ident.log Without the fix, the log (and matching) was broken: Aug 1 07:36:58 hostname ident[123][86483]: test Now it works as expected and worked before breakage: Aug 1 07:39:40 hostname ident[123]: test Differential: https://reviews.freebsd.org/D36005 MFC after: 2 weeks
This commit is contained in:
parent
e87ff1ea22
commit
e9ae9fa937
@ -65,7 +65,9 @@ static int LogFile = -1; /* fd for log */
|
||||
static bool connected; /* have done connect */
|
||||
static int opened; /* have done openlog() */
|
||||
static int LogStat = 0; /* status bits, set by openlog() */
|
||||
static pid_t LogPid = -1; /* process id to tag the entry with */
|
||||
static const char *LogTag = NULL; /* string to tag the entry with */
|
||||
static int LogTagLength = -1; /* usable part of LogTag */
|
||||
static int LogFacility = LOG_USER; /* default facility code */
|
||||
static int LogMask = 0xff; /* mask of priorities to be logged */
|
||||
static pthread_mutex_t syslog_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
@ -85,6 +87,7 @@ static pthread_mutex_t syslog_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static void disconnectlog(void); /* disconnect from syslogd */
|
||||
static void connectlog(void); /* (re)connect to syslogd */
|
||||
static void openlog_unlocked(const char *, int, int);
|
||||
static void parse_tag(void); /* parse ident[NNN] if needed */
|
||||
|
||||
/*
|
||||
* Format of the magic cookie passed through the stdio hook
|
||||
@ -204,13 +207,20 @@ vsyslog1(int pri, const char *fmt, va_list ap)
|
||||
/* Application name. */
|
||||
if (LogTag == NULL)
|
||||
LogTag = _getprogname();
|
||||
(void)fprintf(fp, "%s ", LogTag == NULL ? NILVALUE : LogTag);
|
||||
else if (LogTagLength == -1)
|
||||
parse_tag();
|
||||
if (LogTagLength > 0)
|
||||
(void)fprintf(fp, "%.*s ", LogTagLength, LogTag);
|
||||
else
|
||||
(void)fprintf(fp, "%s ", LogTag == NULL ? NILVALUE : LogTag);
|
||||
/*
|
||||
* Provide the process ID regardless of whether LOG_PID has been
|
||||
* specified, as it provides valuable information. Many
|
||||
* applications tend not to use this, even though they should.
|
||||
*/
|
||||
(void)fprintf(fp, "%d ", getpid());
|
||||
if (LogPid == -1)
|
||||
LogPid = getpid();
|
||||
(void)fprintf(fp, "%d ", (int)LogPid);
|
||||
/* Message ID. */
|
||||
(void)fputs(NILVALUE " ", fp);
|
||||
/* Structured data. */
|
||||
@ -398,9 +408,12 @@ connectlog(void)
|
||||
static void
|
||||
openlog_unlocked(const char *ident, int logstat, int logfac)
|
||||
{
|
||||
if (ident != NULL)
|
||||
if (ident != NULL) {
|
||||
LogTag = ident;
|
||||
LogTagLength = -1;
|
||||
}
|
||||
LogStat = logstat;
|
||||
parse_tag();
|
||||
if (logfac != 0 && (logfac &~ LOG_FACMASK) == 0)
|
||||
LogFacility = logfac;
|
||||
|
||||
@ -430,6 +443,7 @@ closelog(void)
|
||||
LogFile = -1;
|
||||
}
|
||||
LogTag = NULL;
|
||||
LogTagLength = -1;
|
||||
connected = false;
|
||||
THREAD_UNLOCK();
|
||||
}
|
||||
@ -447,3 +461,37 @@ setlogmask(int pmask)
|
||||
THREAD_UNLOCK();
|
||||
return (omask);
|
||||
}
|
||||
|
||||
/*
|
||||
* Obtain LogPid from LogTag formatted as following: ident[NNN]
|
||||
*/
|
||||
static void
|
||||
parse_tag(void)
|
||||
{
|
||||
char *begin, *end, *p;
|
||||
pid_t pid;
|
||||
|
||||
if (LogTag == NULL || (LogStat & LOG_PID) != 0)
|
||||
return;
|
||||
/*
|
||||
* LogTagLength is -1 if LogTag was not parsed yet.
|
||||
* Avoid multiple passes over same LogTag.
|
||||
*/
|
||||
LogTagLength = 0;
|
||||
|
||||
/* Check for presence of opening [ and non-empty ident. */
|
||||
if ((begin = strchr(LogTag, '[')) == NULL || begin == LogTag)
|
||||
return;
|
||||
/* Check for presence of closing ] at the very end and non-empty pid. */
|
||||
if ((end = strchr(begin + 1, ']')) == NULL || end[1] != 0 ||
|
||||
(end - begin) < 2)
|
||||
return;
|
||||
|
||||
/* Check for pid to contain digits only. */
|
||||
pid = (pid_t)strtol(begin + 1, &p, 10);
|
||||
if (p != end)
|
||||
return;
|
||||
|
||||
LogPid = pid;
|
||||
LogTagLength = begin - LogTag;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user