]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
dmesg: Gracefully handle EPIPE errors
authorTobias Stoeckmann <tobias@stoeckmann.org>
Thu, 19 Feb 2026 17:14:23 +0000 (18:14 +0100)
committerTobias Stoeckmann <tobias@stoeckmann.org>
Thu, 19 Feb 2026 17:43:22 +0000 (18:43 +0100)
Just calling exit with a success return value in case of an EPIPE error
in safe_fwrite is not precise enough. If dmesg was called with "-c",
i.e. to print and then clear the ring buffer, a successful return value
should mean that the ring buffer is cleared as well.

Instead, continue operation on EPIPE error but stop any further regular
output.

Signed-off-by: Tobias Stoeckmann <tobias@stoeckmann.org>
sys-utils/dmesg.c

index b6f506034ed0b51ee8bbb56c0a1dbf18d6894940..cd042f5491a1887fac9d575abc29159e268137dd 100644 (file)
@@ -821,11 +821,8 @@ doprint:
                } else
                        rc = fwrite(p, 1, len, out) != len;
 
-               if (rc != 0) {
-                       if (errno != EPIPE)
-                               err(EXIT_FAILURE, _("write failed"));
-                       exit(EXIT_SUCCESS);
-               }
+               if (rc != 0 && errno != EPIPE)
+                       err(EXIT_FAILURE, _("write failed"));
        }
 }
 
@@ -1012,7 +1009,7 @@ static void raw_print(struct dmesg_control *ctl, const char *buf, size_t size)
                /*
                 * Print file in small chunks to save memory
                 */
-               while (size) {
+               while (size && !ferror(stdout)) {
                        size_t sz = size > ctl->pagesize ? ctl->pagesize : size;
                        char *x = ctl->mmap_buff;
 
@@ -1380,7 +1377,7 @@ static void print_buffer(struct dmesg_control *ctl,
                return;
        }
 
-       while (get_next_syslog_record(ctl, &rec) == 0)
+       while (get_next_syslog_record(ctl, &rec) == 0 && !ferror(stdout))
                print_record(ctl, &rec);
 }
 
@@ -1549,7 +1546,7 @@ static int print_kmsg(struct dmesg_control *ctl)
         */
        sz = ctl->kmsg_first_read;
 
-       while (sz > 0) {
+       while (sz > 0 && !ferror(stdout)) {
                *(ctl->kmsg_buf + sz) = '\0';   /* for debug messages */
 
                if (parse_kmsg_record(ctl, &rec,
@@ -1571,7 +1568,7 @@ static int print_kmsg_file(struct dmesg_control *ctl, size_t sz)
        if (ctl->method != DMESG_METHOD_KMSG || !ctl->filename)
                return -1;
 
-       while (sz > 0) {
+       while (sz > 0 && !ferror(stdout)) {
                len = strnlen(ctl->mmap_buff, sz);
                if (len > sizeof(str))
                        errx(EXIT_FAILURE, _("record too large"));