]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
maint: prefer 'read' to 'safe_read'
authorPaul Eggert <eggert@cs.ucla.edu>
Thu, 31 Jul 2025 19:31:58 +0000 (12:31 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Mon, 4 Aug 2025 02:48:05 +0000 (19:48 -0700)
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.

src/cat.c
src/head.c
src/ioblksize.h
src/tac.c
src/tail.c
src/tr.c

index c02210301d6cda1eb4a992258004cf416bb9ffa0..30a923ccec2ff1655840a92b08d573b307c94bc1 100644 (file)
--- 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));
index 1d83d2f1fcd37af788975ae94066319fd60829ab..20c2ee031364b3de841b9b817e7646dbda9a53c7 100644 (file)
@@ -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)
index cca38be2e32e14a0241da9aadab91ed7efaad131..133ca122b22028e37ddf18b24d251af7cef89001 100644 (file)
@@ -19,6 +19,7 @@
 /* sys/stat.h and minmax.h will already have been included by system.h. */
 #include <stdbit.h>
 #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);
 }
index f086f5345151e3947dd055abe581df59bc870113..2779c2d2cdd1b9cc81c05183a70deba3ad796433 100644 (file)
--- 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)
index 8f2b0115f9612a8439cb5890047b9444c2e2d741..d184fb13eb34bc2f40e508db96970bf8e20fca9b 100644 (file)
@@ -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
index 426065d11f12784d0a99e2335b894233cfd15671..87daa947123fcd56a0dba9924c9890d0ff9c86fe 100644 (file)
--- 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;