From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
To: libc-alpha@sourceware.org
Subject: [PATCH 5/7] misc: syslog: Use static buffer
Date: Tue, 5 Oct 2021 10:56:29 -0300 [thread overview]
Message-ID: <20211005135631.3209020-6-adhemerval.zanella@linaro.org> (raw)
In-Reply-To: <20211005135631.3209020-1-adhemerval.zanella@linaro.org>
The static buffer is used instead of memstream for messages up to
1024 bytes to avoid the potential BUFSIZ (8K) malloc and free for
each syslog call. The memstream is still used as fallback for
larger messages.
Checked on x86_64-linux-gnu.
---
misc/syslog.c | 105 ++++++++++++++++++++++++++++++++------------------
1 file changed, 68 insertions(+), 37 deletions(-)
diff --git a/misc/syslog.c b/misc/syslog.c
index 8365e16128..99fa595b40 100644
--- a/misc/syslog.c
+++ b/misc/syslog.c
@@ -121,12 +121,11 @@ void
__vsyslog_internal(int pri, const char *fmt, va_list ap,
unsigned int mode_flags)
{
- FILE *f;
- char *buf = 0;
+ char *buf = NULL;
size_t bufsize = 0;
+ bool buf_malloced = false;
int msgoff;
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. */
@@ -150,46 +149,78 @@ __vsyslog_internal(int pri, const char *fmt, va_list ap,
if ((pri & LOG_FACMASK) == 0)
pri |= LogFacility;
- /* Build the message in a memory-buffer stream. */
- f = __open_memstream (&buf, &bufsize);
- if (f != NULL)
+ pid_t pid = LogStat & LOG_PID ? __getpid () : 0;
+
+ enum
+ {
+ timebuf_size = 3+1 /* "%h " */
+ + 2+1 /* "%e " */
+ + 2+1 + 2+1 + 2+1 + 1, /* "%T " */
+
+ bufs_size = 1024
+ };
+
+ /* "%h %e %H:%M:%S " */
+ char timestamp[timebuf_size];
+ time_t now = time_now ();
+ struct tm now_tm;
+ __localtime_r (&now, &now_tm);
+ __strftime_l (timestamp, sizeof (timestamp), "%h %e %T ", &now_tm,
+ _nl_C_locobj_ptr);
+
+#define SYSLOG_HEADER(__pri, __timestamp, __msgoff, pid) \
+ "<%d>%s %n%s%s%.0d%s: ", \
+ __pri, __timestamp, __msgoff, \
+ LogTag == NULL ? __progname : LogTag, \
+ pid != 0 ? "[" : "", pid, pid != 0 ? "]" : ""
+
+ /* Try to use a static buffer as an optimization. */
+ char bufs[bufs_size];
+ int l = __snprintf (bufs, sizeof bufs,
+ SYSLOG_HEADER (pri, timestamp, &msgoff, pid));
+ if (l < sizeof (bufs))
{
- __fsetlocking (f, FSETLOCKING_BYCALLER);
- /* "%h %e %H:%M:%S " */
- char timebuf[3+1 /* "%h " */
- + 2+1 /* "%e " */
- + 2+1 + 2+1 + 2+1 + 1 /* "%T " */];
- time_t now = time_now ();
- struct tm now_tm;
- __localtime_r (&now, &now_tm);
- __strftime_l (timebuf, sizeof (timebuf), "%h %e %T ", &now_tm,
- _nl_C_locobj_ptr);
-
- 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 ? "]" : "");
+ va_list apc;
+ va_copy (apc, ap);
+
/* Restore errno for %m format. */
__set_errno (saved_errno);
- /* We have the header. Print the user's format into the buffer. */
- __vfprintf_internal (f, fmt, ap, mode_flags);
+ int vl = __vsnprintf_internal (bufs + l, sizeof (bufs) - l, fmt, apc,
+ mode_flags);
+ if (l + vl < sizeof (bufs))
+ {
+ buf = bufs;
+ bufsize = l + vl;
+ }
- /* Close the memory stream; this will finalize the data into a malloc'd
- buffer in BUF. */
- fclose (f);
-
- /* Tell the cancellation handler to free this buffer. */
- clarg.buf = buf;
+ va_end (apc);
}
- else
+
+ /* If the required size is larger than buffer size fallbacks to
+ open_memstream. */
+ if (buf == NULL)
{
- /* We cannot get a stream. There is not much we can do but emitting an
- error messages. */
- bufsize = __snprintf (failbuf, sizeof failbuf, "out of memory[%d]",
- __getpid ());
- buf = failbuf;
+ FILE *f = __open_memstream (&buf, &bufsize);
+ if (f != NULL)
+ {
+ __fsetlocking (f, FSETLOCKING_BYCALLER);
+ fprintf (f, SYSLOG_HEADER (pri, timestamp, &msgoff, pid));
+ /* Restore errno for %m format. */
+ __set_errno (saved_errno);
+ __vfprintf_internal (f, fmt, ap, mode_flags);
+ fclose (f);
+
+ /* Tell the cancellation handler to free this buffer. */
+ buf_malloced = true;
+ clarg.buf = buf;
+ }
+ else
+ {
+ bufsize = __snprintf (bufs, sizeof bufs,
+ "out of memory[%d]", __getpid ());
+ buf = bufs;
+ }
}
/* Output to stderr if requested. */
@@ -241,7 +272,7 @@ __vsyslog_internal(int pri, const char *fmt, va_list ap,
__libc_cleanup_pop (0);
__libc_lock_unlock (syslog_lock);
- if (buf != failbuf)
+ if (buf_malloced)
free (buf);
}
--
2.30.2
next prev parent reply other threads:[~2021-10-05 13:56 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-10-05 13:56 [PATCH 0/7] Use RFC5424 for syslog Adhemerval Zanella
2021-10-05 13:56 ` [PATCH 1/7] support: Add xmkfifo Adhemerval Zanella
2021-10-05 19:10 ` Florian Weimer
2021-10-06 19:25 ` Adhemerval Zanella
2021-10-05 13:56 ` [PATCH 2/7] misc: Add syslog test Adhemerval Zanella
2021-10-05 13:56 ` [PATCH 3/7] misc: syslog: Fix indentation and style Adhemerval Zanella
2021-10-05 13:56 ` [PATCH 4/7] misc: syslog: Simplify implementation Adhemerval Zanella
2021-10-05 13:56 ` Adhemerval Zanella [this message]
2021-10-05 13:56 ` [PATCH 6/7] misc: syslog: Move SYSLOG_NAME to USE_MISC (BZ #16355) Adhemerval Zanella
2021-10-05 13:56 ` [PATCH 7/7] misc: syslog: Use RFC5424 Adhemerval Zanella
2021-10-05 19:07 ` Paul Eggert
2021-10-06 19:36 ` Adhemerval Zanella
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20211005135631.3209020-6-adhemerval.zanella@linaro.org \
--to=adhemerval.zanella@linaro.org \
--cc=libc-alpha@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).