mirror of
https://sourceware.org/git/glibc.git
synced 2025-08-08 17:42:12 +03:00
misc: syslog: Simplify implementation
Use a temporary buffer for strftime instead of using internal libio members, simplify fprintf call on the memstream and memory allocation, use %b instead of %h, use dprintf instead of writev for LOG_PERROR. Checked on x86_64-linux-gnu and i686-linux-gnu.
This commit is contained in:
@@ -42,8 +42,6 @@ static char sccsid[] = "@(#)syslog.c 8.4 (Berkeley) 3/18/94";
|
|||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
|
|
||||||
#define ftell(s) _IO_ftell (s)
|
|
||||||
|
|
||||||
static int LogType = SOCK_DGRAM; /* type of socket connection */
|
static int LogType = SOCK_DGRAM; /* type of socket connection */
|
||||||
static int LogFile = -1; /* fd for log */
|
static int LogFile = -1; /* fd for log */
|
||||||
static bool connected; /* have done connect */
|
static bool connected; /* have done connect */
|
||||||
@@ -122,13 +120,10 @@ void
|
|||||||
__vsyslog_internal (int pri, const char *fmt, va_list ap,
|
__vsyslog_internal (int pri, const char *fmt, va_list ap,
|
||||||
unsigned int mode_flags)
|
unsigned int mode_flags)
|
||||||
{
|
{
|
||||||
struct tm now_tm;
|
|
||||||
time_t now;
|
|
||||||
int fd;
|
|
||||||
FILE *f;
|
FILE *f;
|
||||||
char *buf = 0;
|
char *buf = 0;
|
||||||
size_t bufsize = 0;
|
size_t bufsize = 0;
|
||||||
size_t msgoff;
|
int msgoff;
|
||||||
int saved_errno = errno;
|
int saved_errno = errno;
|
||||||
char failbuf[3 * sizeof (pid_t) + sizeof "out of memory []"];
|
char failbuf[3 * sizeof (pid_t) + sizeof "out of memory []"];
|
||||||
|
|
||||||
@@ -142,9 +137,7 @@ __vsyslog_internal (int pri, const char *fmt, va_list ap,
|
|||||||
|
|
||||||
/* Prepare for multiple users. We have to take care: most syscalls we are
|
/* Prepare for multiple users. We have to take care: most syscalls we are
|
||||||
using are cancellation points. */
|
using are cancellation points. */
|
||||||
struct cleanup_arg clarg;
|
struct cleanup_arg clarg = { NULL, NULL };
|
||||||
clarg.buf = NULL;
|
|
||||||
clarg.oldaction = NULL;
|
|
||||||
__libc_cleanup_push (cancel_handler, &clarg);
|
__libc_cleanup_push (cancel_handler, &clarg);
|
||||||
__libc_lock_lock (syslog_lock);
|
__libc_lock_lock (syslog_lock);
|
||||||
|
|
||||||
@@ -158,51 +151,22 @@ __vsyslog_internal (int pri, const char *fmt, va_list ap,
|
|||||||
|
|
||||||
/* Build the message in a memory-buffer stream. */
|
/* Build the message in a memory-buffer stream. */
|
||||||
f = __open_memstream (&buf, &bufsize);
|
f = __open_memstream (&buf, &bufsize);
|
||||||
if (f == NULL)
|
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);
|
__fsetlocking (f, FSETLOCKING_BYCALLER);
|
||||||
fprintf (f, "<%d>", pri);
|
/* "%b %e %H:%M:%S" */
|
||||||
now = time_now ();
|
char timebuf[sizeof "MMM DD hh:mm:ss "];
|
||||||
f->_IO_write_ptr += __strftime_l (f->_IO_write_ptr,
|
time_t now = time_now ();
|
||||||
f->_IO_write_end - f->_IO_write_ptr,
|
struct tm now_tm;
|
||||||
"%h %e %T ",
|
__localtime_r (&now, &now_tm);
|
||||||
__localtime_r (&now, &now_tm),
|
__strftime_l (timebuf, sizeof (timebuf), "%b %e %T", &now_tm,
|
||||||
_nl_C_locobj_ptr);
|
_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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
pid_t pid = LogStat & LOG_PID ? __getpid () : 0;
|
||||||
|
|
||||||
|
fprintf (f, "<%d>%s %n%s%s%.0d%s: ", pri, timebuf, &msgoff,
|
||||||
|
LogTag == NULL ? __progname : LogTag,
|
||||||
|
pid != 0 ? "[" : "", pid, pid != 0 ? "]" : "");
|
||||||
/* Restore errno for %m format. */
|
/* Restore errno for %m format. */
|
||||||
__set_errno (saved_errno);
|
__set_errno (saved_errno);
|
||||||
|
|
||||||
@@ -216,26 +180,18 @@ __vsyslog_internal (int pri, const char *fmt, va_list ap,
|
|||||||
/* Tell the cancellation handler to free this buffer. */
|
/* Tell the cancellation handler to free this buffer. */
|
||||||
clarg.buf = buf;
|
clarg.buf = buf;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Nothing much to do but emit an error message. */
|
||||||
|
bufsize = __snprintf (failbuf, sizeof failbuf, "out of memory[%d]",
|
||||||
|
__getpid ());
|
||||||
|
buf = failbuf;
|
||||||
|
}
|
||||||
|
|
||||||
/* Output to stderr if requested. */
|
/* Output to stderr if requested. */
|
||||||
if (LogStat & LOG_PERROR)
|
if (LogStat & LOG_PERROR)
|
||||||
{
|
__dprintf (STDERR_FILENO, "%s%s", buf + msgoff,
|
||||||
struct iovec iov[2];
|
"\n" + (buf[bufsize - 1] == '\n'));
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* writev is a cancellation point. */
|
|
||||||
__writev (STDERR_FILENO, iov, v - iov + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get connected, output the message to the local logger. */
|
/* Get connected, output the message to the local logger. */
|
||||||
if (!connected)
|
if (!connected)
|
||||||
@@ -264,6 +220,7 @@ __vsyslog_internal (int pri, const char *fmt, va_list ap,
|
|||||||
* Make sure the error reported is the one from the
|
* Make sure the error reported is the one from the
|
||||||
* syslogd failure.
|
* syslogd failure.
|
||||||
*/
|
*/
|
||||||
|
int fd;
|
||||||
if (LogStat & LOG_CONS &&
|
if (LogStat & LOG_CONS &&
|
||||||
(fd = __open (_PATH_CONSOLE, O_WRONLY | O_NOCTTY
|
(fd = __open (_PATH_CONSOLE, O_WRONLY | O_NOCTTY
|
||||||
| O_CLOEXEC, 0)) >= 0)
|
| O_CLOEXEC, 0)) >= 0)
|
||||||
|
Reference in New Issue
Block a user