@@ -371,12 +371,57 @@ static bool debug;
371371 number are present, temp files will be used. */
372372static unsigned int nmerge = NMERGE_DEFAULT ;
373373
374+ /* Whether SIGPIPE had the default disposition at startup. */
375+ static bool default_SIGPIPE ;
376+
377+ /* The list of temporary files. */
378+ struct tempnode
379+ {
380+ struct tempnode * volatile next ;
381+ pid_t pid ; /* The subprocess PID; undefined if state == UNCOMPRESSED. */
382+ char state ;
383+ char name [FLEXIBLE_ARRAY_MEMBER ];
384+ };
385+ static struct tempnode * volatile temphead ;
386+ static struct tempnode * volatile * temptail = & temphead ;
387+
388+ /* Clean up any remaining temporary files. */
389+
390+ static void
391+ cleanup (void )
392+ {
393+ struct tempnode const * node ;
394+
395+ for (node = temphead ; node ; node = node -> next )
396+ unlink (node -> name );
397+ temphead = nullptr ;
398+ }
399+
400+ /* Handle interrupts and hangups. */
401+
402+ static void
403+ sighandler (int sig )
404+ {
405+ if (! SA_NOCLDSTOP )
406+ signal (sig , SIG_IGN );
407+
408+ cleanup ();
409+
410+ signal (sig , SIG_DFL );
411+ raise (sig );
412+ }
413+
374414/* Report MESSAGE for FILE, then clean up and exit.
375415 If FILE is null, it represents standard output. */
376416
377417static void
378418sort_die (char const * message , char const * file )
379419{
420+ /* If we got EPIPE writing to stdout (from a previous fwrite() or fclose()
421+ and SIGPIPE was originally SIG_DFL, mimic standard SIGPIPE behavior. */
422+ if (errno == EPIPE && !file && default_SIGPIPE )
423+ sighandler (SIGPIPE );
424+
380425 error (SORT_FAILURE , errno , "%s: %s" , message ,
381426 quotef (file ? file : _ ("standard output" )));
382427}
@@ -631,17 +676,6 @@ cs_leave (struct cs_status const *status)
631676 the subprocess to finish. */
632677enum { UNCOMPRESSED , UNREAPED , REAPED };
633678
634- /* The list of temporary files. */
635- struct tempnode
636- {
637- struct tempnode * volatile next ;
638- pid_t pid ; /* The subprocess PID; undefined if state == UNCOMPRESSED. */
639- char state ;
640- char name [FLEXIBLE_ARRAY_MEMBER ];
641- };
642- static struct tempnode * volatile temphead ;
643- static struct tempnode * volatile * temptail = & temphead ;
644-
645679/* A file to be sorted. */
646680struct sortfile
647681{
@@ -780,18 +814,6 @@ reap_all (void)
780814 reap (-1 );
781815}
782816
783- /* Clean up any remaining temporary files. */
784-
785- static void
786- cleanup (void )
787- {
788- struct tempnode const * node ;
789-
790- for (node = temphead ; node ; node = node -> next )
791- unlink (node -> name );
792- temphead = nullptr ;
793- }
794-
795817/* Cleanup actions to take when exiting. */
796818
797819static void
@@ -4262,20 +4284,6 @@ parse_field_count (char const *string, size_t *val, char const *msgid)
42624284 return suffix ;
42634285}
42644286
4265- /* Handle interrupts and hangups. */
4266-
4267- static void
4268- sighandler (int sig )
4269- {
4270- if (! SA_NOCLDSTOP )
4271- signal (sig , SIG_IGN );
4272-
4273- cleanup ();
4274-
4275- signal (sig , SIG_DFL );
4276- raise (sig );
4277- }
4278-
42794287/* Set the ordering options for KEY specified in S.
42804288 Return the address of the first character in S that
42814289 is not a valid ordering option.
@@ -4409,7 +4417,7 @@ main (int argc, char **argv)
44094417 static int const sig [] =
44104418 {
44114419 /* The usual suspects. */
4412- SIGALRM , SIGHUP , SIGINT , SIGPIPE , SIGQUIT , SIGTERM ,
4420+ SIGALRM , SIGHUP , SIGINT , SIGQUIT , SIGTERM ,
44134421#ifdef SIGPOLL
44144422 SIGPOLL ,
44154423#endif
@@ -4457,6 +4465,11 @@ main (int argc, char **argv)
44574465 }
44584466 signal (SIGCHLD , SIG_DFL ); /* Don't inherit CHLD handling from parent. */
44594467
4468+ /* Ignore SIGPIPE so write failures are reported via EPIPE errno.
4469+ For stdout, sort_die() will reraise SIGPIPE if it was originally SIG_DFL.
4470+ For compression pipes, sort_die() will exit with SORT_FAILURE. */
4471+ default_SIGPIPE = (signal (SIGPIPE , SIG_IGN ) == SIG_DFL );
4472+
44604473 /* The signal mask is known, so it is safe to invoke exit_cleanup. */
44614474 atexit (exit_cleanup );
44624475
0 commit comments