| --- |
| kernel/printk.c | 42 +++++++++++++++++++++++++++--------------- |
| 1 file changed, 27 insertions(+), 15 deletions(-) |
| |
| --- a/kernel/printk.c |
| +++ b/kernel/printk.c |
| @@ -356,10 +356,28 @@ static void log_store(int facility, int |
| log_next_seq++; |
| } |
| |
| +static bool msg_wants_prefix(const struct log *msg, enum log_flags prev) |
| +{ |
| + if ((prev & LOG_CONT) && !(msg->flags & LOG_PREFIX)) |
| + return false; |
| + if ((msg->flags & LOG_CONT) && (prev & LOG_CONT) && |
| + !(prev & LOG_NEWLINE)) |
| + return false; |
| + return true; |
| +} |
| + |
| +static bool msg_wants_newline(const struct log *msg, enum log_flags prev) |
| +{ |
| + if ((msg->flags & LOG_CONT) && !(msg->flags & LOG_NEWLINE)) |
| + return false; |
| + return true; |
| +} |
| + |
| /* /dev/kmsg - userspace message inject/listen interface */ |
| struct devkmsg_user { |
| u64 seq; |
| u32 idx; |
| + enum log_flags prev; |
| struct mutex lock; |
| char buf[8192]; |
| }; |
| @@ -424,6 +442,7 @@ static ssize_t devkmsg_read(struct file |
| struct devkmsg_user *user = file->private_data; |
| struct log *msg; |
| u64 ts_usec; |
| + char flag = '-'; |
| size_t i; |
| size_t len; |
| ssize_t ret; |
| @@ -462,8 +481,12 @@ static ssize_t devkmsg_read(struct file |
| msg = log_from_idx(user->idx); |
| ts_usec = msg->ts_nsec; |
| do_div(ts_usec, 1000); |
| - len = sprintf(user->buf, "%u,%llu,%llu;", |
| - (msg->facility << 3) | msg->level, user->seq, ts_usec); |
| + if (!msg_wants_prefix(msg, user->prev) || |
| + !msg_wants_newline(msg, user->prev)) |
| + flag = '+'; |
| + len = sprintf(user->buf, |
| + "%u,%llu,%llu,%c;", (msg->facility << 3) | msg->level, |
| + user->seq, ts_usec, flag); |
| |
| /* escape non-printable characters */ |
| for (i = 0; i < msg->text_len; i++) { |
| @@ -847,21 +870,10 @@ static size_t msg_print_text(const struc |
| { |
| const char *text = log_text(msg); |
| size_t text_size = msg->text_len; |
| - bool prefix = true; |
| - bool newline = true; |
| + bool prefix = msg_wants_prefix(msg, prev); |
| + bool newline = msg_wants_newline(msg, prev); |
| size_t len = 0; |
| |
| - if ((prev & LOG_CONT) && !(msg->flags & LOG_PREFIX)) |
| - prefix = false; |
| - |
| - if (msg->flags & LOG_CONT) { |
| - if ((prev & LOG_CONT) && !(prev & LOG_NEWLINE)) |
| - prefix = false; |
| - |
| - if (!(msg->flags & LOG_NEWLINE)) |
| - newline = false; |
| - } |
| - |
| do { |
| const char *next = memchr(text, '\n', text_size); |
| size_t text_len; |