Merge pull request #15052 from jaankit/journal-send
journal-send: Fix the limitation of LINE_MAX
This commit is contained in:
commit
214ffe64fc
|
@ -15,6 +15,7 @@
|
||||||
#include "errno-util.h"
|
#include "errno-util.h"
|
||||||
#include "fd-util.h"
|
#include "fd-util.h"
|
||||||
#include "io-util.h"
|
#include "io-util.h"
|
||||||
|
#include "fileio.h"
|
||||||
#include "memfd-util.h"
|
#include "memfd-util.h"
|
||||||
#include "socket-util.h"
|
#include "socket-util.h"
|
||||||
#include "stdio-util.h"
|
#include "stdio-util.h"
|
||||||
|
@ -73,12 +74,12 @@ _public_ int sd_journal_print(int priority, const char *format, ...) {
|
||||||
}
|
}
|
||||||
|
|
||||||
_public_ int sd_journal_printv(int priority, const char *format, va_list ap) {
|
_public_ int sd_journal_printv(int priority, const char *format, va_list ap) {
|
||||||
|
char p[STRLEN("PRIORITY=") + DECIMAL_STR_MAX(int) + 1];
|
||||||
/* FIXME: Instead of limiting things to LINE_MAX we could do a
|
char sbuf[LINE_MAX + 8] = "MESSAGE=";
|
||||||
C99 variable-length array on the stack here in a loop. */
|
|
||||||
|
|
||||||
char buffer[8 + LINE_MAX], p[STRLEN("PRIORITY=") + DECIMAL_STR_MAX(int) + 1];
|
|
||||||
struct iovec iov[2];
|
struct iovec iov[2];
|
||||||
|
int len;
|
||||||
|
va_list aq;
|
||||||
|
char *buffer = sbuf;
|
||||||
|
|
||||||
assert_return(priority >= 0, -EINVAL);
|
assert_return(priority >= 0, -EINVAL);
|
||||||
assert_return(priority <= 7, -EINVAL);
|
assert_return(priority <= 7, -EINVAL);
|
||||||
|
@ -86,14 +87,27 @@ _public_ int sd_journal_printv(int priority, const char *format, va_list ap) {
|
||||||
|
|
||||||
xsprintf(p, "PRIORITY=%i", priority & LOG_PRIMASK);
|
xsprintf(p, "PRIORITY=%i", priority & LOG_PRIMASK);
|
||||||
|
|
||||||
memcpy(buffer, "MESSAGE=", 8);
|
va_copy(aq, ap);
|
||||||
vsnprintf(buffer+8, sizeof(buffer) - 8, format, ap);
|
len = vsnprintf(buffer + 8, LINE_MAX, format, aq);
|
||||||
|
va_end(aq);
|
||||||
|
|
||||||
|
if (len >= (int)LONG_LINE_MAX - 8)
|
||||||
|
return -ENOBUFS;
|
||||||
|
|
||||||
|
/* Allocate large buffer to accomodate big message */
|
||||||
|
if (len >= LINE_MAX) {
|
||||||
|
int rlen;
|
||||||
|
buffer = alloca(len + 9);
|
||||||
|
memcpy(buffer, "MESSAGE=", 8);
|
||||||
|
rlen = vsnprintf(buffer + 8, len + 1, format, ap);
|
||||||
|
assert(len == rlen);
|
||||||
|
}
|
||||||
|
|
||||||
/* Strip trailing whitespace, keep prefix whitespace. */
|
/* Strip trailing whitespace, keep prefix whitespace. */
|
||||||
(void) strstrip(buffer);
|
(void) strstrip(buffer);
|
||||||
|
|
||||||
/* Suppress empty lines */
|
/* Suppress empty lines */
|
||||||
if (isempty(buffer+8))
|
if (isempty(buffer + 8))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
iov[0] = IOVEC_MAKE_STRING(buffer);
|
iov[0] = IOVEC_MAKE_STRING(buffer);
|
||||||
|
@ -437,9 +451,13 @@ _public_ int sd_journal_print_with_location(int priority, const char *file, cons
|
||||||
}
|
}
|
||||||
|
|
||||||
_public_ int sd_journal_printv_with_location(int priority, const char *file, const char *line, const char *func, const char *format, va_list ap) {
|
_public_ int sd_journal_printv_with_location(int priority, const char *file, const char *line, const char *func, const char *format, va_list ap) {
|
||||||
char buffer[8 + LINE_MAX], p[STRLEN("PRIORITY=") + DECIMAL_STR_MAX(int) + 1];
|
char p[STRLEN("PRIORITY=") + DECIMAL_STR_MAX(int) + 1];
|
||||||
|
char sbuf[LINE_MAX + 8] = "MESSAGE=";
|
||||||
struct iovec iov[5];
|
struct iovec iov[5];
|
||||||
char *f;
|
char *f;
|
||||||
|
int len;
|
||||||
|
char *buffer = sbuf;
|
||||||
|
va_list aq;
|
||||||
|
|
||||||
assert_return(priority >= 0, -EINVAL);
|
assert_return(priority >= 0, -EINVAL);
|
||||||
assert_return(priority <= 7, -EINVAL);
|
assert_return(priority <= 7, -EINVAL);
|
||||||
|
@ -447,14 +465,27 @@ _public_ int sd_journal_printv_with_location(int priority, const char *file, con
|
||||||
|
|
||||||
xsprintf(p, "PRIORITY=%i", priority & LOG_PRIMASK);
|
xsprintf(p, "PRIORITY=%i", priority & LOG_PRIMASK);
|
||||||
|
|
||||||
memcpy(buffer, "MESSAGE=", 8);
|
va_copy(aq, ap);
|
||||||
vsnprintf(buffer+8, sizeof(buffer) - 8, format, ap);
|
len = vsnprintf(buffer + 8, LINE_MAX, format, aq);
|
||||||
|
va_end(aq);
|
||||||
|
|
||||||
|
if (len >= (int)LONG_LINE_MAX - 8)
|
||||||
|
return -ENOBUFS;
|
||||||
|
|
||||||
|
/* Allocate large buffer to accomodate big message */
|
||||||
|
if (len >= LINE_MAX) {
|
||||||
|
int rlen;
|
||||||
|
buffer = alloca(len + 9);
|
||||||
|
memcpy(buffer, "MESSAGE=", 8);
|
||||||
|
rlen = vsnprintf(buffer + 8, len + 1, format, ap);
|
||||||
|
assert(len == rlen);
|
||||||
|
}
|
||||||
|
|
||||||
/* Strip trailing whitespace, keep prefixing whitespace */
|
/* Strip trailing whitespace, keep prefixing whitespace */
|
||||||
(void) strstrip(buffer);
|
(void) strstrip(buffer);
|
||||||
|
|
||||||
/* Suppress empty lines */
|
/* Suppress empty lines */
|
||||||
if (isempty(buffer+8))
|
if (isempty(buffer + 8))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* func is initialized from __func__ which is not a macro, but
|
/* func is initialized from __func__ which is not a macro, but
|
||||||
|
|
|
@ -5,11 +5,19 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "sd-journal.h"
|
#include "sd-journal.h"
|
||||||
|
#include "fileio.h"
|
||||||
#include "macro.h"
|
#include "macro.h"
|
||||||
#include "memory-util.h"
|
#include "memory-util.h"
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
static void test_journal_print(void) {
|
||||||
|
assert_se(sd_journal_print(LOG_INFO, "XXX") == 0);
|
||||||
|
assert_se(sd_journal_print(LOG_INFO, "%s", "YYY") == 0);
|
||||||
|
assert_se(sd_journal_print(LOG_INFO, "X%4094sY", "ZZZ") == 0);
|
||||||
|
assert_se(sd_journal_print(LOG_INFO, "X%*sY", LONG_LINE_MAX - 8 - 3, "ZZZ") == 0);
|
||||||
|
assert_se(sd_journal_print(LOG_INFO, "X%*sY", LONG_LINE_MAX - 8 - 2, "ZZZ") == -ENOBUFS);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_journal_send(void) {
|
||||||
_cleanup_free_ char *huge = NULL;
|
_cleanup_free_ char *huge = NULL;
|
||||||
|
|
||||||
#define HUGE_SIZE (4096*1024)
|
#define HUGE_SIZE (4096*1024)
|
||||||
|
@ -82,7 +90,13 @@ int main(int argc, char *argv[]) {
|
||||||
assert_se(sd_journal_sendv(graph2, 1) == 0);
|
assert_se(sd_journal_sendv(graph2, 1) == 0);
|
||||||
assert_se(sd_journal_sendv(message1, 1) == 0);
|
assert_se(sd_journal_sendv(message1, 1) == 0);
|
||||||
assert_se(sd_journal_sendv(message2, 1) == 0);
|
assert_se(sd_journal_sendv(message2, 1) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
test_journal_print();
|
||||||
|
test_journal_send();
|
||||||
|
|
||||||
|
/* Sleep a bit to make it easy for journald to collect metadata. */
|
||||||
sleep(1);
|
sleep(1);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in a new issue