[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#8565: gzip/bzip2/output-hook support for split
From: |
Jim Meyering |
Subject: |
bug#8565: gzip/bzip2/output-hook support for split |
Date: |
Sat, 30 Apr 2011 16:29:45 +0200 |
Karl Heuer wrote:
>>Karl, this is a good time to add the feature.
>>If you don't have time to handle the remaining bits (test,
>>doc and NEWS), let us know and we will take care of the rest.
>
> I'd better let you do it; I've got too many other items in my
> queue at the moment.
Hi Karl,
FYI, I've nearly finished with split-filter-related changes.
I posted a slightly modified version of your patch and a few
follow-on changes:
http://thread.gmane.org/gmane.comp.gnu.coreutils.general/1138
And one more below.
I noticed that you've added a lot of "errno != EPIPE" tests.
And for a good reason, as you explained here:
/* When filtering, closure of one pipe must not terminate the process,
as there may still be other streams expecting input from us. */
sigemptyset (&newblocked);
if (filter_command)
{
struct sigaction act;
sigaction (SIGPIPE, NULL, &act);
if (act.sa_handler != SIG_IGN)
sigaddset (&newblocked, SIGPIPE);
}
sigprocmask (SIG_BLOCK, &newblocked, &oldblocked);
However, I presume you intended that change only
when filter_command is non-NULL. I would not want to
suppress an error if somehow I accidentally ran a
classic split command with a non-default signal handler
and I sent it a SIGPIPE signal just as it was writing to
a file I cared about.
>From baf68e2dfb8ccfbfa797917e818551b12e129aef Mon Sep 17 00:00:00 2001
From: Jim Meyering <address@hidden>
Date: Sat, 30 Apr 2011 16:08:04 +0200
Subject: [PATCH] split: factor out all new EPIPE tests; exempt EPIPE only
with --filter
* src/split.c (ignorable): New function, to encapsulate EPIPE test.
Ignore failure with errno == EPIPE only when --filter=CMD is specified.
Replace all comparisons like && errno != EPIPE with
&& ! ignorable (errno).
---
src/split.c | 28 ++++++++++++++++++----------
1 files changed, 18 insertions(+), 10 deletions(-)
diff --git a/src/split.c b/src/split.c
index 66f44fc..05315e6 100644
--- a/src/split.c
+++ b/src/split.c
@@ -131,6 +131,13 @@ static struct option const longopts[] =
{NULL, 0, NULL, 0}
};
+/* Return true if the errno value, ERR, is ignorable. */
+static inline bool
+ignorable (int err)
+{
+ return filter_command && err == EPIPE;
+}
+
static void
set_suffix_length (uintmax_t n_units, enum Split_type split_type)
{
@@ -346,7 +353,7 @@ create (const char *name)
static void
closeout (FILE *fp, int fd, pid_t pid, char const *name)
{
- if (fp != NULL && fclose (fp) != 0 && errno != EPIPE)
+ if (fp != NULL && fclose (fp) != 0 && ! ignorable (errno))
error (EXIT_FAILURE, errno, "%s", name);
if (fd >= 0)
{
@@ -412,7 +419,7 @@ cwrite (bool new_file_flag, const char *bp, size_t bytes)
if ((output_desc = create (outfile)) < 0)
error (EXIT_FAILURE, errno, "%s", outfile);
}
- if (full_write (output_desc, bp, bytes) != bytes && errno != EPIPE)
+ if (full_write (output_desc, bp, bytes) != bytes && ! ignorable (errno))
error (EXIT_FAILURE, errno, "%s", outfile);
}
@@ -635,7 +642,7 @@ lines_chunk_split (uintmax_t k, uintmax_t n, char *buf,
size_t bufsize,
large chunks from an existing file, so it's more efficient
to write out directly. */
if (full_write (STDOUT_FILENO, bp, to_write) != to_write
- && errno != EPIPE)
+ && ! ignorable (errno))
error (EXIT_FAILURE, errno, "%s", _("write error"));
}
else
@@ -698,7 +705,8 @@ bytes_chunk_extract (uintmax_t k, uintmax_t n, char *buf,
size_t bufsize,
error (EXIT_FAILURE, errno, "%s", infile);
else if (n_read == 0)
break; /* eof. */
- if (full_write (STDOUT_FILENO, buf, n_read) != n_read && errno != EPIPE)
+ if (full_write (STDOUT_FILENO, buf, n_read) != n_read
+ && ! ignorable (errno))
error (EXIT_FAILURE, errno, "%s", quote ("-"));
start += n_read;
}
@@ -772,7 +780,7 @@ ofile_open (of_t *files, size_t i_check, size_t nfiles)
error (EXIT_FAILURE, errno, "%s", files[i_check].of_name);
}
- if (fclose (files[i_reopen].ofile) != 0 && errno != EPIPE)
+ if (fclose (files[i_reopen].ofile) != 0 && ! ignorable (errno))
error (EXIT_FAILURE, errno, "%s", files[i_reopen].of_name);
files[i_reopen].ofile = NULL;
files[i_reopen].ofd = OFD_APPEND;
@@ -856,11 +864,11 @@ lines_rr (uintmax_t k, uintmax_t n, char *buf, size_t
bufsize)
if (line_no == k && unbuffered)
{
if (full_write (STDOUT_FILENO, bp, to_write) != to_write
- && errno != EPIPE)
+ && ! ignorable (errno))
error (EXIT_FAILURE, errno, "%s", _("write error"));
}
else if (line_no == k && fwrite (bp, to_write, 1, stdout) != 1
- && errno != EPIPE)
+ && ! ignorable (errno))
{
clearerr (stdout); /* To silence close_stdout(). */
error (EXIT_FAILURE, errno, "%s", _("write error"));
@@ -877,15 +885,15 @@ lines_rr (uintmax_t k, uintmax_t n, char *buf, size_t
bufsize)
/* Note writing to fd, rather than flushing the FILE gives
an 8% performance benefit, due to reduced data copying.
*/
if (full_write (files[i_file].ofd, bp, to_write) != to_write
- && errno != EPIPE)
+ && ! ignorable (errno))
error (EXIT_FAILURE, errno, "%s", files[i_file].of_name);
}
else if (fwrite (bp, to_write, 1, files[i_file].ofile) != 1
- && errno != EPIPE)
+ && ! ignorable (errno))
error (EXIT_FAILURE, errno, "%s", files[i_file].of_name);
if (file_limit)
{
- if (fclose (files[i_file].ofile) != 0 && errno != EPIPE)
+ if (fclose (files[i_file].ofile) != 0 && ! ignorable (errno))
error (EXIT_FAILURE, errno, "%s", files[i_file].of_name);
files[i_file].ofile = NULL;
files[i_file].ofd = OFD_APPEND;
--
1.7.5.134.g1c08b