From: Paul Eggert Date: Thu, 31 Jul 2025 19:31:58 +0000 (-0700) Subject: maint: prefer 'read' to 'safe_read' X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d3c7072a0950c57c52a4e1856109d084a6d09593;p=thirdparty%2Fcoreutils.git maint: prefer 'read' to 'safe_read' In the old days, safe_read acted more like what full_read does now. When that went away, some code that invoked safe_read should have gone back to plain 'read' but I guess we never got around to it. Simplify this code by going back to plain 'read'. Use safe_read only in csplit.c, which has a signal handler and where 'read' can therefore fail with EINTR. Although safe_read also checks for oversize buffers, that is better done via io_blksize. * src/cat.c (simple_cat, cat): * src/head.c (copy_fd, elide_tail_lines_pipe) * src/tac.c (tac_seekable, copy_to_temp): (elide_tail_lines_seekable, head_lines): * src/tail.c (dump_remainder, file_lines, pipe_lines) (pipe_bytes, start_bytes, start_lines, tail_forever_inotify): * src/tr.c (plain_read): Use plain 'read', not safe_read, since there is no need to worry about signals or oversize requests. Also, there is no longer a need to include safe-read.h. * src/ioblksize.h: Include sys-limits.h, for SYS_BUFSIZE_MAX. (io_blksize): Max out at SYS_BUFSIZE_MAX. --- diff --git a/src/cat.c b/src/cat.c index c02210301d..30a923ccec 100644 --- a/src/cat.c +++ b/src/cat.c @@ -37,7 +37,6 @@ #include "ioblksize.h" #include "fadvise.h" #include "full-write.h" -#include "safe-read.h" #include "xbinary-io.h" /* The official name of this program (e.g., no 'g' prefix). */ @@ -161,7 +160,7 @@ simple_cat (char *buf, idx_t bufsize) { /* Read a block of input. */ - ptrdiff_t n_read = safe_read (input_desc, buf, bufsize); + ssize_t n_read = read (input_desc, buf, bufsize); if (n_read < 0) { error (0, errno, "%s", quotef (infile)); @@ -310,7 +309,7 @@ cat (char *inbuf, idx_t insize, char *outbuf, idx_t outsize, /* Read more input into INBUF. */ - ptrdiff_t n_read = safe_read (input_desc, inbuf, insize); + ssize_t n_read = read (input_desc, inbuf, insize); if (n_read < 0) { error (0, errno, "%s", quotef (infile)); diff --git a/src/head.c b/src/head.c index 1d83d2f1fc..20c2ee0313 100644 --- a/src/head.c +++ b/src/head.c @@ -34,7 +34,6 @@ #include "assure.h" #include "c-ctype.h" #include "full-read.h" -#include "safe-read.h" #include "stat-size.h" #include "xbinary-io.h" #include "xdectoint.h" @@ -205,7 +204,7 @@ copy_fd (int src_fd, uintmax_t n_bytes) while (0 < n_bytes) { idx_t n_to_read = MIN (n_bytes, sizeof buf); - ptrdiff_t n_read = safe_read (src_fd, buf, n_to_read); + ssize_t n_read = read (src_fd, buf, n_to_read); if (n_read < 0) return COPY_FD_READ_ERROR; @@ -508,7 +507,7 @@ elide_tail_lines_pipe (char const *filename, int fd, uintmax_t n_elide, LBUFFER *first, *last, *tmp; size_t total_lines = 0; /* Total number of newlines in all buffers. */ bool ok = true; - ptrdiff_t n_read; /* Size in bytes of most recent read */ + ssize_t n_read; /* Size in bytes of most recent read */ first = last = xmalloc (sizeof (LBUFFER)); first->nbytes = first->nlines = 0; @@ -520,7 +519,7 @@ elide_tail_lines_pipe (char const *filename, int fd, uintmax_t n_elide, n_elide newlines, or until EOF, whichever comes first. */ while (true) { - n_read = safe_read (fd, tmp->buffer, BUFSIZ); + n_read = read (fd, tmp->buffer, BUFSIZ); if (n_read <= 0) break; @@ -648,7 +647,7 @@ elide_tail_lines_seekable (char const *pretty_filename, int fd, off_t start_pos, off_t size) { char buffer[BUFSIZ]; - ptrdiff_t bytes_read; + ssize_t bytes_read; off_t pos = size; /* Set 'bytes_read' to the size of the last, probably partial, buffer; @@ -661,7 +660,7 @@ elide_tail_lines_seekable (char const *pretty_filename, int fd, pos -= bytes_read; if (elseek (fd, pos, SEEK_SET, pretty_filename) < 0) return false; - bytes_read = safe_read (fd, buffer, bytes_read); + bytes_read = read (fd, buffer, bytes_read); if (bytes_read < 0) { diagnose_read_failure (pretty_filename); @@ -730,7 +729,7 @@ elide_tail_lines_seekable (char const *pretty_filename, int fd, if (elseek (fd, pos, SEEK_SET, pretty_filename) < 0) return false; - bytes_read = safe_read (fd, buffer, BUFSIZ); + bytes_read = read (fd, buffer, BUFSIZ); if (bytes_read < 0) { diagnose_read_failure (pretty_filename); @@ -787,7 +786,7 @@ head_lines (char const *filename, int fd, uintmax_t lines_to_write) while (lines_to_write) { - ptrdiff_t bytes_read = safe_read (fd, buffer, BUFSIZ); + ssize_t bytes_read = read (fd, buffer, BUFSIZ); idx_t bytes_to_write = 0; if (bytes_read < 0) diff --git a/src/ioblksize.h b/src/ioblksize.h index cca38be2e3..133ca122b2 100644 --- a/src/ioblksize.h +++ b/src/ioblksize.h @@ -19,6 +19,7 @@ /* sys/stat.h and minmax.h will already have been included by system.h. */ #include #include "stat-size.h" +#include "sys-limits.h" /* As of Feb 2024, 256KiB is determined to be the best blksize @@ -103,8 +104,8 @@ io_blksize (struct stat const *st) } } - /* Don’t go above the largest power of two that fits in idx_t and size_t, + /* Don’t go above the maximum number of bytes + to read or write in a single system call, as that is asking for trouble. */ - return MIN (MIN (IDX_MAX, SIZE_MAX) / 2 + 1, - blocksize); + return MIN (SYS_BUFSIZE_MAX, blocksize); } diff --git a/src/tac.c b/src/tac.c index f086f53451..2779c2d2cd 100644 --- a/src/tac.c +++ b/src/tac.c @@ -45,7 +45,6 @@ tac -r -s '.\| #include "filenamecat.h" #include "full-read.h" -#include "safe-read.h" #include "temp-stream.h" #include "xbinary-io.h" @@ -212,7 +211,7 @@ tac_seekable (int input_fd, char const *file, off_t file_pos) /* Scan backward, looking for end of file. This caters to proc-like file systems where the file size is just an estimate. */ - while ((saved_record_size = safe_read (input_fd, G_buffer, read_size)) == 0 + while ((saved_record_size = read (input_fd, G_buffer, read_size)) == 0 && file_pos != 0) { off_t rsize = read_size; @@ -224,7 +223,7 @@ tac_seekable (int input_fd, char const *file, off_t file_pos) /* Now scan forward, looking for end of file. */ while (saved_record_size == read_size) { - ptrdiff_t nread = safe_read (input_fd, G_buffer, read_size); + ssize_t nread = read (input_fd, G_buffer, read_size); if (nread == 0) break; saved_record_size = nread; @@ -385,7 +384,7 @@ copy_to_temp (FILE **g_tmp, char **g_tempfile, int input_fd, char const *file) while (true) { - ptrdiff_t bytes_read = safe_read (input_fd, G_buffer, read_size); + ssize_t bytes_read = read (input_fd, G_buffer, read_size); if (bytes_read == 0) break; if (bytes_read < 0) diff --git a/src/tail.c b/src/tail.c index 8f2b0115f9..d184fb13eb 100644 --- a/src/tail.c +++ b/src/tail.c @@ -445,7 +445,7 @@ dump_remainder (bool want_header, char const *prettyname, int fd, { char buffer[BUFSIZ]; idx_t n = n_bytes < 0 || BUFSIZ < n_remaining ? BUFSIZ : n_remaining; - ptrdiff_t bytes_read = safe_read (fd, buffer, n); + ssize_t bytes_read = read (fd, buffer, n); if (bytes_read < 0) { if (errno != EAGAIN) @@ -536,14 +536,14 @@ file_lines (char const *prettyname, int fd, struct stat const *sb, /* Set 'bytes_read' to the size of the last, probably partial, buffer; 0 < 'bytes_read' <= 'bufsize'. */ - ptrdiff_t bytes_read = (pos - start_pos) % bufsize; - if (bytes_read == 0) - bytes_read = bufsize; + idx_t bytes_to_read = (pos - start_pos) % bufsize; + if (bytes_to_read == 0) + bytes_to_read = bufsize; /* Make 'pos' a multiple of 'bufsize' (0 if the file is short), so that all reads will be on block boundaries, which might increase efficiency. */ - pos -= bytes_read; + pos -= bytes_to_read; xlseek (fd, pos, SEEK_SET, prettyname); - bytes_read = safe_read (fd, buffer, bytes_read); + ssize_t bytes_read = read (fd, buffer, bytes_to_read); if (bytes_read < 0) { error (0, errno, _("error reading %s"), quoteaf (prettyname)); @@ -592,7 +592,7 @@ file_lines (char const *prettyname, int fd, struct stat const *sb, pos -= bufsize; xlseek (fd, pos, SEEK_SET, prettyname); - bytes_read = safe_read (fd, buffer, bufsize); + bytes_read = read (fd, buffer, bufsize); if (bytes_read < 0) { error (0, errno, _("error reading %s"), quoteaf (prettyname)); @@ -629,7 +629,7 @@ pipe_lines (char const *prettyname, int fd, count_t n_lines, LBUFFER *first, *last, *tmp; idx_t total_lines = 0; /* Total number of newlines in all buffers. */ bool ok = true; - ptrdiff_t n_read; /* Size in bytes of most recent read */ + ssize_t n_read; /* Size in bytes of most recent read */ first = last = xmalloc (sizeof (LBUFFER)); first->nbytes = first->nlines = 0; @@ -639,7 +639,7 @@ pipe_lines (char const *prettyname, int fd, count_t n_lines, /* Input is always read into a fresh buffer. */ while (true) { - n_read = safe_read (fd, tmp->buffer, BUFSIZ); + n_read = read (fd, tmp->buffer, BUFSIZ); if (n_read <= 0) break; tmp->nbytes = n_read; @@ -768,7 +768,7 @@ pipe_bytes (char const *prettyname, int fd, count_t n_bytes, idx_t i; /* Index into buffers. */ intmax_t total_bytes = 0; /* Total characters in all buffers. */ bool ok = true; - ptrdiff_t n_read; + ssize_t n_read; first = last = xmalloc (sizeof (CBUFFER)); first->nbytes = 0; @@ -778,7 +778,7 @@ pipe_bytes (char const *prettyname, int fd, count_t n_bytes, /* Input is always read into a fresh buffer. */ while (true) { - n_read = safe_read (fd, tmp->buffer, BUFSIZ); + n_read = read (fd, tmp->buffer, BUFSIZ); if (n_read <= 0) break; *read_pos += n_read; @@ -862,7 +862,7 @@ start_bytes (char const *prettyname, int fd, count_t n_bytes, while (0 < n_bytes) { - ptrdiff_t bytes_read = safe_read (fd, buffer, BUFSIZ); + ssize_t bytes_read = read (fd, buffer, BUFSIZ); if (bytes_read == 0) return -1; if (bytes_read < 0) @@ -897,7 +897,7 @@ start_lines (char const *prettyname, int fd, count_t n_lines, while (true) { char buffer[BUFSIZ]; - ptrdiff_t bytes_read = safe_read (fd, buffer, BUFSIZ); + ssize_t bytes_read = read (fd, buffer, BUFSIZ); if (bytes_read == 0) /* EOF */ return -1; if (bytes_read < 0) /* error */ @@ -1602,7 +1602,7 @@ tail_forever_inotify (int wd, struct File_spec *f, int n_files, /* Wait for inotify events and handle them. Events on directories ensure that watched files can be re-added when following by name. - This loop blocks on the 'safe_read' call until a new event is notified. + This loop blocks on the 'read' call until a new event is notified. But when --pid=P is specified, tail usually waits via poll. */ ptrdiff_t len = 0; while (true) @@ -1663,7 +1663,7 @@ tail_forever_inotify (int wd, struct File_spec *f, int n_files, if (pfd[1].revents) die_pipe (); - len = safe_read (wd, evbuf, evlen); + len = read (wd, evbuf, evlen); evbuf_off = 0; /* For kernels prior to 2.6.21, read returns 0 when the buffer diff --git a/src/tr.c b/src/tr.c index 426065d11f..87daa94712 100644 --- a/src/tr.c +++ b/src/tr.c @@ -28,7 +28,6 @@ #include "c-ctype.h" #include "fadvise.h" #include "quote.h" -#include "safe-read.h" #include "xbinary-io.h" #include "xstrtol.h" @@ -1593,7 +1592,7 @@ squeeze_filter (char *buf, size_t size, size_t (*reader) (char *, size_t)) static size_t plain_read (char *buf, size_t size) { - ptrdiff_t nr = safe_read (STDIN_FILENO, buf, size); + ssize_t nr = read (STDIN_FILENO, buf, size); if (nr < 0) error (EXIT_FAILURE, errno, _("read error")); return nr;