1 /* sort - sort lines of text (with all kinds of options).
2    Copyright (C) 1988-2023 Free Software Foundation, Inc.
3 
4    This program is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation, either version 3 of the License, or
7    (at your option) any later version.
8 
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13 
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see <https://www.gnu.org/licenses/>.
16 
17    Written December 1988 by Mike Haertel.
18    The author may be reached (Email) at the address mike@gnu.ai.mit.edu,
19    or (US mail) as Mike Haertel c/o Free Software Foundation.
20 
21    Ørn E. Hansen added NLS support in 1997.  */
22 
23 #include <config.h>
24 
25 #include <getopt.h>
26 #include <pthread.h>
27 #include <sys/resource.h>
28 #include <sys/types.h>
29 #include <sys/wait.h>
30 #include <signal.h>
31 #include "system.h"
32 #include "argmatch.h"
33 #include "assure.h"
34 #include "fadvise.h"
35 #include "filevercmp.h"
36 #include "flexmember.h"
37 #include "hard-locale.h"
38 #include "hash.h"
39 #include "heap.h"
40 #include "ignore-value.h"
41 #include "md5.h"
42 #include "mbswidth.h"
43 #include "nproc.h"
44 #include "physmem.h"
45 #include "posixver.h"
46 #include "quote.h"
47 #include "randread.h"
48 #include "readtokens0.h"
49 #include "stdlib--.h"
50 #include "strnumcmp.h"
51 #include "xmemcoll.h"
52 #include "xnanosleep.h"
53 #include "xstrtol.h"
54 #include "xstrtol-error.h"
55 
56 #ifndef RLIMIT_DATA
57 struct rlimit { size_t rlim_cur; };
58 # define getrlimit(Resource, Rlp) (-1)
59 #endif
60 
61 /* The official name of this program (e.g., no 'g' prefix).  */
62 #define PROGRAM_NAME "sort"
63 
64 #define AUTHORS \
65   proper_name ("Mike Haertel"), \
66   proper_name ("Paul Eggert")
67 
68 #if HAVE_LANGINFO_CODESET
69 # include <langinfo.h>
70 #endif
71 
72 /* Use SA_NOCLDSTOP as a proxy for whether the sigaction machinery is
73    present.  */
74 #ifndef SA_NOCLDSTOP
75 # define SA_NOCLDSTOP 0
76 /* No sigprocmask.  Always 'return' zero. */
77 # define sigprocmask(How, Set, Oset) (0)
78 # define sigset_t int
79 # if ! HAVE_SIGINTERRUPT
80 #  define siginterrupt(sig, flag) /* empty */
81 # endif
82 #endif
83 
84 #if !defined OPEN_MAX && defined NR_OPEN
85 # define OPEN_MAX NR_OPEN
86 #endif
87 #if !defined OPEN_MAX
88 # define OPEN_MAX 20
89 #endif
90 
91 #define UCHAR_LIM (UCHAR_MAX + 1)
92 
93 #ifndef DEFAULT_TMPDIR
94 # define DEFAULT_TMPDIR "/tmp"
95 #endif
96 
97 /* Maximum number of lines to merge every time a NODE is taken from
98    the merge queue.  Node is at LEVEL in the binary merge tree,
99    and is responsible for merging TOTAL lines. */
100 #define MAX_MERGE(total, level) (((total) >> (2 * ((level) + 1))) + 1)
101 
102 /* Heuristic value for the number of lines for which it is worth creating
103    a subthread, during an internal merge sort.  I.e., it is a small number
104    of "average" lines for which sorting via two threads is faster than
105    sorting via one on an "average" system.  On a dual-core 2.0 GHz i686
106    system with 3GB of RAM and 2MB of L2 cache, a file containing 128K
107    lines of gensort -a output is sorted slightly faster with --parallel=2
108    than with --parallel=1.  By contrast, using --parallel=1 is about 10%
109    faster than using --parallel=2 with a 64K-line input.  */
110 enum { SUBTHREAD_LINES_HEURISTIC = 128 * 1024 };
111 static_assert (4 <= SUBTHREAD_LINES_HEURISTIC);
112 
113 /* The number of threads after which there are
114    diminishing performance gains.  */
115 enum { DEFAULT_MAX_THREADS = 8 };
116 
117 /* Exit statuses.  */
118 enum
119   {
120     /* POSIX says to exit with status 1 if invoked with -c and the
121        input is not properly sorted.  */
122     SORT_OUT_OF_ORDER = 1,
123 
124     /* POSIX says any other irregular exit must exit with a status
125        code greater than 1.  */
126     SORT_FAILURE = 2
127   };
128 
129 enum
130   {
131     /* The number of times we should try to fork a compression process
132        (we retry if the fork call fails).  We don't _need_ to compress
133        temp files, this is just to reduce file system access, so this number
134        can be small.  Each retry doubles in duration.  */
135     MAX_FORK_TRIES_COMPRESS = 4,
136 
137     /* The number of times we should try to fork a decompression process.
138        If we can't fork a decompression process, we can't sort, so this
139        number should be big.  Each retry doubles in duration.  */
140     MAX_FORK_TRIES_DECOMPRESS = 9
141   };
142 
143 enum
144   {
145     /* Level of the end-of-merge node, one level above the root. */
146     MERGE_END = 0,
147 
148     /* Level of the root node in merge tree. */
149     MERGE_ROOT = 1
150   };
151 
152 /* The representation of the decimal point in the current locale.  */
153 static char decimal_point;
154 
155 /* Thousands separator; if outside char range, there is no separator.  */
156 static int thousands_sep;
157 /* We currently ignore multi-byte grouping chars.  */
158 static bool thousands_sep_ignored;
159 
160 /* Nonzero if the corresponding locales are hard.  */
161 static bool hard_LC_COLLATE;
162 #if HAVE_NL_LANGINFO
163 static bool hard_LC_TIME;
164 #endif
165 
166 #define NONZERO(x) ((x) != 0)
167 
168 /* The kind of blanks for '-b' to skip in various options. */
169 enum blanktype { bl_start, bl_end, bl_both };
170 
171 /* The character marking end of line. Default to \n. */
172 static char eolchar = '\n';
173 
174 /* Lines are held in memory as counted strings. */
175 struct line
176 {
177   char *text;			/* Text of the line. */
178   size_t length;		/* Length including final newline. */
179   char *keybeg;			/* Start of first key. */
180   char *keylim;			/* Limit of first key. */
181 };
182 
183 /* Input buffers. */
184 struct buffer
185 {
186   char *buf;			/* Dynamically allocated buffer,
187                                    partitioned into 3 regions:
188                                    - input data;
189                                    - unused area;
190                                    - an array of lines, in reverse order.  */
191   size_t used;			/* Number of bytes used for input data.  */
192   size_t nlines;		/* Number of lines in the line array.  */
193   size_t alloc;			/* Number of bytes allocated. */
194   size_t left;			/* Number of bytes left from previous reads. */
195   size_t line_bytes;		/* Number of bytes to reserve for each line. */
196   bool eof;			/* An EOF has been read.  */
197 };
198 
199 /* Sort key.  */
200 struct keyfield
201 {
202   size_t sword;			/* Zero-origin 'word' to start at. */
203   size_t schar;			/* Additional characters to skip. */
204   size_t eword;			/* Zero-origin last 'word' of key. */
205   size_t echar;			/* Additional characters in field. */
206   bool const *ignore;		/* Boolean array of characters to ignore. */
207   char const *translate;	/* Translation applied to characters. */
208   bool skipsblanks;		/* Skip leading blanks when finding start.  */
209   bool skipeblanks;		/* Skip leading blanks when finding end.  */
210   bool numeric;			/* Flag for numeric comparison.  Handle
211                                    strings of digits with optional decimal
212                                    point, but no exponential notation. */
213   bool random;			/* Sort by random hash of key.  */
214   bool general_numeric;		/* Flag for general, numeric comparison.
215                                    Handle numbers in exponential notation. */
216   bool human_numeric;		/* Flag for sorting by human readable
217                                    units with either SI or IEC prefixes. */
218   bool month;			/* Flag for comparison by month name. */
219   bool reverse;			/* Reverse the sense of comparison. */
220   bool version;			/* sort by version number */
221   bool traditional_used;	/* Traditional key option format is used. */
222   struct keyfield *next;	/* Next keyfield to try. */
223 };
224 
225 struct month
226 {
227   char const *name;
228   int val;
229 };
230 
231 /* Binary merge tree node. */
232 struct merge_node
233 {
234   struct line *lo;              /* Lines to merge from LO child node. */
235   struct line *hi;              /* Lines to merge from HI child node. */
236   struct line *end_lo;          /* End of available lines from LO. */
237   struct line *end_hi;          /* End of available lines from HI. */
238   struct line **dest;           /* Pointer to destination of merge. */
239   size_t nlo;                   /* Total Lines remaining from LO. */
240   size_t nhi;                   /* Total lines remaining from HI. */
241   struct merge_node *parent;    /* Parent node. */
242   struct merge_node *lo_child;  /* LO child node. */
243   struct merge_node *hi_child;  /* HI child node. */
244   unsigned int level;           /* Level in merge tree. */
245   bool queued;                  /* Node is already in heap. */
246   pthread_mutex_t lock;         /* Lock for node operations. */
247 };
248 
249 /* Priority queue of merge nodes. */
250 struct merge_node_queue
251 {
252   struct heap *priority_queue;  /* Priority queue of merge tree nodes. */
253   pthread_mutex_t mutex;        /* Lock for queue operations. */
254   pthread_cond_t cond;          /* Conditional wait for empty queue to populate
255                                    when popping. */
256 };
257 
258 /* Used to implement --unique (-u).  */
259 static struct line saved_line;
260 
261 /* FIXME: None of these tables work with multibyte character sets.
262    Also, there are many other bugs when handling multibyte characters.
263    One way to fix this is to rewrite 'sort' to use wide characters
264    internally, but doing this with good performance is a bit
265    tricky.  */
266 
267 /* Table of blanks.  */
268 static bool blanks[UCHAR_LIM];
269 
270 /* Table of non-printing characters. */
271 static bool nonprinting[UCHAR_LIM];
272 
273 /* Table of non-dictionary characters (not letters, digits, or blanks). */
274 static bool nondictionary[UCHAR_LIM];
275 
276 /* Translation table folding lower case to upper.  */
277 static char fold_toupper[UCHAR_LIM];
278 
279 #define MONTHS_PER_YEAR 12
280 
281 /* Table mapping month names to integers.
282    Alphabetic order allows binary search. */
283 static struct month monthtab[] =
284 {
285   {"APR", 4},
286   {"AUG", 8},
287   {"DEC", 12},
288   {"FEB", 2},
289   {"JAN", 1},
290   {"JUL", 7},
291   {"JUN", 6},
292   {"MAR", 3},
293   {"MAY", 5},
294   {"NOV", 11},
295   {"OCT", 10},
296   {"SEP", 9}
297 };
298 
299 /* During the merge phase, the number of files to merge at once. */
300 #define NMERGE_DEFAULT 16
301 
302 /* Minimum size for a merge or check buffer.  */
303 #define MIN_MERGE_BUFFER_SIZE (2 + sizeof (struct line))
304 
305 /* Minimum sort size; the code might not work with smaller sizes.  */
306 #define MIN_SORT_SIZE (nmerge * MIN_MERGE_BUFFER_SIZE)
307 
308 /* The number of bytes needed for a merge or check buffer, which can
309    function relatively efficiently even if it holds only one line.  If
310    a longer line is seen, this value is increased.  */
311 static size_t merge_buffer_size = MAX (MIN_MERGE_BUFFER_SIZE, 256 * 1024);
312 
313 /* The approximate maximum number of bytes of main memory to use, as
314    specified by the user.  Zero if the user has not specified a size.  */
315 static size_t sort_size;
316 
317 /* The initial allocation factor for non-regular files.
318    This is used, e.g., when reading from a pipe.
319    Don't make it too big, since it is multiplied by ~130 to
320    obtain the size of the actual buffer sort will allocate.
321    Also, there may be 8 threads all doing this at the same time.  */
322 #define INPUT_FILE_SIZE_GUESS (128 * 1024)
323 
324 /* Array of directory names in which any temporary files are to be created. */
325 static char const **temp_dirs;
326 
327 /* Number of temporary directory names used.  */
328 static size_t temp_dir_count;
329 
330 /* Number of allocated slots in temp_dirs.  */
331 static size_t temp_dir_alloc;
332 
333 /* Flag to reverse the order of all comparisons. */
334 static bool reverse;
335 
336 /* Flag for stable sort.  This turns off the last ditch bytewise
337    comparison of lines, and instead leaves lines in the same order
338    they were read if all keys compare equal.  */
339 static bool stable;
340 
341 /* An int value outside char range.  */
342 enum { NON_CHAR = CHAR_MAX + 1 };
343 
344 /* If TAB has this value, blanks separate fields.  */
345 enum { TAB_DEFAULT = CHAR_MAX + 1 };
346 
347 /* Tab character separating fields.  If TAB_DEFAULT, then fields are
348    separated by the empty string between a non-blank character and a blank
349    character. */
350 static int tab = TAB_DEFAULT;
351 
352 /* Flag to remove consecutive duplicate lines from the output.
353    Only the last of a sequence of equal lines will be output. */
354 static bool unique;
355 
356 /* Nonzero if any of the input files are the standard input. */
357 static bool have_read_stdin;
358 
359 /* List of key field comparisons to be tried.  */
360 static struct keyfield *keylist;
361 
362 /* Program used to (de)compress temp files.  Must accept -d.  */
363 static char const *compress_program;
364 
365 /* Annotate the output with extra info to aid the user.  */
366 static bool debug;
367 
368 /* Maximum number of files to merge in one go.  If more than this
369    number are present, temp files will be used. */
370 static unsigned int nmerge = NMERGE_DEFAULT;
371 
372 /* Output an error to stderr and exit using async-signal-safe routines.
373    This can be used safely from signal handlers,
374    and between fork and exec of multithreaded processes.  */
375 
376 static _Noreturn void
async_safe_die(int errnum,char const * errstr)377 async_safe_die (int errnum, char const *errstr)
378 {
379   ignore_value (write (STDERR_FILENO, errstr, strlen (errstr)));
380 
381   /* Even if defined HAVE_STRERROR_R, we can't use it,
382      as it may return a translated string etc. and even if not
383      may call malloc which is unsafe.  We might improve this
384      by testing for sys_errlist and using that if available.
385      For now just report the error number.  */
386   if (errnum)
387     {
388       char errbuf[INT_BUFSIZE_BOUND (errnum)];
389       char *p = inttostr (errnum, errbuf);
390       ignore_value (write (STDERR_FILENO, ": errno ", 8));
391       ignore_value (write (STDERR_FILENO, p, strlen (p)));
392     }
393 
394   ignore_value (write (STDERR_FILENO, "\n", 1));
395 
396   _exit (SORT_FAILURE);
397 }
398 
399 /* Report MESSAGE for FILE, then clean up and exit.
400    If FILE is null, it represents standard output.  */
401 
402 static void
sort_die(char const * message,char const * file)403 sort_die (char const *message, char const *file)
404 {
405   error (SORT_FAILURE, errno, "%s: %s", message,
406          quotef (file ? file : _("standard output")));
407 }
408 
409 void
usage(int status)410 usage (int status)
411 {
412   if (status != EXIT_SUCCESS)
413     emit_try_help ();
414   else
415     {
416       printf (_("\
417 Usage: %s [OPTION]... [FILE]...\n\
418   or:  %s [OPTION]... --files0-from=F\n\
419 "),
420               program_name, program_name);
421       fputs (_("\
422 Write sorted concatenation of all FILE(s) to standard output.\n\
423 "), stdout);
424 
425       emit_stdin_note ();
426       emit_mandatory_arg_note ();
427 
428       fputs (_("\
429 Ordering options:\n\
430 \n\
431 "), stdout);
432       fputs (_("\
433   -b, --ignore-leading-blanks  ignore leading blanks\n\
434   -d, --dictionary-order      consider only blanks and alphanumeric characters\
435 \n\
436   -f, --ignore-case           fold lower case to upper case characters\n\
437 "), stdout);
438       fputs (_("\
439   -g, --general-numeric-sort  compare according to general numerical value\n\
440   -i, --ignore-nonprinting    consider only printable characters\n\
441   -M, --month-sort            compare (unknown) < 'JAN' < ... < 'DEC'\n\
442 "), stdout);
443       fputs (_("\
444   -h, --human-numeric-sort    compare human readable numbers (e.g., 2K 1G)\n\
445 "), stdout);
446       fputs (_("\
447   -n, --numeric-sort          compare according to string numerical value;\n\
448                                 see manual for which strings are supported\n\
449   -R, --random-sort           shuffle, but group identical keys.  See shuf(1)\n\
450       --random-source=FILE    get random bytes from FILE\n\
451   -r, --reverse               reverse the result of comparisons\n\
452 "), stdout);
453       fputs (_("\
454       --sort=WORD             sort according to WORD:\n\
455                                 general-numeric -g, human-numeric -h, month -M,\
456 \n\
457                                 numeric -n, random -R, version -V\n\
458   -V, --version-sort          natural sort of (version) numbers within text\n\
459 \n\
460 "), stdout);
461       fputs (_("\
462 Other options:\n\
463 \n\
464 "), stdout);
465       fputs (_("\
466       --batch-size=NMERGE   merge at most NMERGE inputs at once;\n\
467                             for more use temp files\n\
468 "), stdout);
469       fputs (_("\
470   -c, --check, --check=diagnose-first  check for sorted input; do not sort\n\
471   -C, --check=quiet, --check=silent  like -c, but do not report first bad line\
472 \n\
473       --compress-program=PROG  compress temporaries with PROG;\n\
474                               decompress them with PROG -d\n\
475 "), stdout);
476       fputs (_("\
477       --debug               annotate the part of the line used to sort,\n\
478                               and warn about questionable usage to stderr\n\
479       --files0-from=F       read input from the files specified by\n\
480                             NUL-terminated names in file F;\n\
481                             If F is - then read names from standard input\n\
482 "), stdout);
483       fputs (_("\
484   -k, --key=KEYDEF          sort via a key; KEYDEF gives location and type\n\
485   -m, --merge               merge already sorted files; do not sort\n\
486 "), stdout);
487       fputs (_("\
488   -o, --output=FILE         write result to FILE instead of standard output\n\
489   -s, --stable              stabilize sort by disabling last-resort comparison\
490 \n\
491   -S, --buffer-size=SIZE    use SIZE for main memory buffer\n\
492 "), stdout);
493       printf (_("\
494   -t, --field-separator=SEP  use SEP instead of non-blank to blank transition\n\
495   -T, --temporary-directory=DIR  use DIR for temporaries, not $TMPDIR or %s;\n\
496                               multiple options specify multiple directories\n\
497       --parallel=N          change the number of sorts run concurrently to N\n\
498   -u, --unique              with -c, check for strict ordering;\n\
499                               without -c, output only the first of an equal run\
500 \n\
501 "), DEFAULT_TMPDIR);
502       fputs (_("\
503   -z, --zero-terminated     line delimiter is NUL, not newline\n\
504 "), stdout);
505       fputs (HELP_OPTION_DESCRIPTION, stdout);
506       fputs (VERSION_OPTION_DESCRIPTION, stdout);
507       fputs (_("\
508 \n\
509 KEYDEF is F[.C][OPTS][,F[.C][OPTS]] for start and stop position, where F is a\n\
510 field number and C a character position in the field; both are origin 1, and\n\
511 the stop position defaults to the line's end.  If neither -t nor -b is in\n\
512 effect, characters in a field are counted from the beginning of the preceding\n\
513 whitespace.  OPTS is one or more single-letter ordering options [bdfgiMhnRrV],\
514 \n\
515 which override global ordering options for that key.  If no key is given, use\n\
516 the entire line as the key.  Use --debug to diagnose incorrect key usage.\n\
517 \n\
518 SIZE may be followed by the following multiplicative suffixes:\n\
519 "), stdout);
520       fputs (_("\
521 % 1% of memory, b 1, K 1024 (default), and so on for M, G, T, P, E, Z, Y, R, Q.\
522 \n\n\
523 *** WARNING ***\n\
524 The locale specified by the environment affects sort order.\n\
525 Set LC_ALL=C to get the traditional sort order that uses\n\
526 native byte values.\n\
527 "), stdout );
528       emit_ancillary_info (PROGRAM_NAME);
529     }
530 
531   exit (status);
532 }
533 
534 /* For long options that have no equivalent short option, use a
535    non-character as a pseudo short option, starting with CHAR_MAX + 1.  */
536 enum
537 {
538   CHECK_OPTION = CHAR_MAX + 1,
539   COMPRESS_PROGRAM_OPTION,
540   DEBUG_PROGRAM_OPTION,
541   FILES0_FROM_OPTION,
542   NMERGE_OPTION,
543   RANDOM_SOURCE_OPTION,
544   SORT_OPTION,
545   PARALLEL_OPTION
546 };
547 
548 static char const short_options[] = "-bcCdfghik:mMno:rRsS:t:T:uVy:z";
549 
550 static struct option const long_options[] =
551 {
552   {"ignore-leading-blanks", no_argument, nullptr, 'b'},
553   {"check", optional_argument, nullptr, CHECK_OPTION},
554   {"compress-program", required_argument, nullptr, COMPRESS_PROGRAM_OPTION},
555   {"debug", no_argument, nullptr, DEBUG_PROGRAM_OPTION},
556   {"dictionary-order", no_argument, nullptr, 'd'},
557   {"ignore-case", no_argument, nullptr, 'f'},
558   {"files0-from", required_argument, nullptr, FILES0_FROM_OPTION},
559   {"general-numeric-sort", no_argument, nullptr, 'g'},
560   {"ignore-nonprinting", no_argument, nullptr, 'i'},
561   {"key", required_argument, nullptr, 'k'},
562   {"merge", no_argument, nullptr, 'm'},
563   {"month-sort", no_argument, nullptr, 'M'},
564   {"numeric-sort", no_argument, nullptr, 'n'},
565   {"human-numeric-sort", no_argument, nullptr, 'h'},
566   {"version-sort", no_argument, nullptr, 'V'},
567   {"random-sort", no_argument, nullptr, 'R'},
568   {"random-source", required_argument, nullptr, RANDOM_SOURCE_OPTION},
569   {"sort", required_argument, nullptr, SORT_OPTION},
570   {"output", required_argument, nullptr, 'o'},
571   {"reverse", no_argument, nullptr, 'r'},
572   {"stable", no_argument, nullptr, 's'},
573   {"batch-size", required_argument, nullptr, NMERGE_OPTION},
574   {"buffer-size", required_argument, nullptr, 'S'},
575   {"field-separator", required_argument, nullptr, 't'},
576   {"temporary-directory", required_argument, nullptr, 'T'},
577   {"unique", no_argument, nullptr, 'u'},
578   {"zero-terminated", no_argument, nullptr, 'z'},
579   {"parallel", required_argument, nullptr, PARALLEL_OPTION},
580   {GETOPT_HELP_OPTION_DECL},
581   {GETOPT_VERSION_OPTION_DECL},
582   {nullptr, 0, nullptr, 0},
583 };
584 
585 #define CHECK_TABLE \
586   _ct_("quiet",          'C') \
587   _ct_("silent",         'C') \
588   _ct_("diagnose-first", 'c')
589 
590 static char const *const check_args[] =
591 {
592 #define _ct_(_s, _c) _s,
593   CHECK_TABLE nullptr
594 #undef  _ct_
595 };
596 static char const check_types[] =
597 {
598 #define _ct_(_s, _c) _c,
599   CHECK_TABLE
600 #undef  _ct_
601 };
602 
603 #define SORT_TABLE \
604   _st_("general-numeric", 'g') \
605   _st_("human-numeric",   'h') \
606   _st_("month",           'M') \
607   _st_("numeric",         'n') \
608   _st_("random",          'R') \
609   _st_("version",         'V')
610 
611 static char const *const sort_args[] =
612 {
613 #define _st_(_s, _c) _s,
614   SORT_TABLE nullptr
615 #undef  _st_
616 };
617 static char const sort_types[] =
618 {
619 #define _st_(_s, _c) _c,
620   SORT_TABLE
621 #undef  _st_
622 };
623 
624 /* The set of signals that are caught.  */
625 static sigset_t caught_signals;
626 
627 /* Critical section status.  */
628 struct cs_status
629 {
630   bool valid;
631   sigset_t sigs;
632 };
633 
634 /* Enter a critical section.  */
635 static void
cs_enter(struct cs_status * status)636 cs_enter (struct cs_status *status)
637 {
638   int ret = pthread_sigmask (SIG_BLOCK, &caught_signals, &status->sigs);
639   status->valid = ret == 0;
640 }
641 
642 /* Leave a critical section.  */
643 static void
cs_leave(struct cs_status const * status)644 cs_leave (struct cs_status const *status)
645 {
646   if (status->valid)
647     {
648       /* Ignore failure when restoring the signal mask. */
649       pthread_sigmask (SIG_SETMASK, &status->sigs, nullptr);
650     }
651 }
652 
653 /* Possible states for a temp file.  If compressed, the file's status
654    is unreaped or reaped, depending on whether 'sort' has waited for
655    the subprocess to finish.  */
656 enum { UNCOMPRESSED, UNREAPED, REAPED };
657 
658 /* The list of temporary files. */
659 struct tempnode
660 {
661   struct tempnode *volatile next;
662   pid_t pid;     /* The subprocess PID; undefined if state == UNCOMPRESSED.  */
663   char state;
664   char name[FLEXIBLE_ARRAY_MEMBER];
665 };
666 static struct tempnode *volatile temphead;
667 static struct tempnode *volatile *temptail = &temphead;
668 
669 /* A file to be sorted.  */
670 struct sortfile
671 {
672   /* The file's name.  */
673   char const *name;
674 
675   /* Non-null if this is a temporary file, in which case NAME == TEMP->name.  */
676   struct tempnode *temp;
677 };
678 
679 /* Map PIDs of unreaped subprocesses to their struct tempnode objects.  */
680 static Hash_table *proctab;
681 
682 enum { INIT_PROCTAB_SIZE = 47 };
683 
684 static size_t
proctab_hasher(void const * entry,size_t tabsize)685 proctab_hasher (void const *entry, size_t tabsize)
686 {
687   struct tempnode const *node = entry;
688   return node->pid % tabsize;
689 }
690 
691 static bool
proctab_comparator(void const * e1,void const * e2)692 proctab_comparator (void const *e1, void const *e2)
693 {
694   struct tempnode const *n1 = e1;
695   struct tempnode const *n2 = e2;
696   return n1->pid == n2->pid;
697 }
698 
699 /* The number of unreaped child processes.  */
700 static pid_t nprocs;
701 
702 static bool delete_proc (pid_t);
703 
704 /* If PID is positive, wait for the child process with that PID to
705    exit, and assume that PID has already been removed from the process
706    table.  If PID is 0 or -1, clean up some child that has exited (by
707    waiting for it, and removing it from the proc table) and return the
708    child's process ID.  However, if PID is 0 and no children have
709    exited, return 0 without waiting.  */
710 
711 static pid_t
reap(pid_t pid)712 reap (pid_t pid)
713 {
714   int status;
715   pid_t cpid = waitpid ((pid ? pid : -1), &status, (pid ? 0 : WNOHANG));
716 
717   if (cpid < 0)
718     error (SORT_FAILURE, errno, _("waiting for %s [-d]"),
719            quoteaf (compress_program));
720   else if (0 < cpid && (0 < pid || delete_proc (cpid)))
721     {
722       if (! WIFEXITED (status) || WEXITSTATUS (status))
723         error (SORT_FAILURE, 0, _("%s [-d] terminated abnormally"),
724                quoteaf (compress_program));
725       --nprocs;
726     }
727 
728   return cpid;
729 }
730 
731 /* TEMP represents a new process; add it to the process table.  Create
732    the process table the first time it's called.  */
733 
734 static void
register_proc(struct tempnode * temp)735 register_proc (struct tempnode *temp)
736 {
737   if (! proctab)
738     {
739       proctab = hash_initialize (INIT_PROCTAB_SIZE, nullptr,
740                                  proctab_hasher,
741                                  proctab_comparator,
742                                  nullptr);
743       if (! proctab)
744         xalloc_die ();
745     }
746 
747   temp->state = UNREAPED;
748 
749   if (! hash_insert (proctab, temp))
750     xalloc_die ();
751 }
752 
753 /* If PID is in the process table, remove it and return true.
754    Otherwise, return false.  */
755 
756 static bool
delete_proc(pid_t pid)757 delete_proc (pid_t pid)
758 {
759   struct tempnode test;
760 
761   test.pid = pid;
762   struct tempnode *node = hash_remove (proctab, &test);
763   if (! node)
764     return false;
765   node->state = REAPED;
766   return true;
767 }
768 
769 /* Remove PID from the process table, and wait for it to exit if it
770    hasn't already.  */
771 
772 static void
wait_proc(pid_t pid)773 wait_proc (pid_t pid)
774 {
775   if (delete_proc (pid))
776     reap (pid);
777 }
778 
779 /* Reap any exited children.  Do not block; reap only those that have
780    already exited.  */
781 
782 static void
reap_exited(void)783 reap_exited (void)
784 {
785   while (0 < nprocs && reap (0))
786     continue;
787 }
788 
789 /* Reap at least one exited child, waiting if necessary.  */
790 
791 static void
reap_some(void)792 reap_some (void)
793 {
794   reap (-1);
795   reap_exited ();
796 }
797 
798 /* Reap all children, waiting if necessary.  */
799 
800 static void
reap_all(void)801 reap_all (void)
802 {
803   while (0 < nprocs)
804     reap (-1);
805 }
806 
807 /* Clean up any remaining temporary files.  */
808 
809 static void
cleanup(void)810 cleanup (void)
811 {
812   struct tempnode const *node;
813 
814   for (node = temphead; node; node = node->next)
815     unlink (node->name);
816   temphead = nullptr;
817 }
818 
819 /* Cleanup actions to take when exiting.  */
820 
821 static void
exit_cleanup(void)822 exit_cleanup (void)
823 {
824   if (temphead)
825     {
826       /* Clean up any remaining temporary files in a critical section so
827          that a signal handler does not try to clean them too.  */
828       struct cs_status cs;
829       cs_enter (&cs);
830       cleanup ();
831       cs_leave (&cs);
832     }
833 
834   close_stdout ();
835 }
836 
837 /* Create a new temporary file, returning its newly allocated tempnode.
838    Store into *PFD the file descriptor open for writing.
839    If the creation fails, return nullptr and store -1 into *PFD if the
840    failure is due to file descriptor exhaustion and
841    SURVIVE_FD_EXHAUSTION; otherwise, die.  */
842 
843 static struct tempnode *
create_temp_file(int * pfd,bool survive_fd_exhaustion)844 create_temp_file (int *pfd, bool survive_fd_exhaustion)
845 {
846   static char const slashbase[] = "/sortXXXXXX";
847   static size_t temp_dir_index;
848   int fd;
849   int saved_errno;
850   char const *temp_dir = temp_dirs[temp_dir_index];
851   size_t len = strlen (temp_dir);
852   struct tempnode *node =
853     xmalloc (FLEXSIZEOF (struct tempnode, name, len + sizeof slashbase));
854   char *file = node->name;
855   struct cs_status cs;
856 
857   memcpy (file, temp_dir, len);
858   memcpy (file + len, slashbase, sizeof slashbase);
859   node->next = nullptr;
860   if (++temp_dir_index == temp_dir_count)
861     temp_dir_index = 0;
862 
863   /* Create the temporary file in a critical section, to avoid races.  */
864   cs_enter (&cs);
865   fd = mkostemp (file, O_CLOEXEC);
866   if (0 <= fd)
867     {
868       *temptail = node;
869       temptail = &node->next;
870     }
871   saved_errno = errno;
872   cs_leave (&cs);
873   errno = saved_errno;
874 
875   if (fd < 0)
876     {
877       if (! (survive_fd_exhaustion && errno == EMFILE))
878         error (SORT_FAILURE, errno, _("cannot create temporary file in %s"),
879                quoteaf (temp_dir));
880       free (node);
881       node = nullptr;
882     }
883 
884   *pfd = fd;
885   return node;
886 }
887 
888 /* Return a pointer to stdout status, or nullptr on failure.  */
889 
890 static struct stat *
get_outstatus(void)891 get_outstatus (void)
892 {
893   static int outstat_errno;
894   static struct stat outstat;
895   if (outstat_errno == 0)
896     outstat_errno = fstat (STDOUT_FILENO, &outstat) == 0 ? -1 : errno;
897   return outstat_errno < 0 ? &outstat : nullptr;
898 }
899 
900 /* Return a stream for FILE, opened with mode HOW.  If HOW is "w",
901    the file is already open on standard output, and needs to be
902    truncated unless FILE is null.  When opening for input, "-"
903    means standard input.  To avoid confusion, do not return file
904    descriptors STDIN_FILENO, STDOUT_FILENO, or STDERR_FILENO when
905    opening an ordinary FILE.  Return nullptr if unsuccessful.
906 
907    Use fadvise to specify an access pattern for input files.
908    There are a few hints we could possibly provide,
909    and after careful testing it was decided that
910    specifying FADVISE_SEQUENTIAL was not detrimental
911    to any cases.  On Linux 2.6.31, this option doubles
912    the size of read ahead performed and thus was seen to
913    benefit these cases:
914      Merging
915      Sorting with a smaller internal buffer
916      Reading from faster flash devices
917 
918    In _addition_ one could also specify other hints...
919 
920    FADVISE_WILLNEED was tested, but Linux 2.6.31
921    at least uses that to _synchronously_ prepopulate the cache
922    with the specified range.  While sort does need to
923    read all of its input before outputting, a synchronous
924    read of the whole file up front precludes any processing
925    that sort could do in parallel with the system doing
926    read ahead of the data. This was seen to have negative effects
927    in a couple of cases:
928      Merging
929      Sorting with a smaller internal buffer
930    This option was seen to shorten the runtime for sort
931    on a multicore system with lots of RAM and other processes
932    competing for CPU.  It could be argued that more explicit
933    scheduling hints with 'nice' et. al. are more appropriate
934    for this situation.
935 
936    FADVISE_NOREUSE is a possibility as it could lower
937    the priority of input data in the cache as sort will
938    only need to process it once.  However its functionality
939    has changed over Linux kernel versions and as of 2.6.31
940    it does nothing and thus we can't depend on what it might
941    do in future.
942 
943    FADVISE_DONTNEED is not appropriate for user specified
944    input files, but for temp files we do want to drop the
945    cache immediately after processing.  This is done implicitly
946    however when the files are unlinked.  */
947 
948 static FILE *
stream_open(char const * file,char const * how)949 stream_open (char const *file, char const *how)
950 {
951   FILE *fp;
952 
953   if (*how == 'r')
954     {
955       if (STREQ (file, "-"))
956         {
957           have_read_stdin = true;
958           fp = stdin;
959         }
960       else
961         {
962           int fd = open (file, O_RDONLY | O_CLOEXEC);
963           fp = fd < 0 ? nullptr : fdopen (fd, how);
964         }
965       fadvise (fp, FADVISE_SEQUENTIAL);
966     }
967   else if (*how == 'w')
968     {
969       if (file && ftruncate (STDOUT_FILENO, 0) != 0)
970         {
971           int ftruncate_errno = errno;
972           struct stat *outst = get_outstatus ();
973           if (!outst || S_ISREG (outst->st_mode) || S_TYPEISSHM (outst))
974             error (SORT_FAILURE, ftruncate_errno, _("%s: error truncating"),
975                    quotef (file));
976         }
977       fp = stdout;
978     }
979   else
980     affirm (!"unexpected mode passed to stream_open");
981 
982   return fp;
983 }
984 
985 /* Same as stream_open, except always return a non-null value; die on
986    failure.  */
987 
988 static FILE *
xfopen(char const * file,char const * how)989 xfopen (char const *file, char const *how)
990 {
991   FILE *fp = stream_open (file, how);
992   if (!fp)
993     sort_die (_("open failed"), file);
994   return fp;
995 }
996 
997 /* Close FP, whose name is FILE, and report any errors.  */
998 
999 static void
xfclose(FILE * fp,char const * file)1000 xfclose (FILE *fp, char const *file)
1001 {
1002   switch (fileno (fp))
1003     {
1004     case STDIN_FILENO:
1005       /* Allow reading stdin from tty more than once.  */
1006       clearerr (fp);
1007       break;
1008 
1009     case STDOUT_FILENO:
1010       /* Don't close stdout just yet.  close_stdout does that.  */
1011       if (fflush (fp) != 0)
1012         sort_die (_("fflush failed"), file);
1013       break;
1014 
1015     default:
1016       if (fclose (fp) != 0)
1017         sort_die (_("close failed"), file);
1018       break;
1019     }
1020 }
1021 
1022 /* Move OLDFD to NEWFD.  If OLDFD != NEWFD, NEWFD is not close-on-exec.  */
1023 
1024 static void
move_fd(int oldfd,int newfd)1025 move_fd (int oldfd, int newfd)
1026 {
1027   if (oldfd != newfd)
1028     {
1029       /* These should never fail for our usage.  */
1030       ignore_value (dup2 (oldfd, newfd));
1031       ignore_value (close (oldfd));
1032     }
1033 }
1034 
1035 /* Fork a child process for piping to and do common cleanup.  The
1036    TRIES parameter specifies how many times to try to fork before
1037    giving up.  Return the PID of the child, or -1 (setting errno)
1038    on failure. */
1039 
1040 static pid_t
pipe_fork(int pipefds[2],size_t tries)1041 pipe_fork (int pipefds[2], size_t tries)
1042 {
1043 #if HAVE_WORKING_FORK
1044   struct tempnode *saved_temphead;
1045   int saved_errno;
1046   double wait_retry = 0.25;
1047   pid_t pid;
1048   struct cs_status cs;
1049 
1050   if (pipe2 (pipefds, O_CLOEXEC) < 0)
1051     return -1;
1052 
1053   /* At least NMERGE + 1 subprocesses are needed.  More could be created, but
1054      uncontrolled subprocess generation can hurt performance significantly.
1055      Allow at most NMERGE + 2 subprocesses, on the theory that there
1056      may be some useful parallelism by letting compression for the
1057      previous merge finish (1 subprocess) in parallel with the current
1058      merge (NMERGE + 1 subprocesses).  */
1059 
1060   if (nmerge + 1 < nprocs)
1061     reap_some ();
1062 
1063   while (tries--)
1064     {
1065       /* This is so the child process won't delete our temp files
1066          if it receives a signal before exec-ing.  */
1067       cs_enter (&cs);
1068       saved_temphead = temphead;
1069       temphead = nullptr;
1070 
1071       pid = fork ();
1072       saved_errno = errno;
1073       if (pid)
1074         temphead = saved_temphead;
1075 
1076       cs_leave (&cs);
1077       errno = saved_errno;
1078 
1079       if (0 <= pid || errno != EAGAIN)
1080         break;
1081       else
1082         {
1083           xnanosleep (wait_retry);
1084           wait_retry *= 2;
1085           reap_exited ();
1086         }
1087     }
1088 
1089   if (pid < 0)
1090     {
1091       saved_errno = errno;
1092       close (pipefds[0]);
1093       close (pipefds[1]);
1094       errno = saved_errno;
1095     }
1096   else if (pid == 0)
1097     {
1098       close (STDIN_FILENO);
1099       close (STDOUT_FILENO);
1100     }
1101   else
1102     ++nprocs;
1103 
1104   return pid;
1105 
1106 #else  /* ! HAVE_WORKING_FORK */
1107   return -1;
1108 #endif
1109 }
1110 
1111 /* Create a temporary file and, if asked for, start a compressor
1112    to that file.  Set *PFP to the file handle and return
1113    the address of the new temp node.  If the creation
1114    fails, return nullptr if the failure is due to file descriptor
1115    exhaustion and SURVIVE_FD_EXHAUSTION; otherwise, die.  */
1116 
1117 static struct tempnode *
maybe_create_temp(FILE ** pfp,bool survive_fd_exhaustion)1118 maybe_create_temp (FILE **pfp, bool survive_fd_exhaustion)
1119 {
1120   int tempfd;
1121   struct tempnode *node = create_temp_file (&tempfd, survive_fd_exhaustion);
1122   if (! node)
1123     return nullptr;
1124 
1125   node->state = UNCOMPRESSED;
1126 
1127   if (compress_program)
1128     {
1129       int pipefds[2];
1130 
1131       node->pid = pipe_fork (pipefds, MAX_FORK_TRIES_COMPRESS);
1132       if (0 < node->pid)
1133         {
1134           close (tempfd);
1135           close (pipefds[0]);
1136           tempfd = pipefds[1];
1137 
1138           register_proc (node);
1139         }
1140       else if (node->pid == 0)
1141         {
1142           /* Being the child of a multithreaded program before exec,
1143              we're restricted to calling async-signal-safe routines here.  */
1144           close (pipefds[1]);
1145           move_fd (tempfd, STDOUT_FILENO);
1146           move_fd (pipefds[0], STDIN_FILENO);
1147 
1148           execlp (compress_program, compress_program, (char *) nullptr);
1149 
1150           async_safe_die (errno, "couldn't execute compress program");
1151         }
1152     }
1153 
1154   *pfp = fdopen (tempfd, "w");
1155   if (! *pfp)
1156     sort_die (_("couldn't create temporary file"), node->name);
1157 
1158   return node;
1159 }
1160 
1161 /* Create a temporary file and, if asked for, start a compressor
1162    to that file.  Set *PFP to the file handle and return the address
1163    of the new temp node.  Die on failure.  */
1164 
1165 static struct tempnode *
create_temp(FILE ** pfp)1166 create_temp (FILE **pfp)
1167 {
1168   return maybe_create_temp (pfp, false);
1169 }
1170 
1171 /* Open a compressed temp file and start a decompression process through
1172    which to filter the input.  Return nullptr (setting errno to
1173    EMFILE) if we ran out of file descriptors, and die on any other
1174    kind of failure.  */
1175 
1176 static FILE *
open_temp(struct tempnode * temp)1177 open_temp (struct tempnode *temp)
1178 {
1179   int tempfd, pipefds[2];
1180   FILE *fp = nullptr;
1181 
1182   if (temp->state == UNREAPED)
1183     wait_proc (temp->pid);
1184 
1185   tempfd = open (temp->name, O_RDONLY);
1186   if (tempfd < 0)
1187     return nullptr;
1188 
1189   pid_t child = pipe_fork (pipefds, MAX_FORK_TRIES_DECOMPRESS);
1190 
1191   switch (child)
1192     {
1193     case -1:
1194       if (errno != EMFILE)
1195         error (SORT_FAILURE, errno, _("couldn't create process for %s -d"),
1196                quoteaf (compress_program));
1197       close (tempfd);
1198       errno = EMFILE;
1199       break;
1200 
1201     case 0:
1202       /* Being the child of a multithreaded program before exec,
1203          we're restricted to calling async-signal-safe routines here.  */
1204       close (pipefds[0]);
1205       move_fd (tempfd, STDIN_FILENO);
1206       move_fd (pipefds[1], STDOUT_FILENO);
1207 
1208       execlp (compress_program, compress_program, "-d", (char *) nullptr);
1209 
1210       async_safe_die (errno, "couldn't execute compress program (with -d)");
1211 
1212     default:
1213       temp->pid = child;
1214       register_proc (temp);
1215       close (tempfd);
1216       close (pipefds[1]);
1217 
1218       fp = fdopen (pipefds[0], "r");
1219       if (! fp)
1220         {
1221           int saved_errno = errno;
1222           close (pipefds[0]);
1223           errno = saved_errno;
1224         }
1225       break;
1226     }
1227 
1228   return fp;
1229 }
1230 
1231 /* Append DIR to the array of temporary directory names.  */
1232 static void
add_temp_dir(char const * dir)1233 add_temp_dir (char const *dir)
1234 {
1235   if (temp_dir_count == temp_dir_alloc)
1236     temp_dirs = X2NREALLOC (temp_dirs, &temp_dir_alloc);
1237 
1238   temp_dirs[temp_dir_count++] = dir;
1239 }
1240 
1241 /* Remove NAME from the list of temporary files.  */
1242 
1243 static void
zaptemp(char const * name)1244 zaptemp (char const *name)
1245 {
1246   struct tempnode *volatile *pnode;
1247   struct tempnode *node;
1248   struct tempnode *next;
1249   int unlink_status;
1250   int unlink_errno = 0;
1251   struct cs_status cs;
1252 
1253   for (pnode = &temphead; (node = *pnode)->name != name; pnode = &node->next)
1254     continue;
1255 
1256   if (node->state == UNREAPED)
1257     wait_proc (node->pid);
1258 
1259   /* Unlink the temporary file in a critical section to avoid races.  */
1260   next = node->next;
1261   cs_enter (&cs);
1262   unlink_status = unlink (name);
1263   unlink_errno = errno;
1264   *pnode = next;
1265   cs_leave (&cs);
1266 
1267   if (unlink_status != 0)
1268     error (0, unlink_errno, _("warning: cannot remove: %s"), quotef (name));
1269   if (! next)
1270     temptail = pnode;
1271   free (node);
1272 }
1273 
1274 #if HAVE_NL_LANGINFO
1275 
1276 static int
struct_month_cmp(void const * m1,void const * m2)1277 struct_month_cmp (void const *m1, void const *m2)
1278 {
1279   struct month const *month1 = m1;
1280   struct month const *month2 = m2;
1281   return strcmp (month1->name, month2->name);
1282 }
1283 
1284 #endif
1285 
1286 /* Initialize the character class tables. */
1287 
1288 static void
inittables(void)1289 inittables (void)
1290 {
1291   size_t i;
1292 
1293   for (i = 0; i < UCHAR_LIM; ++i)
1294     {
1295       blanks[i] = field_sep (i);
1296       nonprinting[i] = ! isprint (i);
1297       nondictionary[i] = ! isalnum (i) && ! field_sep (i);
1298       fold_toupper[i] = toupper (i);
1299     }
1300 
1301 #if HAVE_NL_LANGINFO
1302   /* If we're not in the "C" locale, read different names for months.  */
1303   if (hard_LC_TIME)
1304     {
1305       for (i = 0; i < MONTHS_PER_YEAR; i++)
1306         {
1307           char const *s;
1308           size_t s_len;
1309           size_t j, k;
1310           char *name;
1311 
1312           s = nl_langinfo (ABMON_1 + i);
1313           s_len = strlen (s);
1314           monthtab[i].name = name = xmalloc (s_len + 1);
1315           monthtab[i].val = i + 1;
1316 
1317           for (j = k = 0; j < s_len; j++)
1318             if (! isblank (to_uchar (s[j])))
1319               name[k++] = fold_toupper[to_uchar (s[j])];
1320           name[k] = '\0';
1321         }
1322       qsort (monthtab, MONTHS_PER_YEAR, sizeof *monthtab, struct_month_cmp);
1323     }
1324 #endif
1325 }
1326 
1327 /* Specify how many inputs may be merged at once.
1328    This may be set on the command-line with the
1329    --batch-size option. */
1330 static void
specify_nmerge(int oi,char c,char const * s)1331 specify_nmerge (int oi, char c, char const *s)
1332 {
1333   uintmax_t n;
1334   struct rlimit rlimit;
1335   enum strtol_error e = xstrtoumax (s, nullptr, 10, &n, "");
1336 
1337   /* Try to find out how many file descriptors we'll be able
1338      to open.  We need at least nmerge + 3 (STDIN_FILENO,
1339      STDOUT_FILENO and STDERR_FILENO). */
1340   unsigned int max_nmerge = ((getrlimit (RLIMIT_NOFILE, &rlimit) == 0
1341                               ? rlimit.rlim_cur
1342                               : OPEN_MAX)
1343                              - 3);
1344 
1345   if (e == LONGINT_OK)
1346     {
1347       nmerge = n;
1348       if (nmerge != n)
1349         e = LONGINT_OVERFLOW;
1350       else
1351         {
1352           if (nmerge < 2)
1353             {
1354               error (0, 0, _("invalid --%s argument %s"),
1355                      long_options[oi].name, quote (s));
1356               error (SORT_FAILURE, 0,
1357                      _("minimum --%s argument is %s"),
1358                      long_options[oi].name, quote ("2"));
1359             }
1360           else if (max_nmerge < nmerge)
1361             {
1362               e = LONGINT_OVERFLOW;
1363             }
1364           else
1365             return;
1366         }
1367     }
1368 
1369   if (e == LONGINT_OVERFLOW)
1370     {
1371       char max_nmerge_buf[INT_BUFSIZE_BOUND (max_nmerge)];
1372       error (0, 0, _("--%s argument %s too large"),
1373              long_options[oi].name, quote (s));
1374       error (SORT_FAILURE, 0,
1375              _("maximum --%s argument with current rlimit is %s"),
1376              long_options[oi].name,
1377              uinttostr (max_nmerge, max_nmerge_buf));
1378     }
1379   else
1380     xstrtol_fatal (e, oi, c, long_options, s);
1381 }
1382 
1383 /* Specify the amount of main memory to use when sorting.  */
1384 static void
specify_sort_size(int oi,char c,char const * s)1385 specify_sort_size (int oi, char c, char const *s)
1386 {
1387   uintmax_t n;
1388   char *suffix;
1389   enum strtol_error e = xstrtoumax (s, &suffix, 10, &n, "EgGkKmMPQRtTYZ");
1390 
1391   /* The default unit is KiB.  */
1392   if (e == LONGINT_OK && ISDIGIT (suffix[-1]))
1393     {
1394       if (n <= UINTMAX_MAX / 1024)
1395         n *= 1024;
1396       else
1397         e = LONGINT_OVERFLOW;
1398     }
1399 
1400   /* A 'b' suffix means bytes; a '%' suffix means percent of memory.  */
1401   if (e == LONGINT_INVALID_SUFFIX_CHAR && ISDIGIT (suffix[-1]) && ! suffix[1])
1402     switch (suffix[0])
1403       {
1404       case 'b':
1405         e = LONGINT_OK;
1406         break;
1407 
1408       case '%':
1409         {
1410           double mem = physmem_total () * n / 100;
1411 
1412           /* Use "<", not "<=", to avoid problems with rounding.  */
1413           if (mem < UINTMAX_MAX)
1414             {
1415               n = mem;
1416               e = LONGINT_OK;
1417             }
1418           else
1419             e = LONGINT_OVERFLOW;
1420         }
1421         break;
1422       }
1423 
1424   if (e == LONGINT_OK)
1425     {
1426       /* If multiple sort sizes are specified, take the maximum, so
1427          that option order does not matter.  */
1428       if (n < sort_size)
1429         return;
1430 
1431       sort_size = n;
1432       if (sort_size == n)
1433         {
1434           sort_size = MAX (sort_size, MIN_SORT_SIZE);
1435           return;
1436         }
1437 
1438       e = LONGINT_OVERFLOW;
1439     }
1440 
1441   xstrtol_fatal (e, oi, c, long_options, s);
1442 }
1443 
1444 /* Specify the number of threads to spawn during internal sort.  */
1445 static size_t
specify_nthreads(int oi,char c,char const * s)1446 specify_nthreads (int oi, char c, char const *s)
1447 {
1448   uintmax_t nthreads;
1449   enum strtol_error e = xstrtoumax (s, nullptr, 10, &nthreads, "");
1450   if (e == LONGINT_OVERFLOW)
1451     return SIZE_MAX;
1452   if (e != LONGINT_OK)
1453     xstrtol_fatal (e, oi, c, long_options, s);
1454   if (SIZE_MAX < nthreads)
1455     nthreads = SIZE_MAX;
1456   if (nthreads == 0)
1457     error (SORT_FAILURE, 0, _("number in parallel must be nonzero"));
1458   return nthreads;
1459 }
1460 
1461 /* Return the default sort size.  */
1462 static size_t
default_sort_size(void)1463 default_sort_size (void)
1464 {
1465   /* Let SIZE be MEM, but no more than the maximum object size,
1466      total memory, or system resource limits.  Don't bother to check
1467      for values like RLIM_INFINITY since in practice they are not much
1468      less than SIZE_MAX.  */
1469   size_t size = SIZE_MAX;
1470   struct rlimit rlimit;
1471   if (getrlimit (RLIMIT_DATA, &rlimit) == 0 && rlimit.rlim_cur < size)
1472     size = rlimit.rlim_cur;
1473 #ifdef RLIMIT_AS
1474   if (getrlimit (RLIMIT_AS, &rlimit) == 0 && rlimit.rlim_cur < size)
1475     size = rlimit.rlim_cur;
1476 #endif
1477 
1478   /* Leave a large safety margin for the above limits, as failure can
1479      occur when they are exceeded.  */
1480   size /= 2;
1481 
1482 #ifdef RLIMIT_RSS
1483   /* Leave a 1/16 margin for RSS to leave room for code, stack, etc.
1484      Exceeding RSS is not fatal, but can be quite slow.  */
1485   if (getrlimit (RLIMIT_RSS, &rlimit) == 0 && rlimit.rlim_cur / 16 * 15 < size)
1486     size = rlimit.rlim_cur / 16 * 15;
1487 #endif
1488 
1489   /* Let MEM be available memory or 1/8 of total memory, whichever
1490      is greater.  */
1491   double avail = physmem_available ();
1492   double total = physmem_total ();
1493   double mem = MAX (avail, total / 8);
1494 
1495   /* Leave a 1/4 margin for physical memory.  */
1496   if (total * 0.75 < size)
1497     size = total * 0.75;
1498 
1499   /* Return the minimum of MEM and SIZE, but no less than
1500      MIN_SORT_SIZE.  Avoid the MIN macro here, as it is not quite
1501      right when only one argument is floating point.  */
1502   if (mem < size)
1503     size = mem;
1504   return MAX (size, MIN_SORT_SIZE);
1505 }
1506 
1507 /* Return the sort buffer size to use with the input files identified
1508    by FPS and FILES, which are alternate names of the same files.
1509    NFILES gives the number of input files; NFPS may be less.  Assume
1510    that each input line requires LINE_BYTES extra bytes' worth of line
1511    information.  Do not exceed the size bound specified by the user
1512    (or a default size bound, if the user does not specify one).  */
1513 
1514 static size_t
sort_buffer_size(FILE * const * fps,size_t nfps,char * const * files,size_t nfiles,size_t line_bytes)1515 sort_buffer_size (FILE *const *fps, size_t nfps,
1516                   char *const *files, size_t nfiles,
1517                   size_t line_bytes)
1518 {
1519   /* A bound on the input size.  If zero, the bound hasn't been
1520      determined yet.  */
1521   static size_t size_bound;
1522 
1523   /* In the worst case, each input byte is a newline.  */
1524   size_t worst_case_per_input_byte = line_bytes + 1;
1525 
1526   /* Keep enough room for one extra input line and an extra byte.
1527      This extra room might be needed when preparing to read EOF.  */
1528   size_t size = worst_case_per_input_byte + 1;
1529 
1530   for (size_t i = 0; i < nfiles; i++)
1531     {
1532       struct stat st;
1533       off_t file_size;
1534       size_t worst_case;
1535 
1536       if ((i < nfps ? fstat (fileno (fps[i]), &st)
1537            : STREQ (files[i], "-") ? fstat (STDIN_FILENO, &st)
1538            : stat (files[i], &st))
1539           != 0)
1540         sort_die (_("stat failed"), files[i]);
1541 
1542       if (S_ISREG (st.st_mode))
1543         file_size = st.st_size;
1544       else
1545         {
1546           /* The file has unknown size.  If the user specified a sort
1547              buffer size, use that; otherwise, guess the size.  */
1548           if (sort_size)
1549             return sort_size;
1550           file_size = INPUT_FILE_SIZE_GUESS;
1551         }
1552 
1553       if (! size_bound)
1554         {
1555           size_bound = sort_size;
1556           if (! size_bound)
1557             size_bound = default_sort_size ();
1558         }
1559 
1560       /* Add the amount of memory needed to represent the worst case
1561          where the input consists entirely of newlines followed by a
1562          single non-newline.  Check for overflow.  */
1563       worst_case = file_size * worst_case_per_input_byte + 1;
1564       if (file_size != worst_case / worst_case_per_input_byte
1565           || size_bound - size <= worst_case)
1566         return size_bound;
1567       size += worst_case;
1568     }
1569 
1570   return size;
1571 }
1572 
1573 /* Initialize BUF.  Reserve LINE_BYTES bytes for each line; LINE_BYTES
1574    must be at least sizeof (struct line).  Allocate ALLOC bytes
1575    initially.  */
1576 
1577 static void
initbuf(struct buffer * buf,size_t line_bytes,size_t alloc)1578 initbuf (struct buffer *buf, size_t line_bytes, size_t alloc)
1579 {
1580   /* Ensure that the line array is properly aligned.  If the desired
1581      size cannot be allocated, repeatedly halve it until allocation
1582      succeeds.  The smaller allocation may hurt overall performance,
1583      but that's better than failing.  */
1584   while (true)
1585     {
1586       alloc += sizeof (struct line) - alloc % sizeof (struct line);
1587       buf->buf = malloc (alloc);
1588       if (buf->buf)
1589         break;
1590       alloc /= 2;
1591       if (alloc <= line_bytes + 1)
1592         xalloc_die ();
1593     }
1594 
1595   buf->line_bytes = line_bytes;
1596   buf->alloc = alloc;
1597   buf->used = buf->left = buf->nlines = 0;
1598   buf->eof = false;
1599 }
1600 
1601 /* Return one past the limit of the line array.  */
1602 
1603 static inline struct line *
buffer_linelim(struct buffer const * buf)1604 buffer_linelim (struct buffer const *buf)
1605 {
1606   void *linelim = buf->buf + buf->alloc;
1607   return linelim;
1608 }
1609 
1610 /* Return a pointer to the first character of the field specified
1611    by KEY in LINE. */
1612 
1613 static char *
begfield(struct line const * line,struct keyfield const * key)1614 begfield (struct line const *line, struct keyfield const *key)
1615 {
1616   char *ptr = line->text, *lim = ptr + line->length - 1;
1617   size_t sword = key->sword;
1618   size_t schar = key->schar;
1619 
1620   /* The leading field separator itself is included in a field when -t
1621      is absent.  */
1622 
1623   if (tab != TAB_DEFAULT)
1624     while (ptr < lim && sword--)
1625       {
1626         while (ptr < lim && *ptr != tab)
1627           ++ptr;
1628         if (ptr < lim)
1629           ++ptr;
1630       }
1631   else
1632     while (ptr < lim && sword--)
1633       {
1634         while (ptr < lim && blanks[to_uchar (*ptr)])
1635           ++ptr;
1636         while (ptr < lim && !blanks[to_uchar (*ptr)])
1637           ++ptr;
1638       }
1639 
1640   /* If we're ignoring leading blanks when computing the Start
1641      of the field, skip past them here.  */
1642   if (key->skipsblanks)
1643     while (ptr < lim && blanks[to_uchar (*ptr)])
1644       ++ptr;
1645 
1646   /* Advance PTR by SCHAR (if possible), but no further than LIM.  */
1647   ptr = MIN (lim, ptr + schar);
1648 
1649   return ptr;
1650 }
1651 
1652 /* Return the limit of (a pointer to the first character after) the field
1653    in LINE specified by KEY. */
1654 
1655 ATTRIBUTE_PURE
1656 static char *
limfield(struct line const * line,struct keyfield const * key)1657 limfield (struct line const *line, struct keyfield const *key)
1658 {
1659   char *ptr = line->text, *lim = ptr + line->length - 1;
1660   size_t eword = key->eword, echar = key->echar;
1661 
1662   if (echar == 0)
1663     eword++; /* Skip all of end field.  */
1664 
1665   /* Move PTR past EWORD fields or to one past the last byte on LINE,
1666      whichever comes first.  If there are more than EWORD fields, leave
1667      PTR pointing at the beginning of the field having zero-based index,
1668      EWORD.  If a delimiter character was specified (via -t), then that
1669      'beginning' is the first character following the delimiting TAB.
1670      Otherwise, leave PTR pointing at the first 'blank' character after
1671      the preceding field.  */
1672   if (tab != TAB_DEFAULT)
1673     while (ptr < lim && eword--)
1674       {
1675         while (ptr < lim && *ptr != tab)
1676           ++ptr;
1677         if (ptr < lim && (eword || echar))
1678           ++ptr;
1679       }
1680   else
1681     while (ptr < lim && eword--)
1682       {
1683         while (ptr < lim && blanks[to_uchar (*ptr)])
1684           ++ptr;
1685         while (ptr < lim && !blanks[to_uchar (*ptr)])
1686           ++ptr;
1687       }
1688 
1689 #ifdef POSIX_UNSPECIFIED
1690   /* The following block of code makes GNU sort incompatible with
1691      standard Unix sort, so it's ifdef'd out for now.
1692      The POSIX spec isn't clear on how to interpret this.
1693      FIXME: request clarification.
1694 
1695      From: kwzh@gnu.ai.mit.edu (Karl Heuer)
1696      Date: Thu, 30 May 96 12:20:41 -0400
1697      [Translated to POSIX 1003.1-2001 terminology by Paul Eggert.]
1698 
1699      [...]I believe I've found another bug in 'sort'.
1700 
1701      $ cat /tmp/sort.in
1702      a b c 2 d
1703      pq rs 1 t
1704      $ textutils-1.15/src/sort -k1.7,1.7 </tmp/sort.in
1705      a b c 2 d
1706      pq rs 1 t
1707      $ /bin/sort -k1.7,1.7 </tmp/sort.in
1708      pq rs 1 t
1709      a b c 2 d
1710 
1711      Unix sort produced the answer I expected: sort on the single character
1712      in column 7.  GNU sort produced different results, because it disagrees
1713      on the interpretation of the key-end spec "M.N".  Unix sort reads this
1714      as "skip M-1 fields, then N-1 characters"; but GNU sort wants it to mean
1715      "skip M-1 fields, then either N-1 characters or the rest of the current
1716      field, whichever comes first".  This extra clause applies only to
1717      key-ends, not key-starts.
1718      */
1719 
1720   /* Make LIM point to the end of (one byte past) the current field.  */
1721   if (tab != TAB_DEFAULT)
1722     {
1723       char *newlim;
1724       newlim = memchr (ptr, tab, lim - ptr);
1725       if (newlim)
1726         lim = newlim;
1727     }
1728   else
1729     {
1730       char *newlim;
1731       newlim = ptr;
1732       while (newlim < lim && blanks[to_uchar (*newlim)])
1733         ++newlim;
1734       while (newlim < lim && !blanks[to_uchar (*newlim)])
1735         ++newlim;
1736       lim = newlim;
1737     }
1738 #endif
1739 
1740   if (echar != 0) /* We need to skip over a portion of the end field.  */
1741     {
1742       /* If we're ignoring leading blanks when computing the End
1743          of the field, skip past them here.  */
1744       if (key->skipeblanks)
1745         while (ptr < lim && blanks[to_uchar (*ptr)])
1746           ++ptr;
1747 
1748       /* Advance PTR by ECHAR (if possible), but no further than LIM.  */
1749       ptr = MIN (lim, ptr + echar);
1750     }
1751 
1752   return ptr;
1753 }
1754 
1755 /* Fill BUF reading from FP, moving buf->left bytes from the end
1756    of buf->buf to the beginning first.  If EOF is reached and the
1757    file wasn't terminated by a newline, supply one.  Set up BUF's line
1758    table too.  FILE is the name of the file corresponding to FP.
1759    Return true if some input was read.  */
1760 
1761 static bool
fillbuf(struct buffer * buf,FILE * fp,char const * file)1762 fillbuf (struct buffer *buf, FILE *fp, char const *file)
1763 {
1764   struct keyfield const *key = keylist;
1765   char eol = eolchar;
1766   size_t line_bytes = buf->line_bytes;
1767   size_t mergesize = merge_buffer_size - MIN_MERGE_BUFFER_SIZE;
1768 
1769   if (buf->eof)
1770     return false;
1771 
1772   if (buf->used != buf->left)
1773     {
1774       memmove (buf->buf, buf->buf + buf->used - buf->left, buf->left);
1775       buf->used = buf->left;
1776       buf->nlines = 0;
1777     }
1778 
1779   while (true)
1780     {
1781       char *ptr = buf->buf + buf->used;
1782       struct line *linelim = buffer_linelim (buf);
1783       struct line *line = linelim - buf->nlines;
1784       size_t avail = (char *) linelim - buf->nlines * line_bytes - ptr;
1785       char *line_start = buf->nlines ? line->text + line->length : buf->buf;
1786 
1787       while (line_bytes + 1 < avail)
1788         {
1789           /* Read as many bytes as possible, but do not read so many
1790              bytes that there might not be enough room for the
1791              corresponding line array.  The worst case is when the
1792              rest of the input file consists entirely of newlines,
1793              except that the last byte is not a newline.  */
1794           size_t readsize = (avail - 1) / (line_bytes + 1);
1795           size_t bytes_read = fread (ptr, 1, readsize, fp);
1796           char *ptrlim = ptr + bytes_read;
1797           char *p;
1798           avail -= bytes_read;
1799 
1800           if (bytes_read != readsize)
1801             {
1802               if (ferror (fp))
1803                 sort_die (_("read failed"), file);
1804               if (feof (fp))
1805                 {
1806                   buf->eof = true;
1807                   if (buf->buf == ptrlim)
1808                     return false;
1809                   if (line_start != ptrlim && ptrlim[-1] != eol)
1810                     *ptrlim++ = eol;
1811                 }
1812             }
1813 
1814           /* Find and record each line in the just-read input.  */
1815           while ((p = memchr (ptr, eol, ptrlim - ptr)))
1816             {
1817               /* Delimit the line with NUL. This eliminates the need to
1818                  temporarily replace the last byte with NUL when calling
1819                  xmemcoll, which increases performance.  */
1820               *p = '\0';
1821               ptr = p + 1;
1822               line--;
1823               line->text = line_start;
1824               line->length = ptr - line_start;
1825               mergesize = MAX (mergesize, line->length);
1826               avail -= line_bytes;
1827 
1828               if (key)
1829                 {
1830                   /* Precompute the position of the first key for
1831                      efficiency.  */
1832                   line->keylim = (key->eword == SIZE_MAX
1833                                   ? p
1834                                   : limfield (line, key));
1835 
1836                   if (key->sword != SIZE_MAX)
1837                     line->keybeg = begfield (line, key);
1838                   else
1839                     {
1840                       if (key->skipsblanks)
1841                         while (blanks[to_uchar (*line_start)])
1842                           line_start++;
1843                       line->keybeg = line_start;
1844                     }
1845                 }
1846 
1847               line_start = ptr;
1848             }
1849 
1850           ptr = ptrlim;
1851           if (buf->eof)
1852             break;
1853         }
1854 
1855       buf->used = ptr - buf->buf;
1856       buf->nlines = buffer_linelim (buf) - line;
1857       if (buf->nlines != 0)
1858         {
1859           buf->left = ptr - line_start;
1860           merge_buffer_size = mergesize + MIN_MERGE_BUFFER_SIZE;
1861           return true;
1862         }
1863 
1864       {
1865         /* The current input line is too long to fit in the buffer.
1866            Increase the buffer size and try again, keeping it properly
1867            aligned.  */
1868         size_t line_alloc = buf->alloc / sizeof (struct line);
1869         buf->buf = x2nrealloc (buf->buf, &line_alloc, sizeof (struct line));
1870         buf->alloc = line_alloc * sizeof (struct line);
1871       }
1872     }
1873 }
1874 
1875 /* Table that maps characters to order-of-magnitude values.  */
1876 static char const unit_order[UCHAR_LIM] =
1877   {
1878 #if ! ('K' == 75 && 'M' == 77 && 'G' == 71 && 'T' == 84 && 'P' == 80 \
1879        && 'E' == 69 && 'Z' == 90 && 'Y' == 89 && 'R' == 82 && 'Q' == 81 \
1880        && 'k' == 107)
1881     /* This initializer syntax works on all C99 hosts.  For now, use
1882        it only on non-ASCII hosts, to ease the pain of porting to
1883        pre-C99 ASCII hosts.  */
1884     ['K']=1, ['M']=2, ['G']=3, ['T']=4, ['P']=5, ['E']=6, ['Z']=7, ['Y']=8,
1885     ['R']=9, ['Q']=10,
1886     ['k']=1,
1887 #else
1888     /* Generate the following table with this command:
1889        perl -e 'my %a=(k=>1,K=>1,M=>2,G=>3,T=>4,P=>5,E=>6,Z=>7,Y=>8,R=>9,Q=>10);
1890        foreach my $i (0..255) {my $c=chr($i); $a{$c} ||= 0;print "$a{$c}, "}'\
1891        |fmt  */
1892     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1893     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1894     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 3,
1895     0, 0, 0, 1, 0, 2, 0, 0, 5, 10, 9, 0, 4, 0, 0, 0, 0, 8, 7, 0, 0, 0, 0, 0,
1896     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1897     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1898     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1899     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1900     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1901     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1902     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1903 #endif
1904   };
1905 
1906 /* Traverse number given as *number consisting of digits, thousands_sep, and
1907    decimal_point chars only.  Returns the highest digit found in the number,
1908    or '\0' if no digit has been found.  Upon return *number points at the
1909    character that immediately follows after the given number.  */
1910 static char
traverse_raw_number(char const ** number)1911 traverse_raw_number (char const **number)
1912 {
1913   char const *p = *number;
1914   char ch;
1915   char max_digit = '\0';
1916   bool ends_with_thousands_sep = false;
1917 
1918   /* Scan to end of number.
1919      Decimals or separators not followed by digits stop the scan.
1920      Numbers ending in decimals or separators are thus considered
1921      to be lacking in units.
1922      FIXME: add support for multibyte thousands_sep and decimal_point.  */
1923 
1924   while (ISDIGIT (ch = *p++))
1925     {
1926       if (max_digit < ch)
1927         max_digit = ch;
1928 
1929       /* Allow to skip only one occurrence of thousands_sep to avoid finding
1930          the unit in the next column in case thousands_sep matches as blank
1931          and is used as column delimiter.  */
1932       ends_with_thousands_sep = (*p == thousands_sep);
1933       if (ends_with_thousands_sep)
1934         ++p;
1935     }
1936 
1937   if (ends_with_thousands_sep)
1938     {
1939       /* thousands_sep not followed by digit is not allowed.  */
1940       *number = p - 2;
1941       return max_digit;
1942     }
1943 
1944   if (ch == decimal_point)
1945     while (ISDIGIT (ch = *p++))
1946       if (max_digit < ch)
1947         max_digit = ch;
1948 
1949   *number = p - 1;
1950   return max_digit;
1951 }
1952 
1953 /* Return an integer that represents the order of magnitude of the
1954    unit following the number.  The number may contain thousands
1955    separators and a decimal point, but it may not contain leading blanks.
1956    Negative numbers get negative orders; zero numbers have a zero order.  */
1957 
1958 ATTRIBUTE_PURE
1959 static int
find_unit_order(char const * number)1960 find_unit_order (char const *number)
1961 {
1962   bool minus_sign = (*number == '-');
1963   char const *p = number + minus_sign;
1964   char max_digit = traverse_raw_number (&p);
1965   if ('0' < max_digit)
1966     {
1967       unsigned char ch = *p;
1968       int order = unit_order[ch];
1969       return (minus_sign ? -order : order);
1970     }
1971   else
1972     return 0;
1973 }
1974 
1975 /* Compare numbers A and B ending in units with SI or IEC prefixes
1976        <none/unknown> < K/k < M < G < T < P < E < Z < Y < R < Q */
1977 
1978 ATTRIBUTE_PURE
1979 static int
human_numcompare(char const * a,char const * b)1980 human_numcompare (char const *a, char const *b)
1981 {
1982   while (blanks[to_uchar (*a)])
1983     a++;
1984   while (blanks[to_uchar (*b)])
1985     b++;
1986 
1987   int diff = find_unit_order (a) - find_unit_order (b);
1988   return (diff ? diff : strnumcmp (a, b, decimal_point, thousands_sep));
1989 }
1990 
1991 /* Compare strings A and B as numbers without explicitly converting them to
1992    machine numbers.  Comparatively slow for short strings, but asymptotically
1993    hideously fast. */
1994 
1995 ATTRIBUTE_PURE
1996 static int
numcompare(char const * a,char const * b)1997 numcompare (char const *a, char const *b)
1998 {
1999   while (blanks[to_uchar (*a)])
2000     a++;
2001   while (blanks[to_uchar (*b)])
2002     b++;
2003 
2004   return strnumcmp (a, b, decimal_point, thousands_sep);
2005 }
2006 
2007 static int
nan_compare(long double a,long double b)2008 nan_compare (long double a, long double b)
2009 {
2010   char buf[2][sizeof "-nan""()" + CHAR_BIT * sizeof a];
2011   snprintf (buf[0], sizeof buf[0], "%Lf", a);
2012   snprintf (buf[1], sizeof buf[1], "%Lf", b);
2013   return strcmp (buf[0], buf[1]);
2014 }
2015 
2016 static int
general_numcompare(char const * sa,char const * sb)2017 general_numcompare (char const *sa, char const *sb)
2018 {
2019   /* FIXME: maybe add option to try expensive FP conversion
2020      only if A and B can't be compared more cheaply/accurately.  */
2021 
2022   char *ea;
2023   char *eb;
2024   long double a = strtold (sa, &ea);
2025   long double b = strtold (sb, &eb);
2026 
2027   /* Put conversion errors at the start of the collating sequence.  */
2028   if (sa == ea)
2029     return sb == eb ? 0 : -1;
2030   if (sb == eb)
2031     return 1;
2032 
2033   /* Sort numbers in the usual way, where -0 == +0.  Put NaNs after
2034      conversion errors but before numbers; sort them by internal
2035      bit-pattern, for lack of a more portable alternative.  */
2036   return (a < b ? -1
2037           : a > b ? 1
2038           : a == b ? 0
2039           : b == b ? -1
2040           : a == a ? 1
2041           : nan_compare (a, b));
2042 }
2043 
2044 /* Return an integer in 1..12 of the month name MONTH.
2045    Return 0 if the name in S is not recognized.  */
2046 
2047 static int
getmonth(char const * month,char ** ea)2048 getmonth (char const *month, char **ea)
2049 {
2050   size_t lo = 0;
2051   size_t hi = MONTHS_PER_YEAR;
2052 
2053   while (blanks[to_uchar (*month)])
2054     month++;
2055 
2056   do
2057     {
2058       size_t ix = (lo + hi) / 2;
2059       char const *m = month;
2060       char const *n = monthtab[ix].name;
2061 
2062       for (;; m++, n++)
2063         {
2064           if (!*n)
2065             {
2066               if (ea)
2067                 *ea = (char *) m;
2068               return monthtab[ix].val;
2069             }
2070           if (to_uchar (fold_toupper[to_uchar (*m)]) < to_uchar (*n))
2071             {
2072               hi = ix;
2073               break;
2074             }
2075           else if (to_uchar (fold_toupper[to_uchar (*m)]) > to_uchar (*n))
2076             {
2077               lo = ix + 1;
2078               break;
2079             }
2080         }
2081     }
2082   while (lo < hi);
2083 
2084   return 0;
2085 }
2086 
2087 /* A randomly chosen MD5 state, used for random comparison.  */
2088 static struct md5_ctx random_md5_state;
2089 
2090 /* Initialize the randomly chosen MD5 state.  */
2091 
2092 static void
random_md5_state_init(char const * random_source)2093 random_md5_state_init (char const *random_source)
2094 {
2095   unsigned char buf[MD5_DIGEST_SIZE];
2096   struct randread_source *r = randread_new (random_source, sizeof buf);
2097   if (! r)
2098     sort_die (_("open failed"), random_source ? random_source : "getrandom");
2099   randread (r, buf, sizeof buf);
2100   if (randread_free (r) != 0)
2101     sort_die (_("close failed"), random_source);
2102   md5_init_ctx (&random_md5_state);
2103   md5_process_bytes (buf, sizeof buf, &random_md5_state);
2104 }
2105 
2106 /* This is like strxfrm, except it reports any error and exits.  */
2107 
2108 static size_t
xstrxfrm(char * restrict dest,char const * restrict src,size_t destsize)2109 xstrxfrm (char *restrict dest, char const *restrict src, size_t destsize)
2110 {
2111   errno = 0;
2112   size_t translated_size = strxfrm (dest, src, destsize);
2113 
2114   if (errno)
2115     {
2116       error (0, errno, _("string transformation failed"));
2117       error (0, 0, _("set LC_ALL='C' to work around the problem"));
2118       error (SORT_FAILURE, 0,
2119              _("the original string was %s"),
2120              quotearg_n_style (0, locale_quoting_style, src));
2121     }
2122 
2123   return translated_size;
2124 }
2125 
2126 /* Compare the keys TEXTA (of length LENA) and TEXTB (of length LENB)
2127    using one or more random hash functions.  TEXTA[LENA] and
2128    TEXTB[LENB] must be zero.  */
2129 
2130 static int
compare_random(char * restrict texta,size_t lena,char * restrict textb,size_t lenb)2131 compare_random (char *restrict texta, size_t lena,
2132                 char *restrict textb, size_t lenb)
2133 {
2134   /* XFRM_DIFF records the equivalent of memcmp on the transformed
2135      data.  This is used to break ties if there is a checksum
2136      collision, and this is good enough given the astronomically low
2137      probability of a collision.  */
2138   int xfrm_diff = 0;
2139 
2140   char stackbuf[4000];
2141   char *buf = stackbuf;
2142   size_t bufsize = sizeof stackbuf;
2143   void *allocated = nullptr;
2144   uint32_t dig[2][MD5_DIGEST_SIZE / sizeof (uint32_t)];
2145   struct md5_ctx s[2];
2146   s[0] = s[1] = random_md5_state;
2147 
2148   if (hard_LC_COLLATE)
2149     {
2150       char const *lima = texta + lena;
2151       char const *limb = textb + lenb;
2152 
2153       while (true)
2154         {
2155           /* Transform the text into the basis of comparison, so that byte
2156              strings that would otherwise considered to be equal are
2157              considered equal here even if their bytes differ.
2158 
2159              Each time through this loop, transform one
2160              null-terminated string's worth from TEXTA or from TEXTB
2161              or both.  That way, there's no need to store the
2162              transformation of the whole line, if it contains many
2163              null-terminated strings.  */
2164 
2165           /* Store the transformed data into a big-enough buffer.  */
2166 
2167           /* A 3X size guess avoids the overhead of calling strxfrm
2168              twice on typical implementations.  Don't worry about
2169              size_t overflow, as the guess need not be correct.  */
2170           size_t guess_bufsize = 3 * (lena + lenb) + 2;
2171           if (bufsize < guess_bufsize)
2172             {
2173               bufsize = MAX (guess_bufsize, bufsize * 3 / 2);
2174               free (allocated);
2175               buf = allocated = malloc (bufsize);
2176               if (! buf)
2177                 {
2178                   buf = stackbuf;
2179                   bufsize = sizeof stackbuf;
2180                 }
2181             }
2182 
2183           size_t sizea =
2184             (texta < lima ? xstrxfrm (buf, texta, bufsize) + 1 : 0);
2185           bool a_fits = sizea <= bufsize;
2186           size_t sizeb =
2187             (textb < limb
2188              ? (xstrxfrm ((a_fits ? buf + sizea : nullptr), textb,
2189                           (a_fits ? bufsize - sizea : 0))
2190                 + 1)
2191              : 0);
2192 
2193           if (! (a_fits && sizea + sizeb <= bufsize))
2194             {
2195               bufsize = sizea + sizeb;
2196               if (bufsize < SIZE_MAX / 3)
2197                 bufsize = bufsize * 3 / 2;
2198               free (allocated);
2199               buf = allocated = xmalloc (bufsize);
2200               if (texta < lima)
2201                 strxfrm (buf, texta, sizea);
2202               if (textb < limb)
2203                 strxfrm (buf + sizea, textb, sizeb);
2204             }
2205 
2206           /* Advance past NULs to the next part of each input string,
2207              exiting the loop if both strings are exhausted.  When
2208              exiting the loop, prepare to finish off the tiebreaker
2209              comparison properly.  */
2210           if (texta < lima)
2211             texta += strlen (texta) + 1;
2212           if (textb < limb)
2213             textb += strlen (textb) + 1;
2214           if (! (texta < lima || textb < limb))
2215             {
2216               lena = sizea; texta = buf;
2217               lenb = sizeb; textb = buf + sizea;
2218               break;
2219             }
2220 
2221           /* Accumulate the transformed data in the corresponding
2222              checksums.  */
2223           md5_process_bytes (buf, sizea, &s[0]);
2224           md5_process_bytes (buf + sizea, sizeb, &s[1]);
2225 
2226           /* Update the tiebreaker comparison of the transformed data.  */
2227           if (! xfrm_diff)
2228             {
2229               xfrm_diff = memcmp (buf, buf + sizea, MIN (sizea, sizeb));
2230               if (! xfrm_diff)
2231                 xfrm_diff = (sizea > sizeb) - (sizea < sizeb);
2232             }
2233         }
2234     }
2235 
2236   /* Compute and compare the checksums.  */
2237   md5_process_bytes (texta, lena, &s[0]); md5_finish_ctx (&s[0], dig[0]);
2238   md5_process_bytes (textb, lenb, &s[1]); md5_finish_ctx (&s[1], dig[1]);
2239   int diff = memcmp (dig[0], dig[1], sizeof dig[0]);
2240 
2241   /* Fall back on the tiebreaker if the checksums collide.  */
2242   if (! diff)
2243     {
2244       if (! xfrm_diff)
2245         {
2246           xfrm_diff = memcmp (texta, textb, MIN (lena, lenb));
2247           if (! xfrm_diff)
2248             xfrm_diff = (lena > lenb) - (lena < lenb);
2249         }
2250 
2251       diff = xfrm_diff;
2252     }
2253 
2254   free (allocated);
2255 
2256   return diff;
2257 }
2258 
2259 /* Return the printable width of the block of memory starting at
2260    TEXT and ending just before LIM, counting each tab as one byte.
2261    FIXME: Should we generally be counting non printable chars?  */
2262 
2263 static size_t
debug_width(char const * text,char const * lim)2264 debug_width (char const *text, char const *lim)
2265 {
2266   size_t width = mbsnwidth (text, lim - text, 0);
2267   while (text < lim)
2268     width += (*text++ == '\t');
2269   return width;
2270 }
2271 
2272 /* For debug mode, "underline" a key at the
2273    specified offset and screen width.  */
2274 
2275 static void
mark_key(size_t offset,size_t width)2276 mark_key (size_t offset, size_t width)
2277 {
2278   while (offset--)
2279     putchar (' ');
2280 
2281   if (!width)
2282     printf (_("^ no match for key\n"));
2283   else
2284     {
2285       do
2286         putchar ('_');
2287       while (--width);
2288 
2289       putchar ('\n');
2290     }
2291 }
2292 
2293 /* Return true if KEY is a numeric key.  */
2294 
2295 static inline bool
key_numeric(struct keyfield const * key)2296 key_numeric (struct keyfield const *key)
2297 {
2298   return key->numeric || key->general_numeric || key->human_numeric;
2299 }
2300 
2301 /* For LINE, output a debugging line that underlines KEY in LINE.
2302    If KEY is null, underline the whole line.  */
2303 
2304 static void
debug_key(struct line const * line,struct keyfield const * key)2305 debug_key (struct line const *line, struct keyfield const *key)
2306 {
2307   char *text = line->text;
2308   char *beg = text;
2309   char *lim = text + line->length - 1;
2310 
2311   if (key)
2312     {
2313       if (key->sword != SIZE_MAX)
2314         beg = begfield (line, key);
2315       if (key->eword != SIZE_MAX)
2316         lim = limfield (line, key);
2317 
2318       if ((key->skipsblanks && key->sword == SIZE_MAX)
2319           || key->month || key_numeric (key))
2320         {
2321           char saved = *lim;
2322           *lim = '\0';
2323 
2324           while (blanks[to_uchar (*beg)])
2325             beg++;
2326 
2327           char *tighter_lim = beg;
2328 
2329           if (lim < beg)
2330             tighter_lim = lim;
2331           else if (key->month)
2332             getmonth (beg, &tighter_lim);
2333           else if (key->general_numeric)
2334             ignore_value (strtold (beg, &tighter_lim));
2335           else if (key->numeric || key->human_numeric)
2336             {
2337               char const *p = beg + (beg < lim && *beg == '-');
2338               char max_digit = traverse_raw_number (&p);
2339               if ('0' <= max_digit)
2340                 {
2341                   unsigned char ch = *p;
2342                   tighter_lim = (char *) p
2343                     + (key->human_numeric && unit_order[ch]);
2344                 }
2345             }
2346           else
2347             tighter_lim = lim;
2348 
2349           *lim = saved;
2350           lim = tighter_lim;
2351         }
2352     }
2353 
2354   size_t offset = debug_width (text, beg);
2355   size_t width = debug_width (beg, lim);
2356   mark_key (offset, width);
2357 }
2358 
2359 /* Debug LINE by underlining its keys.  */
2360 
2361 static void
debug_line(struct line const * line)2362 debug_line (struct line const *line)
2363 {
2364   struct keyfield const *key = keylist;
2365 
2366   do
2367     debug_key (line, key);
2368   while (key && ((key = key->next) || ! (unique || stable)));
2369 }
2370 
2371 /* Return whether sorting options specified for key.  */
2372 
2373 static bool
default_key_compare(struct keyfield const * key)2374 default_key_compare (struct keyfield const *key)
2375 {
2376   return ! (key->ignore
2377             || key->translate
2378             || key->skipsblanks
2379             || key->skipeblanks
2380             || key_numeric (key)
2381             || key->month
2382             || key->version
2383             || key->random
2384             /* || key->reverse */
2385            );
2386 }
2387 
2388 /* Convert a key to the short options used to specify it.  */
2389 
2390 static void
key_to_opts(struct keyfield const * key,char * opts)2391 key_to_opts (struct keyfield const *key, char *opts)
2392 {
2393   if (key->skipsblanks || key->skipeblanks)
2394     *opts++ = 'b';/* either disables global -b  */
2395   if (key->ignore == nondictionary)
2396     *opts++ = 'd';
2397   if (key->translate)
2398     *opts++ = 'f';
2399   if (key->general_numeric)
2400     *opts++ = 'g';
2401   if (key->human_numeric)
2402     *opts++ = 'h';
2403   if (key->ignore == nonprinting)
2404     *opts++ = 'i';
2405   if (key->month)
2406     *opts++ = 'M';
2407   if (key->numeric)
2408     *opts++ = 'n';
2409   if (key->random)
2410     *opts++ = 'R';
2411   if (key->reverse)
2412     *opts++ = 'r';
2413   if (key->version)
2414     *opts++ = 'V';
2415   *opts = '\0';
2416 }
2417 
2418 /* Output data independent key warnings to stderr.  */
2419 
2420 static void
key_warnings(struct keyfield const * gkey,bool gkey_only)2421 key_warnings (struct keyfield const *gkey, bool gkey_only)
2422 {
2423   struct keyfield const *key;
2424   struct keyfield ugkey = *gkey;
2425   unsigned long keynum = 1;
2426   bool basic_numeric_field = false;
2427   bool general_numeric_field = false;
2428   bool basic_numeric_field_span = false;
2429   bool general_numeric_field_span = false;
2430 
2431   for (key = keylist; key; key = key->next, keynum++)
2432     {
2433       if (key_numeric (key))
2434         {
2435           if (key->general_numeric)
2436             general_numeric_field = true;
2437           else
2438             basic_numeric_field = true;
2439         }
2440 
2441       if (key->traditional_used)
2442         {
2443           size_t sword = key->sword;
2444           size_t eword = key->eword;
2445           char tmp[INT_BUFSIZE_BOUND (uintmax_t)];
2446           /* obsolescent syntax +A.x -B.y is equivalent to:
2447                -k A+1.x+1,B.y   (when y = 0)
2448                -k A+1.x+1,B+1.y (when y > 0)  */
2449           char obuf[INT_BUFSIZE_BOUND (sword) * 2 + 4]; /* +# -#  */
2450           char nbuf[INT_BUFSIZE_BOUND (sword) * 2 + 5]; /* -k #,#  */
2451           char *po = obuf;
2452           char *pn = nbuf;
2453 
2454           if (sword == SIZE_MAX)
2455             sword++;
2456 
2457           po = stpcpy (stpcpy (po, "+"), umaxtostr (sword, tmp));
2458           pn = stpcpy (stpcpy (pn, "-k "), umaxtostr (sword + 1, tmp));
2459           if (key->eword != SIZE_MAX)
2460             {
2461               stpcpy (stpcpy (po, " -"), umaxtostr (eword + 1, tmp));
2462               stpcpy (stpcpy (pn, ","),
2463                       umaxtostr (eword + 1
2464                                  + (key->echar == SIZE_MAX), tmp));
2465             }
2466           error (0, 0, _("obsolescent key %s used; consider %s instead"),
2467                  quote_n (0, obuf), quote_n (1, nbuf));
2468         }
2469 
2470       /* Warn about field specs that will never match.  */
2471       bool zero_width = key->sword != SIZE_MAX && key->eword < key->sword;
2472       if (zero_width)
2473         error (0, 0, _("key %lu has zero width and will be ignored"), keynum);
2474 
2475       /* Warn about significant leading blanks.  */
2476       bool implicit_skip = key_numeric (key) || key->month;
2477       bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y  */
2478       if (!zero_width && !gkey_only && tab == TAB_DEFAULT && !line_offset
2479           && ((!key->skipsblanks && !implicit_skip)
2480               || (!key->skipsblanks && key->schar)
2481               || (!key->skipeblanks && key->echar)))
2482         error (0, 0, _("leading blanks are significant in key %lu; "
2483                        "consider also specifying 'b'"), keynum);
2484 
2485       /* Warn about numeric comparisons spanning fields,
2486          as field delimiters could be interpreted as part
2487          of the number (maybe only in other locales).  */
2488       if (!gkey_only && key_numeric (key))
2489         {
2490           size_t sword = key->sword + 1;
2491           size_t eword = key->eword + 1;
2492           if (!sword)
2493             sword++;
2494           if (!eword || sword < eword)
2495             {
2496               error (0, 0, _("key %lu is numeric and spans multiple fields"),
2497                      keynum);
2498               if (key->general_numeric)
2499                 general_numeric_field_span = true;
2500               else
2501                 basic_numeric_field_span = true;
2502             }
2503         }
2504 
2505       /* Flag global options not copied or specified in any key.  */
2506       if (ugkey.ignore && (ugkey.ignore == key->ignore))
2507         ugkey.ignore = nullptr;
2508       if (ugkey.translate && (ugkey.translate == key->translate))
2509         ugkey.translate = nullptr;
2510       ugkey.skipsblanks &= !key->skipsblanks;
2511       ugkey.skipeblanks &= !key->skipeblanks;
2512       ugkey.month &= !key->month;
2513       ugkey.numeric &= !key->numeric;
2514       ugkey.general_numeric &= !key->general_numeric;
2515       ugkey.human_numeric &= !key->human_numeric;
2516       ugkey.random &= !key->random;
2517       ugkey.version &= !key->version;
2518       ugkey.reverse &= !key->reverse;
2519     }
2520 
2521   /* Explicitly warn if field delimiters in this locale
2522      don't constrain numbers.  */
2523   bool number_locale_warned = false;
2524   if (basic_numeric_field_span)
2525     {
2526       if (tab == TAB_DEFAULT
2527           ? thousands_sep != NON_CHAR && (isblank (to_uchar (thousands_sep)))
2528           : tab == thousands_sep)
2529         {
2530           error (0, 0,
2531                  _("field separator %s is treated as a "
2532                    "group separator in numbers"),
2533                  quote (((char []) {thousands_sep, 0})));
2534           number_locale_warned = true;
2535         }
2536     }
2537   if (basic_numeric_field_span || general_numeric_field_span)
2538     {
2539       if (tab == TAB_DEFAULT
2540           ? thousands_sep != NON_CHAR && (isblank (to_uchar (decimal_point)))
2541           : tab == decimal_point)
2542         {
2543           error (0, 0,
2544                  _("field separator %s is treated as a "
2545                    "decimal point in numbers"),
2546                  quote (((char []) {decimal_point, 0})));
2547           number_locale_warned = true;
2548         }
2549       else if (tab == '-')
2550         {
2551           error (0, 0,
2552                  _("field separator %s is treated as a "
2553                    "minus sign in numbers"),
2554                  quote (((char []) {tab, 0})));
2555         }
2556       else if (general_numeric_field_span && tab == '+')
2557         {
2558           error (0, 0,
2559                  _("field separator %s is treated as a "
2560                    "plus sign in numbers"),
2561                  quote (((char []) {tab, 0})));
2562         }
2563     }
2564 
2565   /* Explicitly indicate the decimal point used in this locale,
2566      as it suggests that robust scripts need to consider
2567      setting the locale when comparing numbers.  */
2568   if ((basic_numeric_field || general_numeric_field) && ! number_locale_warned)
2569     {
2570       error (0, 0,
2571              _("%snumbers use %s as a decimal point in this locale"),
2572              tab == decimal_point ? "" : _("note "),
2573              quote (((char []) {decimal_point, 0})));
2574 
2575     }
2576 
2577   if (basic_numeric_field && thousands_sep_ignored)
2578     {
2579       error (0, 0,
2580              _("the multi-byte number group separator "
2581                "in this locale is not supported"));
2582     }
2583 
2584   /* Warn about ignored global options flagged above.
2585      This clears all flags if UGKEY is the only one in the list.  */
2586   if (!default_key_compare (&ugkey)
2587       || (ugkey.reverse && (stable || unique) && keylist))
2588     {
2589       bool ugkey_reverse = ugkey.reverse;
2590       if (!(stable || unique))
2591         ugkey.reverse = false;
2592       /* The following is too big, but guaranteed to be "big enough".  */
2593       char opts[sizeof short_options];
2594       key_to_opts (&ugkey, opts);
2595       error (0, 0,
2596              ngettext ("option '-%s' is ignored",
2597                        "options '-%s' are ignored",
2598                        select_plural (strlen (opts))), opts);
2599       ugkey.reverse = ugkey_reverse;
2600     }
2601   if (ugkey.reverse && !(stable || unique) && keylist)
2602     error (0, 0, _("option '-r' only applies to last-resort comparison"));
2603 }
2604 
2605 /* Return either the sense of DIFF or its reverse, depending on REVERSED.
2606    If REVERSED, do not simply negate DIFF as that can mishandle INT_MIN.  */
2607 
2608 static int
diff_reversed(int diff,bool reversed)2609 diff_reversed (int diff, bool reversed)
2610 {
2611   return reversed ? (diff < 0) - (diff > 0) : diff;
2612 }
2613 
2614 /* Compare two lines A and B trying every key in sequence until there
2615    are no more keys or a difference is found. */
2616 
2617 static int
keycompare(struct line const * a,struct line const * b)2618 keycompare (struct line const *a, struct line const *b)
2619 {
2620   struct keyfield *key = keylist;
2621 
2622   /* For the first iteration only, the key positions have been
2623      precomputed for us. */
2624   char *texta = a->keybeg;
2625   char *textb = b->keybeg;
2626   char *lima = a->keylim;
2627   char *limb = b->keylim;
2628 
2629   int diff;
2630 
2631   while (true)
2632     {
2633       char const *translate = key->translate;
2634       bool const *ignore = key->ignore;
2635 
2636       /* Treat field ends before field starts as empty fields.  */
2637       lima = MAX (texta, lima);
2638       limb = MAX (textb, limb);
2639 
2640       /* Find the lengths. */
2641       size_t lena = lima - texta;
2642       size_t lenb = limb - textb;
2643 
2644       if (hard_LC_COLLATE || key_numeric (key)
2645           || key->month || key->random || key->version)
2646         {
2647           /* Ordinarily use the keys in-place, temporarily null-terminated.  */
2648           char *ta = texta;
2649           char *tb = textb;
2650           size_t tlena = lena;
2651           size_t tlenb = lenb;
2652           char enda = ta[tlena];
2653           char endb = tb[tlenb];
2654 
2655           void *allocated = nullptr;
2656           char stackbuf[4000];
2657 
2658           if (ignore || translate)
2659             {
2660               /* Compute with copies of the keys, which are the result of
2661                  translating or ignoring characters, and which need their
2662                  own storage.  */
2663 
2664               size_t i;
2665 
2666               /* Allocate space for copies.  */
2667               size_t size = lena + 1 + lenb + 1;
2668               if (size <= sizeof stackbuf)
2669                 ta = stackbuf;
2670               else
2671                 ta = allocated = xmalloc (size);
2672               tb = ta + lena + 1;
2673 
2674               /* Put into each copy a version of the key in which the
2675                  requested characters are ignored or translated.  */
2676               for (tlena = i = 0; i < lena; i++)
2677                 if (! (ignore && ignore[to_uchar (texta[i])]))
2678                   ta[tlena++] = (translate
2679                                  ? translate[to_uchar (texta[i])]
2680                                  : texta[i]);
2681 
2682               for (tlenb = i = 0; i < lenb; i++)
2683                 if (! (ignore && ignore[to_uchar (textb[i])]))
2684                   tb[tlenb++] = (translate
2685                                  ? translate[to_uchar (textb[i])]
2686                                  : textb[i]);
2687             }
2688 
2689           ta[tlena] = '\0';
2690           tb[tlenb] = '\0';
2691 
2692           if (key->numeric)
2693             diff = numcompare (ta, tb);
2694           else if (key->general_numeric)
2695             diff = general_numcompare (ta, tb);
2696           else if (key->human_numeric)
2697             diff = human_numcompare (ta, tb);
2698           else if (key->month)
2699             diff = getmonth (ta, nullptr) - getmonth (tb, nullptr);
2700           else if (key->random)
2701             diff = compare_random (ta, tlena, tb, tlenb);
2702           else if (key->version)
2703             diff = filenvercmp (ta, tlena, tb, tlenb);
2704           else
2705             {
2706               /* Locale-dependent string sorting.  This is slower than
2707                  C-locale sorting, which is implemented below.  */
2708               if (tlena == 0)
2709                 diff = - NONZERO (tlenb);
2710               else if (tlenb == 0)
2711                 diff = 1;
2712               else
2713                 diff = xmemcoll0 (ta, tlena + 1, tb, tlenb + 1);
2714             }
2715 
2716           ta[tlena] = enda;
2717           tb[tlenb] = endb;
2718 
2719           free (allocated);
2720         }
2721       else if (ignore)
2722         {
2723 #define CMP_WITH_IGNORE(A, B)						\
2724   do									\
2725     {									\
2726           while (true)							\
2727             {								\
2728               while (texta < lima && ignore[to_uchar (*texta)])		\
2729                 ++texta;						\
2730               while (textb < limb && ignore[to_uchar (*textb)])		\
2731                 ++textb;						\
2732               if (! (texta < lima && textb < limb))			\
2733                 {							\
2734                   diff = (texta < lima) - (textb < limb);		\
2735                   break;						\
2736                 }							\
2737               diff = to_uchar (A) - to_uchar (B);			\
2738               if (diff)							\
2739                 break;							\
2740               ++texta;							\
2741               ++textb;							\
2742             }								\
2743                                                                         \
2744     }									\
2745   while (0)
2746 
2747           if (translate)
2748             CMP_WITH_IGNORE (translate[to_uchar (*texta)],
2749                              translate[to_uchar (*textb)]);
2750           else
2751             CMP_WITH_IGNORE (*texta, *textb);
2752         }
2753       else
2754         {
2755           size_t lenmin = MIN (lena, lenb);
2756           if (lenmin == 0)
2757             diff = 0;
2758           else if (translate)
2759             {
2760               size_t i = 0;
2761               do
2762                 {
2763                   diff = (to_uchar (translate[to_uchar (texta[i])])
2764                           - to_uchar (translate[to_uchar (textb[i])]));
2765                   if (diff)
2766                     break;
2767                   i++;
2768                 }
2769               while (i < lenmin);
2770             }
2771           else
2772             diff = memcmp (texta, textb, lenmin);
2773 
2774           if (! diff)
2775             diff = (lena > lenb) - (lena < lenb);
2776         }
2777 
2778       if (diff)
2779         break;
2780 
2781       key = key->next;
2782       if (! key)
2783         return 0;
2784 
2785       /* Find the beginning and limit of the next field.  */
2786       if (key->eword != SIZE_MAX)
2787         lima = limfield (a, key), limb = limfield (b, key);
2788       else
2789         lima = a->text + a->length - 1, limb = b->text + b->length - 1;
2790 
2791       if (key->sword != SIZE_MAX)
2792         texta = begfield (a, key), textb = begfield (b, key);
2793       else
2794         {
2795           texta = a->text, textb = b->text;
2796           if (key->skipsblanks)
2797             {
2798               while (texta < lima && blanks[to_uchar (*texta)])
2799                 ++texta;
2800               while (textb < limb && blanks[to_uchar (*textb)])
2801                 ++textb;
2802             }
2803         }
2804     }
2805 
2806   return diff_reversed (diff, key->reverse);
2807 }
2808 
2809 /* Compare two lines A and B, returning negative, zero, or positive
2810    depending on whether A compares less than, equal to, or greater than B. */
2811 
2812 static int
compare(struct line const * a,struct line const * b)2813 compare (struct line const *a, struct line const *b)
2814 {
2815   int diff;
2816   size_t alen, blen;
2817 
2818   /* First try to compare on the specified keys (if any).
2819      The only two cases with no key at all are unadorned sort,
2820      and unadorned sort -r. */
2821   if (keylist)
2822     {
2823       diff = keycompare (a, b);
2824       if (diff || unique || stable)
2825         return diff;
2826     }
2827 
2828   /* If the keys all compare equal (or no keys were specified)
2829      fall through to the default comparison.  */
2830   alen = a->length - 1, blen = b->length - 1;
2831 
2832   if (alen == 0)
2833     diff = - NONZERO (blen);
2834   else if (blen == 0)
2835     diff = 1;
2836   else if (hard_LC_COLLATE)
2837     {
2838       /* xmemcoll0 is a performance enhancement as
2839          it will not unconditionally write '\0' after the
2840          passed in buffers, which was seen to give around
2841          a 3% increase in performance for short lines.  */
2842       diff = xmemcoll0 (a->text, alen + 1, b->text, blen + 1);
2843     }
2844   else
2845     {
2846       diff = memcmp (a->text, b->text, MIN (alen, blen));
2847       if (!diff)
2848         diff = (alen > blen) - (alen < blen);
2849     }
2850 
2851   return diff_reversed (diff, reverse);
2852 }
2853 
2854 /* Write LINE to output stream FP; the output file's name is
2855    OUTPUT_FILE if OUTPUT_FILE is non-null, and is the standard output
2856    otherwise.  If debugging is enabled and FP is standard output,
2857    append some debugging information.  */
2858 
2859 static void
write_line(struct line const * line,FILE * fp,char const * output_file)2860 write_line (struct line const *line, FILE *fp, char const *output_file)
2861 {
2862   char *buf = line->text;
2863   size_t n_bytes = line->length;
2864   char *ebuf = buf + n_bytes;
2865 
2866   if (!output_file && debug)
2867     {
2868       /* Convert TAB to '>' and EOL to \n, and then output debugging info.  */
2869       char const *c = buf;
2870 
2871       while (c < ebuf)
2872         {
2873           char wc = *c++;
2874           if (wc == '\t')
2875             wc = '>';
2876           else if (c == ebuf)
2877             wc = '\n';
2878           if (fputc (wc, fp) == EOF)
2879             sort_die (_("write failed"), output_file);
2880         }
2881 
2882       debug_line (line);
2883     }
2884   else
2885     {
2886       ebuf[-1] = eolchar;
2887       if (fwrite (buf, 1, n_bytes, fp) != n_bytes)
2888         sort_die (_("write failed"), output_file);
2889       ebuf[-1] = '\0';
2890     }
2891 }
2892 
2893 /* Check that the lines read from FILE_NAME come in order.  Return
2894    true if they are in order.  If CHECKONLY == 'c', also print a
2895    diagnostic (FILE_NAME, line number, contents of line) to stderr if
2896    they are not in order.  */
2897 
2898 static bool
check(char const * file_name,char checkonly)2899 check (char const *file_name, char checkonly)
2900 {
2901   FILE *fp = xfopen (file_name, "r");
2902   struct buffer buf;		/* Input buffer. */
2903   struct line temp;		/* Copy of previous line. */
2904   size_t alloc = 0;
2905   uintmax_t line_number = 0;
2906   struct keyfield const *key = keylist;
2907   bool nonunique = ! unique;
2908   bool ordered = true;
2909 
2910   initbuf (&buf, sizeof (struct line),
2911            MAX (merge_buffer_size, sort_size));
2912   temp.text = nullptr;
2913 
2914   while (fillbuf (&buf, fp, file_name))
2915     {
2916       struct line const *line = buffer_linelim (&buf);
2917       struct line const *linebase = line - buf.nlines;
2918 
2919       /* Make sure the line saved from the old buffer contents is
2920          less than or equal to the first line of the new buffer. */
2921       if (alloc && nonunique <= compare (&temp, line - 1))
2922         {
2923         found_disorder:
2924           {
2925             if (checkonly == 'c')
2926               {
2927                 struct line const *disorder_line = line - 1;
2928                 uintmax_t disorder_line_number =
2929                   buffer_linelim (&buf) - disorder_line + line_number;
2930                 char hr_buf[INT_BUFSIZE_BOUND (disorder_line_number)];
2931                 fprintf (stderr, _("%s: %s:%s: disorder: "),
2932                          program_name, file_name,
2933                          umaxtostr (disorder_line_number, hr_buf));
2934                 write_line (disorder_line, stderr, _("standard error"));
2935               }
2936 
2937             ordered = false;
2938             break;
2939           }
2940         }
2941 
2942       /* Compare each line in the buffer with its successor.  */
2943       while (linebase < --line)
2944         if (nonunique <= compare (line, line - 1))
2945           goto found_disorder;
2946 
2947       line_number += buf.nlines;
2948 
2949       /* Save the last line of the buffer.  */
2950       if (alloc < line->length)
2951         {
2952           do
2953             {
2954               alloc *= 2;
2955               if (! alloc)
2956                 {
2957                   alloc = line->length;
2958                   break;
2959                 }
2960             }
2961           while (alloc < line->length);
2962 
2963           free (temp.text);
2964           temp.text = xmalloc (alloc);
2965         }
2966       memcpy (temp.text, line->text, line->length);
2967       temp.length = line->length;
2968       if (key)
2969         {
2970           temp.keybeg = temp.text + (line->keybeg - line->text);
2971           temp.keylim = temp.text + (line->keylim - line->text);
2972         }
2973     }
2974 
2975   xfclose (fp, file_name);
2976   free (buf.buf);
2977   free (temp.text);
2978   return ordered;
2979 }
2980 
2981 /* Open FILES (there are NFILES of them) and store the resulting array
2982    of stream pointers into (*PFPS).  Allocate the array.  Return the
2983    number of successfully opened files, setting errno if this value is
2984    less than NFILES.  */
2985 
2986 static size_t
open_input_files(struct sortfile * files,size_t nfiles,FILE *** pfps)2987 open_input_files (struct sortfile *files, size_t nfiles, FILE ***pfps)
2988 {
2989   FILE **fps = *pfps = xnmalloc (nfiles, sizeof *fps);
2990   int i;
2991 
2992   /* Open as many input files as we can.  */
2993   for (i = 0; i < nfiles; i++)
2994     {
2995       fps[i] = (files[i].temp && files[i].temp->state != UNCOMPRESSED
2996                 ? open_temp (files[i].temp)
2997                 : stream_open (files[i].name, "r"));
2998       if (!fps[i])
2999         break;
3000     }
3001 
3002   return i;
3003 }
3004 
3005 /* Merge lines from FILES onto OFP.  NTEMPS is the number of temporary
3006    files (all of which are at the start of the FILES array), and
3007    NFILES is the number of files; 0 <= NTEMPS <= NFILES <= NMERGE.
3008    FPS is the vector of open stream corresponding to the files.
3009    Close input and output streams before returning.
3010    OUTPUT_FILE gives the name of the output file.  If it is null,
3011    the output file is standard output.  */
3012 
3013 static void
mergefps(struct sortfile * files,size_t ntemps,size_t nfiles,FILE * ofp,char const * output_file,FILE ** fps)3014 mergefps (struct sortfile *files, size_t ntemps, size_t nfiles,
3015           FILE *ofp, char const *output_file, FILE **fps)
3016 {
3017   struct buffer *buffer = xnmalloc (nfiles, sizeof *buffer);
3018                                 /* Input buffers for each file. */
3019   struct line saved;		/* Saved line storage for unique check. */
3020   struct line const *savedline = nullptr;
3021                                 /* &saved if there is a saved line. */
3022   size_t savealloc = 0;		/* Size allocated for the saved line. */
3023   struct line const **cur = xnmalloc (nfiles, sizeof *cur);
3024                                 /* Current line in each line table. */
3025   struct line const **base = xnmalloc (nfiles, sizeof *base);
3026                                 /* Base of each line table.  */
3027   size_t *ord = xnmalloc (nfiles, sizeof *ord);
3028                                 /* Table representing a permutation of fps,
3029                                    such that cur[ord[0]] is the smallest line
3030                                    and will be next output. */
3031   size_t i;
3032   size_t j;
3033   size_t t;
3034   struct keyfield const *key = keylist;
3035   saved.text = nullptr;
3036 
3037   /* Read initial lines from each input file. */
3038   for (i = 0; i < nfiles; )
3039     {
3040       initbuf (&buffer[i], sizeof (struct line),
3041                MAX (merge_buffer_size, sort_size / nfiles));
3042       if (fillbuf (&buffer[i], fps[i], files[i].name))
3043         {
3044           struct line const *linelim = buffer_linelim (&buffer[i]);
3045           cur[i] = linelim - 1;
3046           base[i] = linelim - buffer[i].nlines;
3047           i++;
3048         }
3049       else
3050         {
3051           /* fps[i] is empty; eliminate it from future consideration.  */
3052           xfclose (fps[i], files[i].name);
3053           if (i < ntemps)
3054             {
3055               ntemps--;
3056               zaptemp (files[i].name);
3057             }
3058           free (buffer[i].buf);
3059           --nfiles;
3060           for (j = i; j < nfiles; ++j)
3061             {
3062               files[j] = files[j + 1];
3063               fps[j] = fps[j + 1];
3064             }
3065         }
3066     }
3067 
3068   /* Set up the ord table according to comparisons among input lines.
3069      Since this only reorders two items if one is strictly greater than
3070      the other, it is stable. */
3071   for (i = 0; i < nfiles; ++i)
3072     ord[i] = i;
3073   for (i = 1; i < nfiles; ++i)
3074     if (0 < compare (cur[ord[i - 1]], cur[ord[i]]))
3075       t = ord[i - 1], ord[i - 1] = ord[i], ord[i] = t, i = 0;
3076 
3077   /* Repeatedly output the smallest line until no input remains. */
3078   while (nfiles)
3079     {
3080       struct line const *smallest = cur[ord[0]];
3081 
3082       /* If uniquified output is turned on, output only the first of
3083          an identical series of lines. */
3084       if (unique)
3085         {
3086           if (savedline && compare (savedline, smallest))
3087             {
3088               savedline = nullptr;
3089               write_line (&saved, ofp, output_file);
3090             }
3091           if (!savedline)
3092             {
3093               savedline = &saved;
3094               if (savealloc < smallest->length)
3095                 {
3096                   do
3097                     if (! savealloc)
3098                       {
3099                         savealloc = smallest->length;
3100                         break;
3101                       }
3102                   while ((savealloc *= 2) < smallest->length);
3103 
3104                   free (saved.text);
3105                   saved.text = xmalloc (savealloc);
3106                 }
3107               saved.length = smallest->length;
3108               memcpy (saved.text, smallest->text, saved.length);
3109               if (key)
3110                 {
3111                   saved.keybeg =
3112                     saved.text + (smallest->keybeg - smallest->text);
3113                   saved.keylim =
3114                     saved.text + (smallest->keylim - smallest->text);
3115                 }
3116             }
3117         }
3118       else
3119         write_line (smallest, ofp, output_file);
3120 
3121       /* Check if we need to read more lines into memory. */
3122       if (base[ord[0]] < smallest)
3123         cur[ord[0]] = smallest - 1;
3124       else
3125         {
3126           if (fillbuf (&buffer[ord[0]], fps[ord[0]], files[ord[0]].name))
3127             {
3128               struct line const *linelim = buffer_linelim (&buffer[ord[0]]);
3129               cur[ord[0]] = linelim - 1;
3130               base[ord[0]] = linelim - buffer[ord[0]].nlines;
3131             }
3132           else
3133             {
3134               /* We reached EOF on fps[ord[0]].  */
3135               for (i = 1; i < nfiles; ++i)
3136                 if (ord[i] > ord[0])
3137                   --ord[i];
3138               --nfiles;
3139               xfclose (fps[ord[0]], files[ord[0]].name);
3140               if (ord[0] < ntemps)
3141                 {
3142                   ntemps--;
3143                   zaptemp (files[ord[0]].name);
3144                 }
3145               free (buffer[ord[0]].buf);
3146               for (i = ord[0]; i < nfiles; ++i)
3147                 {
3148                   fps[i] = fps[i + 1];
3149                   files[i] = files[i + 1];
3150                   buffer[i] = buffer[i + 1];
3151                   cur[i] = cur[i + 1];
3152                   base[i] = base[i + 1];
3153                 }
3154               for (i = 0; i < nfiles; ++i)
3155                 ord[i] = ord[i + 1];
3156               continue;
3157             }
3158         }
3159 
3160       /* The new line just read in may be larger than other lines
3161          already in main memory; push it back in the queue until we
3162          encounter a line larger than it.  Optimize for the common
3163          case where the new line is smallest.  */
3164       {
3165         size_t lo = 1;
3166         size_t hi = nfiles;
3167         size_t probe = lo;
3168         size_t ord0 = ord[0];
3169         size_t count_of_smaller_lines;
3170 
3171         while (lo < hi)
3172           {
3173             int cmp = compare (cur[ord0], cur[ord[probe]]);
3174             if (cmp < 0 || (cmp == 0 && ord0 < ord[probe]))
3175               hi = probe;
3176             else
3177               lo = probe + 1;
3178             probe = (lo + hi) / 2;
3179           }
3180 
3181         count_of_smaller_lines = lo - 1;
3182         for (j = 0; j < count_of_smaller_lines; j++)
3183           ord[j] = ord[j + 1];
3184         ord[count_of_smaller_lines] = ord0;
3185       }
3186     }
3187 
3188   if (unique && savedline)
3189     {
3190       write_line (&saved, ofp, output_file);
3191       free (saved.text);
3192     }
3193 
3194   xfclose (ofp, output_file);
3195   free (fps);
3196   free (buffer);
3197   free (ord);
3198   free (base);
3199   free (cur);
3200 }
3201 
3202 /* Merge lines from FILES onto OFP.  NTEMPS is the number of temporary
3203    files (all of which are at the start of the FILES array), and
3204    NFILES is the number of files; 0 <= NTEMPS <= NFILES <= NMERGE.
3205    Close input and output files before returning.
3206    OUTPUT_FILE gives the name of the output file.
3207 
3208    Return the number of files successfully merged.  This number can be
3209    less than NFILES if we ran low on file descriptors, but in this
3210    case it is never less than 2.  */
3211 
3212 static size_t
mergefiles(struct sortfile * files,size_t ntemps,size_t nfiles,FILE * ofp,char const * output_file)3213 mergefiles (struct sortfile *files, size_t ntemps, size_t nfiles,
3214             FILE *ofp, char const *output_file)
3215 {
3216   FILE **fps;
3217   size_t nopened = open_input_files (files, nfiles, &fps);
3218   if (nopened < nfiles && nopened < 2)
3219     sort_die (_("open failed"), files[nopened].name);
3220   mergefps (files, ntemps, nopened, ofp, output_file, fps);
3221   return nopened;
3222 }
3223 
3224 /* Merge into T (of size NLINES) the two sorted arrays of lines
3225    LO (with NLINES / 2 members), and
3226    T - (NLINES / 2) (with NLINES - NLINES / 2 members).
3227    T and LO point just past their respective arrays, and the arrays
3228    are in reverse order.  NLINES must be at least 2.  */
3229 
3230 static void
mergelines(struct line * restrict t,size_t nlines,struct line const * restrict lo)3231 mergelines (struct line *restrict t, size_t nlines,
3232             struct line const *restrict lo)
3233 {
3234   size_t nlo = nlines / 2;
3235   size_t nhi = nlines - nlo;
3236   struct line *hi = t - nlo;
3237 
3238   while (true)
3239     if (compare (lo - 1, hi - 1) <= 0)
3240       {
3241         *--t = *--lo;
3242         if (! --nlo)
3243           {
3244             /* HI must equal T now, and there is no need to copy from
3245                HI to T. */
3246             return;
3247           }
3248       }
3249     else
3250       {
3251         *--t = *--hi;
3252         if (! --nhi)
3253           {
3254             do
3255               *--t = *--lo;
3256             while (--nlo);
3257 
3258             return;
3259           }
3260       }
3261 }
3262 
3263 /* Sort the array LINES with NLINES members, using TEMP for temporary space.
3264    Do this all within one thread.  NLINES must be at least 2.
3265    If TO_TEMP, put the sorted output into TEMP, and TEMP is as large as LINES.
3266    Otherwise the sort is in-place and TEMP is half-sized.
3267    The input and output arrays are in reverse order, and LINES and
3268    TEMP point just past the end of their respective arrays.
3269 
3270    Use a recursive divide-and-conquer algorithm, in the style
3271    suggested by Knuth volume 3 (2nd edition), exercise 5.2.4-23.  Use
3272    the optimization suggested by exercise 5.2.4-10; this requires room
3273    for only 1.5*N lines, rather than the usual 2*N lines.  Knuth
3274    writes that this memory optimization was originally published by
3275    D. A. Bell, Comp J. 1 (1958), 75.  */
3276 
3277 static void
sequential_sort(struct line * restrict lines,size_t nlines,struct line * restrict temp,bool to_temp)3278 sequential_sort (struct line *restrict lines, size_t nlines,
3279                  struct line *restrict temp, bool to_temp)
3280 {
3281   if (nlines == 2)
3282     {
3283       /* Declare 'swap' as int, not bool, to work around a bug
3284         <https://lists.gnu.org/r/bug-coreutils/2005-10/msg00086.html>
3285          in the IBM xlc 6.0.0.0 compiler in 64-bit mode.  */
3286       int swap = (0 < compare (&lines[-1], &lines[-2]));
3287       if (to_temp)
3288         {
3289           temp[-1] = lines[-1 - swap];
3290           temp[-2] = lines[-2 + swap];
3291         }
3292       else if (swap)
3293         {
3294           temp[-1] = lines[-1];
3295           lines[-1] = lines[-2];
3296           lines[-2] = temp[-1];
3297         }
3298     }
3299   else
3300     {
3301       size_t nlo = nlines / 2;
3302       size_t nhi = nlines - nlo;
3303       struct line *lo = lines;
3304       struct line *hi = lines - nlo;
3305 
3306       sequential_sort (hi, nhi, temp - (to_temp ? nlo : 0), to_temp);
3307       if (1 < nlo)
3308         sequential_sort (lo, nlo, temp, !to_temp);
3309       else if (!to_temp)
3310         temp[-1] = lo[-1];
3311 
3312       struct line *dest;
3313       struct line const *sorted_lo;
3314       if (to_temp)
3315         {
3316           dest = temp;
3317           sorted_lo = lines;
3318         }
3319       else
3320         {
3321           dest = lines;
3322           sorted_lo = temp;
3323         }
3324       mergelines (dest, nlines, sorted_lo);
3325     }
3326 }
3327 
3328 static struct merge_node *init_node (struct merge_node *restrict,
3329                                      struct merge_node *restrict,
3330                                      struct line *, size_t, size_t, bool);
3331 
3332 
3333 /* Create and return a merge tree for NTHREADS threads, sorting NLINES
3334    lines, with destination DEST.  */
3335 static struct merge_node *
merge_tree_init(size_t nthreads,size_t nlines,struct line * dest)3336 merge_tree_init (size_t nthreads, size_t nlines, struct line *dest)
3337 {
3338   struct merge_node *merge_tree = xmalloc (2 * sizeof *merge_tree * nthreads);
3339 
3340   struct merge_node *root = merge_tree;
3341   root->lo = root->hi = root->end_lo = root->end_hi = nullptr;
3342   root->dest = nullptr;
3343   root->nlo = root->nhi = nlines;
3344   root->parent = nullptr;
3345   root->level = MERGE_END;
3346   root->queued = false;
3347   pthread_mutex_init (&root->lock, nullptr);
3348 
3349   init_node (root, root + 1, dest, nthreads, nlines, false);
3350   return merge_tree;
3351 }
3352 
3353 /* Destroy the merge tree. */
3354 static void
merge_tree_destroy(size_t nthreads,struct merge_node * merge_tree)3355 merge_tree_destroy (size_t nthreads, struct merge_node *merge_tree)
3356 {
3357   size_t n_nodes = nthreads * 2;
3358   struct merge_node *node = merge_tree;
3359 
3360   while (n_nodes--)
3361     {
3362       pthread_mutex_destroy (&node->lock);
3363       node++;
3364     }
3365 
3366   free (merge_tree);
3367 }
3368 
3369 /* Initialize a merge tree node and its descendants.  The node's
3370    parent is PARENT.  The node and its descendants are taken from the
3371    array of nodes NODE_POOL.  Their destination starts at DEST; they
3372    will consume NTHREADS threads.  The total number of sort lines is
3373    TOTAL_LINES.  IS_LO_CHILD is true if the node is the low child of
3374    its parent.  */
3375 
3376 static struct merge_node *
init_node(struct merge_node * restrict parent,struct merge_node * restrict node_pool,struct line * dest,size_t nthreads,size_t total_lines,bool is_lo_child)3377 init_node (struct merge_node *restrict parent,
3378            struct merge_node *restrict node_pool,
3379            struct line *dest, size_t nthreads,
3380            size_t total_lines, bool is_lo_child)
3381 {
3382   size_t nlines = (is_lo_child ? parent->nlo : parent->nhi);
3383   size_t nlo = nlines / 2;
3384   size_t nhi = nlines - nlo;
3385   struct line *lo = dest - total_lines;
3386   struct line *hi = lo - nlo;
3387   struct line **parent_end = (is_lo_child ? &parent->end_lo : &parent->end_hi);
3388 
3389   struct merge_node *node = node_pool++;
3390   node->lo = node->end_lo = lo;
3391   node->hi = node->end_hi = hi;
3392   node->dest = parent_end;
3393   node->nlo = nlo;
3394   node->nhi = nhi;
3395   node->parent = parent;
3396   node->level = parent->level + 1;
3397   node->queued = false;
3398   pthread_mutex_init (&node->lock, nullptr);
3399 
3400   if (nthreads > 1)
3401     {
3402       size_t lo_threads = nthreads / 2;
3403       size_t hi_threads = nthreads - lo_threads;
3404       node->lo_child = node_pool;
3405       node_pool = init_node (node, node_pool, lo, lo_threads,
3406                              total_lines, true);
3407       node->hi_child = node_pool;
3408       node_pool = init_node (node, node_pool, hi, hi_threads,
3409                              total_lines, false);
3410     }
3411   else
3412     {
3413       node->lo_child = nullptr;
3414       node->hi_child = nullptr;
3415     }
3416   return node_pool;
3417 }
3418 
3419 
3420 /* Compare two merge nodes A and B for priority.  */
3421 
3422 static int
compare_nodes(void const * a,void const * b)3423 compare_nodes (void const *a, void const *b)
3424 {
3425   struct merge_node const *nodea = a;
3426   struct merge_node const *nodeb = b;
3427   if (nodea->level == nodeb->level)
3428       return (nodea->nlo + nodea->nhi) < (nodeb->nlo + nodeb->nhi);
3429   return nodea->level < nodeb->level;
3430 }
3431 
3432 /* Lock a merge tree NODE.  */
3433 
3434 static inline void
lock_node(struct merge_node * node)3435 lock_node (struct merge_node *node)
3436 {
3437   pthread_mutex_lock (&node->lock);
3438 }
3439 
3440 /* Unlock a merge tree NODE. */
3441 
3442 static inline void
unlock_node(struct merge_node * node)3443 unlock_node (struct merge_node *node)
3444 {
3445   pthread_mutex_unlock (&node->lock);
3446 }
3447 
3448 /* Destroy merge QUEUE. */
3449 
3450 static void
queue_destroy(struct merge_node_queue * queue)3451 queue_destroy (struct merge_node_queue *queue)
3452 {
3453   heap_free (queue->priority_queue);
3454   pthread_cond_destroy (&queue->cond);
3455   pthread_mutex_destroy (&queue->mutex);
3456 }
3457 
3458 /* Initialize merge QUEUE, allocating space suitable for a maximum of
3459    NTHREADS threads.  */
3460 
3461 static void
queue_init(struct merge_node_queue * queue,size_t nthreads)3462 queue_init (struct merge_node_queue *queue, size_t nthreads)
3463 {
3464   /* Though it's highly unlikely all nodes are in the heap at the same
3465      time, the heap should accommodate all of them.  Counting a null
3466      dummy head for the heap, reserve 2 * NTHREADS nodes.  */
3467   queue->priority_queue = heap_alloc (compare_nodes, 2 * nthreads);
3468   pthread_mutex_init (&queue->mutex, nullptr);
3469   pthread_cond_init (&queue->cond, nullptr);
3470 }
3471 
3472 /* Insert NODE into QUEUE.  The caller either holds a lock on NODE, or
3473    does not need to lock NODE.  */
3474 
3475 static void
queue_insert(struct merge_node_queue * queue,struct merge_node * node)3476 queue_insert (struct merge_node_queue *queue, struct merge_node *node)
3477 {
3478   pthread_mutex_lock (&queue->mutex);
3479   heap_insert (queue->priority_queue, node);
3480   node->queued = true;
3481   pthread_cond_signal (&queue->cond);
3482   pthread_mutex_unlock (&queue->mutex);
3483 }
3484 
3485 /* Pop the top node off the priority QUEUE, lock the node, return it.  */
3486 
3487 static struct merge_node *
queue_pop(struct merge_node_queue * queue)3488 queue_pop (struct merge_node_queue *queue)
3489 {
3490   struct merge_node *node;
3491   pthread_mutex_lock (&queue->mutex);
3492   while (! (node = heap_remove_top (queue->priority_queue)))
3493     pthread_cond_wait (&queue->cond, &queue->mutex);
3494   pthread_mutex_unlock (&queue->mutex);
3495   lock_node (node);
3496   node->queued = false;
3497   return node;
3498 }
3499 
3500 /* Output LINE to TFP, unless -u is specified and the line compares
3501    equal to the previous line.  TEMP_OUTPUT is the name of TFP, or
3502    is null if TFP is standard output.
3503 
3504    This function does not save the line for comparison later, so it is
3505    appropriate only for internal sort.  */
3506 
3507 static void
write_unique(struct line const * line,FILE * tfp,char const * temp_output)3508 write_unique (struct line const *line, FILE *tfp, char const *temp_output)
3509 {
3510   if (unique)
3511     {
3512       if (saved_line.text && ! compare (line, &saved_line))
3513         return;
3514       saved_line = *line;
3515     }
3516 
3517   write_line (line, tfp, temp_output);
3518 }
3519 
3520 /* Merge the lines currently available to a NODE in the binary
3521    merge tree.  Merge a number of lines appropriate for this merge
3522    level, assuming TOTAL_LINES is the total number of lines.
3523 
3524    If merging at the top level, send output to TFP.  TEMP_OUTPUT is
3525    the name of TFP, or is null if TFP is standard output.  */
3526 
3527 static void
mergelines_node(struct merge_node * restrict node,size_t total_lines,FILE * tfp,char const * temp_output)3528 mergelines_node (struct merge_node *restrict node, size_t total_lines,
3529                  FILE *tfp, char const *temp_output)
3530 {
3531   struct line *lo_orig = node->lo;
3532   struct line *hi_orig = node->hi;
3533   size_t to_merge = MAX_MERGE (total_lines, node->level);
3534   size_t merged_lo;
3535   size_t merged_hi;
3536 
3537   if (node->level > MERGE_ROOT)
3538     {
3539       /* Merge to destination buffer. */
3540       struct line *dest = *node->dest;
3541       while (node->lo != node->end_lo && node->hi != node->end_hi && to_merge--)
3542         if (compare (node->lo - 1, node->hi - 1) <= 0)
3543           *--dest = *--node->lo;
3544         else
3545           *--dest = *--node->hi;
3546 
3547       merged_lo = lo_orig - node->lo;
3548       merged_hi = hi_orig - node->hi;
3549 
3550       if (node->nhi == merged_hi)
3551         while (node->lo != node->end_lo && to_merge--)
3552           *--dest = *--node->lo;
3553       else if (node->nlo == merged_lo)
3554         while (node->hi != node->end_hi && to_merge--)
3555           *--dest = *--node->hi;
3556       *node->dest = dest;
3557     }
3558   else
3559     {
3560       /* Merge directly to output. */
3561       while (node->lo != node->end_lo && node->hi != node->end_hi && to_merge--)
3562         {
3563           if (compare (node->lo - 1, node->hi - 1) <= 0)
3564             write_unique (--node->lo, tfp, temp_output);
3565           else
3566             write_unique (--node->hi, tfp, temp_output);
3567         }
3568 
3569       merged_lo = lo_orig - node->lo;
3570       merged_hi = hi_orig - node->hi;
3571 
3572       if (node->nhi == merged_hi)
3573         {
3574           while (node->lo != node->end_lo && to_merge--)
3575             write_unique (--node->lo, tfp, temp_output);
3576         }
3577       else if (node->nlo == merged_lo)
3578         {
3579           while (node->hi != node->end_hi && to_merge--)
3580             write_unique (--node->hi, tfp, temp_output);
3581         }
3582     }
3583 
3584   /* Update NODE. */
3585   merged_lo = lo_orig - node->lo;
3586   merged_hi = hi_orig - node->hi;
3587   node->nlo -= merged_lo;
3588   node->nhi -= merged_hi;
3589 }
3590 
3591 /* Into QUEUE, insert NODE if it is not already queued, and if one of
3592    NODE's children has available lines and the other either has
3593    available lines or has exhausted its lines.  */
3594 
3595 static void
queue_check_insert(struct merge_node_queue * queue,struct merge_node * node)3596 queue_check_insert (struct merge_node_queue *queue, struct merge_node *node)
3597 {
3598   if (! node->queued)
3599     {
3600       bool lo_avail = (node->lo - node->end_lo) != 0;
3601       bool hi_avail = (node->hi - node->end_hi) != 0;
3602       if (lo_avail ? hi_avail || ! node->nhi : hi_avail && ! node->nlo)
3603         queue_insert (queue, node);
3604     }
3605 }
3606 
3607 /* Into QUEUE, insert NODE's parent if the parent can now be worked on.  */
3608 
3609 static void
queue_check_insert_parent(struct merge_node_queue * queue,struct merge_node * node)3610 queue_check_insert_parent (struct merge_node_queue *queue,
3611                            struct merge_node *node)
3612 {
3613   if (node->level > MERGE_ROOT)
3614     {
3615       lock_node (node->parent);
3616       queue_check_insert (queue, node->parent);
3617       unlock_node (node->parent);
3618     }
3619   else if (node->nlo + node->nhi == 0)
3620     {
3621       /* If the MERGE_ROOT NODE has finished merging, insert the
3622          MERGE_END node.  */
3623       queue_insert (queue, node->parent);
3624     }
3625 }
3626 
3627 /* Repeatedly pop QUEUE for a node with lines to merge, and merge at least
3628    some of those lines, until the MERGE_END node is popped.
3629    TOTAL_LINES is the total number of lines.  If merging at the top
3630    level, send output to TFP.  TEMP_OUTPUT is the name of TFP, or is
3631    null if TFP is standard output.  */
3632 
3633 static void
merge_loop(struct merge_node_queue * queue,size_t total_lines,FILE * tfp,char const * temp_output)3634 merge_loop (struct merge_node_queue *queue,
3635             size_t total_lines, FILE *tfp, char const *temp_output)
3636 {
3637   while (true)
3638     {
3639       struct merge_node *node = queue_pop (queue);
3640 
3641       if (node->level == MERGE_END)
3642         {
3643           unlock_node (node);
3644           /* Reinsert so other threads can pop it. */
3645           queue_insert (queue, node);
3646           break;
3647         }
3648       mergelines_node (node, total_lines, tfp, temp_output);
3649       queue_check_insert (queue, node);
3650       queue_check_insert_parent (queue, node);
3651 
3652       unlock_node (node);
3653     }
3654 }
3655 
3656 
3657 static void sortlines (struct line *restrict, size_t, size_t,
3658                        struct merge_node *, struct merge_node_queue *,
3659                        FILE *, char const *);
3660 
3661 /* Thread arguments for sortlines_thread. */
3662 
3663 struct thread_args
3664 {
3665   /* Source, i.e., the array of lines to sort.  This points just past
3666      the end of the array.  */
3667   struct line *lines;
3668 
3669   /* Number of threads to use.  If 0 or 1, sort single-threaded.  */
3670   size_t nthreads;
3671 
3672   /* Number of lines in LINES and DEST.  */
3673   size_t const total_lines;
3674 
3675   /* Merge node. Lines from this node and this node's sibling will merged
3676      to this node's parent. */
3677   struct merge_node *const node;
3678 
3679   /* The priority queue controlling available work for the entire
3680      internal sort.  */
3681   struct merge_node_queue *const queue;
3682 
3683   /* If at the top level, the file to output to, and the file's name.
3684      If the file is standard output, the file's name is null.  */
3685   FILE *tfp;
3686   char const *output_temp;
3687 };
3688 
3689 /* Like sortlines, except with a signature acceptable to pthread_create.  */
3690 
3691 static void *
sortlines_thread(void * data)3692 sortlines_thread (void *data)
3693 {
3694   struct thread_args const *args = data;
3695   sortlines (args->lines, args->nthreads, args->total_lines,
3696              args->node, args->queue, args->tfp,
3697              args->output_temp);
3698   return nullptr;
3699 }
3700 
3701 /* Sort lines, possibly in parallel.  The arguments are as in struct
3702    thread_args above.
3703 
3704    The algorithm has three phases: node creation, sequential sort,
3705    and binary merge.
3706 
3707    During node creation, sortlines recursively visits each node in the
3708    binary merge tree and creates a NODE structure corresponding to all the
3709    future line merging NODE is responsible for. For each call to
3710    sortlines, half the available threads are assigned to each recursive
3711    call, until a leaf node having only 1 available thread is reached.
3712 
3713    Each leaf node then performs two sequential sorts, one on each half of
3714    the lines it is responsible for. It records in its NODE structure that
3715    there are two sorted sublists available to merge from, and inserts its
3716    NODE into the priority queue.
3717 
3718    The binary merge phase then begins. Each thread drops into a loop
3719    where the thread retrieves a NODE from the priority queue, merges lines
3720    available to that NODE, and potentially insert NODE or its parent back
3721    into the queue if there are sufficient available lines for them to
3722    merge. This continues until all lines at all nodes of the merge tree
3723    have been merged. */
3724 
3725 static void
sortlines(struct line * restrict lines,size_t nthreads,size_t total_lines,struct merge_node * node,struct merge_node_queue * queue,FILE * tfp,char const * temp_output)3726 sortlines (struct line *restrict lines, size_t nthreads,
3727            size_t total_lines, struct merge_node *node,
3728            struct merge_node_queue *queue, FILE *tfp, char const *temp_output)
3729 {
3730   size_t nlines = node->nlo + node->nhi;
3731 
3732   /* Calculate thread arguments. */
3733   size_t lo_threads = nthreads / 2;
3734   size_t hi_threads = nthreads - lo_threads;
3735   pthread_t thread;
3736   struct thread_args args = {lines, lo_threads, total_lines,
3737                              node->lo_child, queue, tfp, temp_output};
3738 
3739   if (nthreads > 1 && SUBTHREAD_LINES_HEURISTIC <= nlines
3740       && pthread_create (&thread, nullptr, sortlines_thread, &args) == 0)
3741     {
3742       sortlines (lines - node->nlo, hi_threads, total_lines,
3743                  node->hi_child, queue, tfp, temp_output);
3744       pthread_join (thread, nullptr);
3745     }
3746   else
3747     {
3748       /* Nthreads = 1, this is a leaf NODE, or pthread_create failed.
3749          Sort with 1 thread. */
3750       size_t nlo = node->nlo;
3751       size_t nhi = node->nhi;
3752       struct line *temp = lines - total_lines;
3753       if (1 < nhi)
3754         sequential_sort (lines - nlo, nhi, temp - nlo / 2, false);
3755       if (1 < nlo)
3756         sequential_sort (lines, nlo, temp, false);
3757 
3758       /* Update merge NODE. No need to lock yet. */
3759       node->lo = lines;
3760       node->hi = lines - nlo;
3761       node->end_lo = lines - nlo;
3762       node->end_hi = lines - nlo - nhi;
3763 
3764       queue_insert (queue, node);
3765       merge_loop (queue, total_lines, tfp, temp_output);
3766     }
3767 }
3768 
3769 /* Scan through FILES[NTEMPS .. NFILES-1] looking for files that are
3770    the same as OUTFILE.  If found, replace each with the same
3771    temporary copy that can be merged into OUTFILE without destroying
3772    OUTFILE before it is completely read.  This temporary copy does not
3773    count as a merge temp, so don't worry about incrementing NTEMPS in
3774    the caller; final cleanup will remove it, not zaptemp.
3775 
3776    This test ensures that an otherwise-erroneous use like
3777    "sort -m -o FILE ... FILE ..." copies FILE before writing to it.
3778    It's not clear that POSIX requires this nicety.
3779    Detect common error cases, but don't try to catch obscure cases like
3780    "cat ... FILE ... | sort -m -o FILE"
3781    where traditional "sort" doesn't copy the input and where
3782    people should know that they're getting into trouble anyway.
3783    Catching these obscure cases would slow down performance in
3784    common cases.  */
3785 
3786 static void
avoid_trashing_input(struct sortfile * files,size_t ntemps,size_t nfiles,char const * outfile)3787 avoid_trashing_input (struct sortfile *files, size_t ntemps,
3788                       size_t nfiles, char const *outfile)
3789 {
3790   struct tempnode *tempcopy = nullptr;
3791 
3792   for (size_t i = ntemps; i < nfiles; i++)
3793     {
3794       bool is_stdin = STREQ (files[i].name, "-");
3795       bool same;
3796       struct stat instat;
3797 
3798       if (outfile && STREQ (outfile, files[i].name) && !is_stdin)
3799         same = true;
3800       else
3801         {
3802           struct stat *outst = get_outstatus ();
3803           if (!outst)
3804             break;
3805 
3806           same = (((is_stdin
3807                     ? fstat (STDIN_FILENO, &instat)
3808                     : stat (files[i].name, &instat))
3809                    == 0)
3810                   && psame_inode (&instat, outst));
3811         }
3812 
3813       if (same)
3814         {
3815           if (! tempcopy)
3816             {
3817               FILE *tftp;
3818               tempcopy = create_temp (&tftp);
3819               mergefiles (&files[i], 0, 1, tftp, tempcopy->name);
3820             }
3821 
3822           files[i].name = tempcopy->name;
3823           files[i].temp = tempcopy;
3824         }
3825     }
3826 }
3827 
3828 /* Scan the input files to ensure all are accessible.
3829    Otherwise exit with a diagnostic.
3830 
3831    This will catch common issues with permissions etc.
3832    but will fail to notice issues where you can open but not read,
3833    like when a directory is specified on some systems.
3834    Catching these obscure cases could slow down performance in
3835    common cases.  */
3836 
3837 static void
check_inputs(char * const * files,size_t nfiles)3838 check_inputs (char *const *files, size_t nfiles)
3839 {
3840   for (size_t i = 0; i < nfiles; i++)
3841     {
3842       if (STREQ (files[i], "-"))
3843         continue;
3844 
3845       if (euidaccess (files[i], R_OK) != 0)
3846         sort_die (_("cannot read"), files[i]);
3847     }
3848 }
3849 
3850 /* Ensure a specified output file can be created or written to,
3851    and point stdout to it.  Do not truncate the file.
3852    Exit with a diagnostic on failure.  */
3853 
3854 static void
check_output(char const * outfile)3855 check_output (char const *outfile)
3856 {
3857   if (outfile)
3858     {
3859       int oflags = O_WRONLY | O_BINARY | O_CLOEXEC | O_CREAT;
3860       int outfd = open (outfile, oflags, MODE_RW_UGO);
3861       if (outfd < 0)
3862         sort_die (_("open failed"), outfile);
3863       move_fd (outfd, STDOUT_FILENO);
3864     }
3865 }
3866 
3867 /* Merge the input FILES.  NTEMPS is the number of files at the
3868    start of FILES that are temporary; it is zero at the top level.
3869    NFILES is the total number of files.  Put the output in
3870    OUTPUT_FILE; a null OUTPUT_FILE stands for standard output.  */
3871 
3872 static void
merge(struct sortfile * files,size_t ntemps,size_t nfiles,char const * output_file)3873 merge (struct sortfile *files, size_t ntemps, size_t nfiles,
3874        char const *output_file)
3875 {
3876   while (nmerge < nfiles)
3877     {
3878       /* Number of input files processed so far.  */
3879       size_t in;
3880 
3881       /* Number of output files generated so far.  */
3882       size_t out;
3883 
3884       /* nfiles % NMERGE; this counts input files that are left over
3885          after all full-sized merges have been done.  */
3886       size_t remainder;
3887 
3888       /* Number of easily-available slots at the next loop iteration.  */
3889       size_t cheap_slots;
3890 
3891       /* Do as many NMERGE-size merges as possible. In the case that
3892          nmerge is bogus, increment by the maximum number of file
3893          descriptors allowed.  */
3894       for (out = in = 0; nmerge <= nfiles - in; out++)
3895         {
3896           FILE *tfp;
3897           struct tempnode *temp = create_temp (&tfp);
3898           size_t num_merged = mergefiles (&files[in], MIN (ntemps, nmerge),
3899                                           nmerge, tfp, temp->name);
3900           ntemps -= MIN (ntemps, num_merged);
3901           files[out].name = temp->name;
3902           files[out].temp = temp;
3903           in += num_merged;
3904         }
3905 
3906       remainder = nfiles - in;
3907       cheap_slots = nmerge - out % nmerge;
3908 
3909       if (cheap_slots < remainder)
3910         {
3911           /* So many files remain that they can't all be put into the last
3912              NMERGE-sized output window.  Do one more merge.  Merge as few
3913              files as possible, to avoid needless I/O.  */
3914           size_t nshortmerge = remainder - cheap_slots + 1;
3915           FILE *tfp;
3916           struct tempnode *temp = create_temp (&tfp);
3917           size_t num_merged = mergefiles (&files[in], MIN (ntemps, nshortmerge),
3918                                           nshortmerge, tfp, temp->name);
3919           ntemps -= MIN (ntemps, num_merged);
3920           files[out].name = temp->name;
3921           files[out++].temp = temp;
3922           in += num_merged;
3923         }
3924 
3925       /* Put the remaining input files into the last NMERGE-sized output
3926          window, so they will be merged in the next pass.  */
3927       memmove (&files[out], &files[in], (nfiles - in) * sizeof *files);
3928       ntemps += out;
3929       nfiles -= in - out;
3930     }
3931 
3932   avoid_trashing_input (files, ntemps, nfiles, output_file);
3933 
3934   /* We aren't guaranteed that this final mergefiles will work, therefore we
3935      try to merge into the output, and then merge as much as we can into a
3936      temp file if we can't. Repeat.  */
3937 
3938   while (true)
3939     {
3940       /* Merge directly into the output file if possible.  */
3941       FILE **fps;
3942       size_t nopened = open_input_files (files, nfiles, &fps);
3943 
3944       if (nopened == nfiles)
3945         {
3946           FILE *ofp = stream_open (output_file, "w");
3947           if (ofp)
3948             {
3949               mergefps (files, ntemps, nfiles, ofp, output_file, fps);
3950               break;
3951             }
3952           if (errno != EMFILE || nopened <= 2)
3953             sort_die (_("open failed"), output_file);
3954         }
3955       else if (nopened <= 2)
3956         sort_die (_("open failed"), files[nopened].name);
3957 
3958       /* We ran out of file descriptors.  Close one of the input
3959          files, to gain a file descriptor.  Then create a temporary
3960          file with our spare file descriptor.  Retry if that failed
3961          (e.g., some other process could open a file between the time
3962          we closed and tried to create).  */
3963       FILE *tfp;
3964       struct tempnode *temp;
3965       do
3966         {
3967           nopened--;
3968           xfclose (fps[nopened], files[nopened].name);
3969           temp = maybe_create_temp (&tfp, ! (nopened <= 2));
3970         }
3971       while (!temp);
3972 
3973       /* Merge into the newly allocated temporary.  */
3974       mergefps (&files[0], MIN (ntemps, nopened), nopened, tfp, temp->name,
3975                 fps);
3976       ntemps -= MIN (ntemps, nopened);
3977       files[0].name = temp->name;
3978       files[0].temp = temp;
3979 
3980       memmove (&files[1], &files[nopened], (nfiles - nopened) * sizeof *files);
3981       ntemps++;
3982       nfiles -= nopened - 1;
3983     }
3984 }
3985 
3986 /* Sort NFILES FILES onto OUTPUT_FILE.  Use at most NTHREADS threads.  */
3987 
3988 static void
sort(char * const * files,size_t nfiles,char const * output_file,size_t nthreads)3989 sort (char *const *files, size_t nfiles, char const *output_file,
3990       size_t nthreads)
3991 {
3992   struct buffer buf;
3993   size_t ntemps = 0;
3994   bool output_file_created = false;
3995 
3996   buf.alloc = 0;
3997 
3998   while (nfiles)
3999     {
4000       char const *temp_output;
4001       char const *file = *files;
4002       FILE *fp = xfopen (file, "r");
4003       FILE *tfp;
4004 
4005       size_t bytes_per_line;
4006       if (nthreads > 1)
4007         {
4008           /* Get log P. */
4009           size_t tmp = 1;
4010           size_t mult = 1;
4011           while (tmp < nthreads)
4012             {
4013               tmp *= 2;
4014               mult++;
4015             }
4016           bytes_per_line = (mult * sizeof (struct line));
4017         }
4018       else
4019         bytes_per_line = sizeof (struct line) * 3 / 2;
4020 
4021       if (! buf.alloc)
4022         initbuf (&buf, bytes_per_line,
4023                  sort_buffer_size (&fp, 1, files, nfiles, bytes_per_line));
4024       buf.eof = false;
4025       files++;
4026       nfiles--;
4027 
4028       while (fillbuf (&buf, fp, file))
4029         {
4030           struct line *line;
4031 
4032           if (buf.eof && nfiles
4033               && (bytes_per_line + 1
4034                   < (buf.alloc - buf.used - bytes_per_line * buf.nlines)))
4035             {
4036               /* End of file, but there is more input and buffer room.
4037                  Concatenate the next input file; this is faster in
4038                  the usual case.  */
4039               buf.left = buf.used;
4040               break;
4041             }
4042 
4043           saved_line.text = nullptr;
4044           line = buffer_linelim (&buf);
4045           if (buf.eof && !nfiles && !ntemps && !buf.left)
4046             {
4047               xfclose (fp, file);
4048               tfp = xfopen (output_file, "w");
4049               temp_output = output_file;
4050               output_file_created = true;
4051             }
4052           else
4053             {
4054               ++ntemps;
4055               temp_output = create_temp (&tfp)->name;
4056             }
4057           if (1 < buf.nlines)
4058             {
4059               struct merge_node_queue queue;
4060               queue_init (&queue, nthreads);
4061               struct merge_node *merge_tree =
4062                 merge_tree_init (nthreads, buf.nlines, line);
4063 
4064               sortlines (line, nthreads, buf.nlines, merge_tree + 1,
4065                          &queue, tfp, temp_output);
4066 
4067               merge_tree_destroy (nthreads, merge_tree);
4068               queue_destroy (&queue);
4069             }
4070           else
4071             write_unique (line - 1, tfp, temp_output);
4072 
4073           xfclose (tfp, temp_output);
4074 
4075           if (output_file_created)
4076             goto finish;
4077         }
4078       xfclose (fp, file);
4079     }
4080 
4081  finish:
4082   free (buf.buf);
4083 
4084   if (! output_file_created)
4085     {
4086       struct tempnode *node = temphead;
4087       struct sortfile *tempfiles = xnmalloc (ntemps, sizeof *tempfiles);
4088       for (size_t i = 0; node; i++)
4089         {
4090           tempfiles[i].name = node->name;
4091           tempfiles[i].temp = node;
4092           node = node->next;
4093         }
4094       merge (tempfiles, ntemps, ntemps, output_file);
4095       free (tempfiles);
4096     }
4097 
4098   reap_all ();
4099 }
4100 
4101 /* Insert a malloc'd copy of key KEY_ARG at the end of the key list.  */
4102 
4103 static void
insertkey(struct keyfield * key_arg)4104 insertkey (struct keyfield *key_arg)
4105 {
4106   struct keyfield **p;
4107   struct keyfield *key = xmemdup (key_arg, sizeof *key);
4108 
4109   for (p = &keylist; *p; p = &(*p)->next)
4110     continue;
4111   *p = key;
4112   key->next = nullptr;
4113 }
4114 
4115 /* Report a bad field specification SPEC, with extra info MSGID.  */
4116 
4117 static void
badfieldspec(char const * spec,char const * msgid)4118 badfieldspec (char const *spec, char const *msgid)
4119 {
4120   error (SORT_FAILURE, 0, _("%s: invalid field specification %s"),
4121          _(msgid), quote (spec));
4122 }
4123 
4124 /* Report incompatible options.  */
4125 
4126 static void
incompatible_options(char const * opts)4127 incompatible_options (char const *opts)
4128 {
4129   error (SORT_FAILURE, 0, _("options '-%s' are incompatible"), (opts));
4130 }
4131 
4132 /* Check compatibility of ordering options.  */
4133 
4134 static void
check_ordering_compatibility(void)4135 check_ordering_compatibility (void)
4136 {
4137   struct keyfield *key;
4138 
4139   for (key = keylist; key; key = key->next)
4140     if (1 < (key->numeric + key->general_numeric + key->human_numeric
4141              + key->month + (key->version | key->random | !!key->ignore)))
4142       {
4143         /* The following is too big, but guaranteed to be "big enough".  */
4144         char opts[sizeof short_options];
4145         /* Clear flags we're not interested in.  */
4146         key->skipsblanks = key->skipeblanks = key->reverse = false;
4147         key_to_opts (key, opts);
4148         incompatible_options (opts);
4149       }
4150 }
4151 
4152 /* Parse the leading integer in STRING and store the resulting value
4153    (which must fit into size_t) into *VAL.  Return the address of the
4154    suffix after the integer.  If the value is too large, silently
4155    substitute SIZE_MAX.  If MSGID is null, return nullptr after
4156    failure; otherwise, report MSGID and exit on failure.  */
4157 
4158 static char const *
parse_field_count(char const * string,size_t * val,char const * msgid)4159 parse_field_count (char const *string, size_t *val, char const *msgid)
4160 {
4161   char *suffix;
4162   uintmax_t n;
4163 
4164   switch (xstrtoumax (string, &suffix, 10, &n, ""))
4165     {
4166     case LONGINT_OK:
4167     case LONGINT_INVALID_SUFFIX_CHAR:
4168       *val = n;
4169       if (*val == n)
4170         break;
4171       FALLTHROUGH;
4172     case LONGINT_OVERFLOW:
4173     case LONGINT_OVERFLOW | LONGINT_INVALID_SUFFIX_CHAR:
4174       *val = SIZE_MAX;
4175       break;
4176 
4177     case LONGINT_INVALID:
4178       if (msgid)
4179         error (SORT_FAILURE, 0, _("%s: invalid count at start of %s"),
4180                _(msgid), quote (string));
4181       return nullptr;
4182     }
4183 
4184   return suffix;
4185 }
4186 
4187 /* Handle interrupts and hangups. */
4188 
4189 static void
sighandler(int sig)4190 sighandler (int sig)
4191 {
4192   if (! SA_NOCLDSTOP)
4193     signal (sig, SIG_IGN);
4194 
4195   cleanup ();
4196 
4197   signal (sig, SIG_DFL);
4198   raise (sig);
4199 }
4200 
4201 /* Set the ordering options for KEY specified in S.
4202    Return the address of the first character in S that
4203    is not a valid ordering option.
4204    BLANKTYPE is the kind of blanks that 'b' should skip. */
4205 
4206 static char *
set_ordering(char const * s,struct keyfield * key,enum blanktype blanktype)4207 set_ordering (char const *s, struct keyfield *key, enum blanktype blanktype)
4208 {
4209   while (*s)
4210     {
4211       switch (*s)
4212         {
4213         case 'b':
4214           if (blanktype == bl_start || blanktype == bl_both)
4215             key->skipsblanks = true;
4216           if (blanktype == bl_end || blanktype == bl_both)
4217             key->skipeblanks = true;
4218           break;
4219         case 'd':
4220           key->ignore = nondictionary;
4221           break;
4222         case 'f':
4223           key->translate = fold_toupper;
4224           break;
4225         case 'g':
4226           key->general_numeric = true;
4227           break;
4228         case 'h':
4229           key->human_numeric = true;
4230           break;
4231         case 'i':
4232           /* Option order should not matter, so don't let -i override
4233              -d.  -d implies -i, but -i does not imply -d.  */
4234           if (! key->ignore)
4235             key->ignore = nonprinting;
4236           break;
4237         case 'M':
4238           key->month = true;
4239           break;
4240         case 'n':
4241           key->numeric = true;
4242           break;
4243         case 'R':
4244           key->random = true;
4245           break;
4246         case 'r':
4247           key->reverse = true;
4248           break;
4249         case 'V':
4250           key->version = true;
4251           break;
4252         default:
4253           return (char *) s;
4254         }
4255       ++s;
4256     }
4257   return (char *) s;
4258 }
4259 
4260 /* Initialize KEY.  */
4261 
4262 static struct keyfield *
key_init(struct keyfield * key)4263 key_init (struct keyfield *key)
4264 {
4265   memset (key, 0, sizeof *key);
4266   key->eword = SIZE_MAX;
4267   return key;
4268 }
4269 
4270 int
main(int argc,char ** argv)4271 main (int argc, char **argv)
4272 {
4273   struct keyfield *key;
4274   struct keyfield key_buf;
4275   struct keyfield gkey;
4276   bool gkey_only = false;
4277   char const *s;
4278   int c = 0;
4279   char checkonly = 0;
4280   bool mergeonly = false;
4281   char *random_source = nullptr;
4282   bool need_random = false;
4283   size_t nthreads = 0;
4284   size_t nfiles = 0;
4285   bool posixly_correct = (getenv ("POSIXLY_CORRECT") != nullptr);
4286   int posix_ver = posix2_version ();
4287   bool traditional_usage = ! (200112 <= posix_ver && posix_ver < 200809);
4288   char **files;
4289   char *files_from = nullptr;
4290   struct Tokens tok;
4291   char const *outfile = nullptr;
4292   bool locale_ok;
4293 
4294   initialize_main (&argc, &argv);
4295   set_program_name (argv[0]);
4296   locale_ok = !! setlocale (LC_ALL, "");
4297   bindtextdomain (PACKAGE, LOCALEDIR);
4298   textdomain (PACKAGE);
4299 
4300   initialize_exit_failure (SORT_FAILURE);
4301 
4302   hard_LC_COLLATE = hard_locale (LC_COLLATE);
4303 #if HAVE_NL_LANGINFO
4304   hard_LC_TIME = hard_locale (LC_TIME);
4305 #endif
4306 
4307   /* Get locale's representation of the decimal point.  */
4308   {
4309     struct lconv const *locale = localeconv ();
4310 
4311     /* If the locale doesn't define a decimal point, or if the decimal
4312        point is multibyte, use the C locale's decimal point.  FIXME:
4313        add support for multibyte decimal points.  */
4314     decimal_point = locale->decimal_point[0];
4315     if (! decimal_point || locale->decimal_point[1])
4316       decimal_point = '.';
4317 
4318     /* FIXME: add support for multibyte thousands separators.  */
4319     thousands_sep = locale->thousands_sep[0];
4320     if (thousands_sep && locale->thousands_sep[1])
4321       thousands_sep_ignored = true;
4322     if (! thousands_sep || locale->thousands_sep[1])
4323       thousands_sep = NON_CHAR;
4324   }
4325 
4326   have_read_stdin = false;
4327   inittables ();
4328 
4329   {
4330     size_t i;
4331     static int const sig[] =
4332       {
4333         /* The usual suspects.  */
4334         SIGALRM, SIGHUP, SIGINT, SIGPIPE, SIGQUIT, SIGTERM,
4335 #ifdef SIGPOLL
4336         SIGPOLL,
4337 #endif
4338 #ifdef SIGPROF
4339         SIGPROF,
4340 #endif
4341 #ifdef SIGVTALRM
4342         SIGVTALRM,
4343 #endif
4344 #ifdef SIGXCPU
4345         SIGXCPU,
4346 #endif
4347 #ifdef SIGXFSZ
4348         SIGXFSZ,
4349 #endif
4350       };
4351     enum { nsigs = ARRAY_CARDINALITY (sig) };
4352 
4353 #if SA_NOCLDSTOP
4354     struct sigaction act;
4355 
4356     sigemptyset (&caught_signals);
4357     for (i = 0; i < nsigs; i++)
4358       {
4359         sigaction (sig[i], nullptr, &act);
4360         if (act.sa_handler != SIG_IGN)
4361           sigaddset (&caught_signals, sig[i]);
4362       }
4363 
4364     act.sa_handler = sighandler;
4365     act.sa_mask = caught_signals;
4366     act.sa_flags = 0;
4367 
4368     for (i = 0; i < nsigs; i++)
4369       if (sigismember (&caught_signals, sig[i]))
4370         sigaction (sig[i], &act, nullptr);
4371 #else
4372     for (i = 0; i < nsigs; i++)
4373       if (signal (sig[i], SIG_IGN) != SIG_IGN)
4374         {
4375           signal (sig[i], sighandler);
4376           siginterrupt (sig[i], 1);
4377         }
4378 #endif
4379   }
4380   signal (SIGCHLD, SIG_DFL); /* Don't inherit CHLD handling from parent.  */
4381 
4382   /* The signal mask is known, so it is safe to invoke exit_cleanup.  */
4383   atexit (exit_cleanup);
4384 
4385   key_init (&gkey);
4386   gkey.sword = SIZE_MAX;
4387 
4388   files = xnmalloc (argc, sizeof *files);
4389 
4390   while (true)
4391     {
4392       /* Parse an operand as a file after "--" was seen; or if
4393          pedantic and a file was seen, unless the POSIX version
4394          is not 1003.1-2001 and -c was not seen and the operand is
4395          "-o FILE" or "-oFILE".  */
4396       int oi = -1;
4397 
4398       if (c == -1
4399           || (posixly_correct && nfiles != 0
4400               && ! (traditional_usage
4401                     && ! checkonly
4402                     && optind != argc
4403                     && argv[optind][0] == '-' && argv[optind][1] == 'o'
4404                     && (argv[optind][2] || optind + 1 != argc)))
4405           || ((c = getopt_long (argc, argv, short_options,
4406                                 long_options, &oi))
4407               == -1))
4408         {
4409           if (argc <= optind)
4410             break;
4411           files[nfiles++] = argv[optind++];
4412         }
4413       else switch (c)
4414         {
4415         case 1:
4416           key = nullptr;
4417           if (optarg[0] == '+')
4418             {
4419               bool minus_pos_usage = (optind != argc && argv[optind][0] == '-'
4420                                       && ISDIGIT (argv[optind][1]));
4421               traditional_usage |= minus_pos_usage && !posixly_correct;
4422               if (traditional_usage)
4423                 {
4424                   /* Treat +POS1 [-POS2] as a key if possible; but silently
4425                      treat an operand as a file if it is not a valid +POS1.  */
4426                   key = key_init (&key_buf);
4427                   s = parse_field_count (optarg + 1, &key->sword, nullptr);
4428                   if (s && *s == '.')
4429                     s = parse_field_count (s + 1, &key->schar, nullptr);
4430                   if (! (key->sword || key->schar))
4431                     key->sword = SIZE_MAX;
4432                   if (! s || *set_ordering (s, key, bl_start))
4433                     key = nullptr;
4434                   else
4435                     {
4436                       if (minus_pos_usage)
4437                         {
4438                           char const *optarg1 = argv[optind++];
4439                           s = parse_field_count (optarg1 + 1, &key->eword,
4440                                              N_("invalid number after '-'"));
4441                           if (*s == '.')
4442                             s = parse_field_count (s + 1, &key->echar,
4443                                                N_("invalid number after '.'"));
4444                           if (!key->echar && key->eword)
4445                             {
4446                               /* obsolescent syntax +A.x -B.y is equivalent to:
4447                                    -k A+1.x+1,B.y   (when y = 0)
4448                                    -k A+1.x+1,B+1.y (when y > 0)
4449                                  So eword is decremented as in the -k case
4450                                  only when the end field (B) is specified and
4451                                  echar (y) is 0.  */
4452                               key->eword--;
4453                             }
4454                           if (*set_ordering (s, key, bl_end))
4455                             badfieldspec (optarg1,
4456                                       N_("stray character in field spec"));
4457                         }
4458                       key->traditional_used = true;
4459                       insertkey (key);
4460                     }
4461                 }
4462             }
4463           if (! key)
4464             files[nfiles++] = optarg;
4465           break;
4466 
4467         case SORT_OPTION:
4468           c = XARGMATCH ("--sort", optarg, sort_args, sort_types);
4469           FALLTHROUGH;
4470         case 'b':
4471         case 'd':
4472         case 'f':
4473         case 'g':
4474         case 'h':
4475         case 'i':
4476         case 'M':
4477         case 'n':
4478         case 'r':
4479         case 'R':
4480         case 'V':
4481           {
4482             char str[2];
4483             str[0] = c;
4484             str[1] = '\0';
4485             set_ordering (str, &gkey, bl_both);
4486           }
4487           break;
4488 
4489         case CHECK_OPTION:
4490           c = (optarg
4491                ? XARGMATCH ("--check", optarg, check_args, check_types)
4492                : 'c');
4493           FALLTHROUGH;
4494         case 'c':
4495         case 'C':
4496           if (checkonly && checkonly != c)
4497             incompatible_options ("cC");
4498           checkonly = c;
4499           break;
4500 
4501         case COMPRESS_PROGRAM_OPTION:
4502           if (compress_program && !STREQ (compress_program, optarg))
4503             error (SORT_FAILURE, 0, _("multiple compress programs specified"));
4504           compress_program = optarg;
4505           break;
4506 
4507         case DEBUG_PROGRAM_OPTION:
4508           debug = true;
4509           break;
4510 
4511         case FILES0_FROM_OPTION:
4512           files_from = optarg;
4513           break;
4514 
4515         case 'k':
4516           key = key_init (&key_buf);
4517 
4518           /* Get POS1. */
4519           s = parse_field_count (optarg, &key->sword,
4520                                  N_("invalid number at field start"));
4521           if (! key->sword--)
4522             {
4523               /* Provoke with 'sort -k0' */
4524               badfieldspec (optarg, N_("field number is zero"));
4525             }
4526           if (*s == '.')
4527             {
4528               s = parse_field_count (s + 1, &key->schar,
4529                                      N_("invalid number after '.'"));
4530               if (! key->schar--)
4531                 {
4532                   /* Provoke with 'sort -k1.0' */
4533                   badfieldspec (optarg, N_("character offset is zero"));
4534                 }
4535             }
4536           if (! (key->sword || key->schar))
4537             key->sword = SIZE_MAX;
4538           s = set_ordering (s, key, bl_start);
4539           if (*s != ',')
4540             {
4541               key->eword = SIZE_MAX;
4542               key->echar = 0;
4543             }
4544           else
4545             {
4546               /* Get POS2. */
4547               s = parse_field_count (s + 1, &key->eword,
4548                                      N_("invalid number after ','"));
4549               if (! key->eword--)
4550                 {
4551                   /* Provoke with 'sort -k1,0' */
4552                   badfieldspec (optarg, N_("field number is zero"));
4553                 }
4554               if (*s == '.')
4555                 {
4556                   s = parse_field_count (s + 1, &key->echar,
4557                                          N_("invalid number after '.'"));
4558                 }
4559               s = set_ordering (s, key, bl_end);
4560             }
4561           if (*s)
4562             badfieldspec (optarg, N_("stray character in field spec"));
4563           insertkey (key);
4564           break;
4565 
4566         case 'm':
4567           mergeonly = true;
4568           break;
4569 
4570         case NMERGE_OPTION:
4571           specify_nmerge (oi, c, optarg);
4572           break;
4573 
4574         case 'o':
4575           if (outfile && !STREQ (outfile, optarg))
4576             error (SORT_FAILURE, 0, _("multiple output files specified"));
4577           outfile = optarg;
4578           break;
4579 
4580         case RANDOM_SOURCE_OPTION:
4581           if (random_source && !STREQ (random_source, optarg))
4582             error (SORT_FAILURE, 0, _("multiple random sources specified"));
4583           random_source = optarg;
4584           break;
4585 
4586         case 's':
4587           stable = true;
4588           break;
4589 
4590         case 'S':
4591           specify_sort_size (oi, c, optarg);
4592           break;
4593 
4594         case 't':
4595           {
4596             char newtab = optarg[0];
4597             if (! newtab)
4598               error (SORT_FAILURE, 0, _("empty tab"));
4599             if (optarg[1])
4600               {
4601                 if (STREQ (optarg, "\\0"))
4602                   newtab = '\0';
4603                 else
4604                   {
4605                     /* Provoke with 'sort -txx'.  Complain about
4606                        "multi-character tab" instead of "multibyte tab", so
4607                        that the diagnostic's wording does not need to be
4608                        changed once multibyte characters are supported.  */
4609                     error (SORT_FAILURE, 0, _("multi-character tab %s"),
4610                            quote (optarg));
4611                   }
4612               }
4613             if (tab != TAB_DEFAULT && tab != newtab)
4614               error (SORT_FAILURE, 0, _("incompatible tabs"));
4615             tab = newtab;
4616           }
4617           break;
4618 
4619         case 'T':
4620           add_temp_dir (optarg);
4621           break;
4622 
4623         case PARALLEL_OPTION:
4624           nthreads = specify_nthreads (oi, c, optarg);
4625           break;
4626 
4627         case 'u':
4628           unique = true;
4629           break;
4630 
4631         case 'y':
4632           /* Accept and ignore e.g. -y0 for compatibility with Solaris 2.x
4633              through Solaris 7.  It is also accepted by many non-Solaris
4634              "sort" implementations, e.g., AIX 5.2, HP-UX 11i v2, IRIX 6.5.
4635              -y is marked as obsolete starting with Solaris 8 (1999), but is
4636              still accepted as of Solaris 10 prerelease (2004).
4637 
4638              Solaris 2.5.1 "sort -y 100" reads the input file "100", but
4639              emulate Solaris 8 and 9 "sort -y 100" which ignores the "100",
4640              and which in general ignores the argument after "-y" if it
4641              consists entirely of digits (it can even be empty).  */
4642           if (optarg == argv[optind - 1])
4643             {
4644               char const *p;
4645               for (p = optarg; ISDIGIT (*p); p++)
4646                 continue;
4647               optind -= (*p != '\0');
4648             }
4649           break;
4650 
4651         case 'z':
4652           eolchar = 0;
4653           break;
4654 
4655         case_GETOPT_HELP_CHAR;
4656 
4657         case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
4658 
4659         default:
4660           usage (SORT_FAILURE);
4661         }
4662     }
4663 
4664   if (files_from)
4665     {
4666       /* When using --files0-from=F, you may not specify any files
4667          on the command-line.  */
4668       if (nfiles)
4669         {
4670           error (0, 0, _("extra operand %s"), quoteaf (files[0]));
4671           fprintf (stderr, "%s\n",
4672                    _("file operands cannot be combined with --files0-from"));
4673           usage (SORT_FAILURE);
4674         }
4675 
4676       FILE *stream = xfopen (files_from, "r");
4677 
4678       readtokens0_init (&tok);
4679 
4680       if (! readtokens0 (stream, &tok))
4681         error (SORT_FAILURE, 0, _("cannot read file names from %s"),
4682                quoteaf (files_from));
4683       xfclose (stream, files_from);
4684 
4685       if (tok.n_tok)
4686         {
4687           free (files);
4688           files = tok.tok;
4689           nfiles = tok.n_tok;
4690           for (size_t i = 0; i < nfiles; i++)
4691             {
4692               if (STREQ (files[i], "-"))
4693                 error (SORT_FAILURE, 0, _("when reading file names from stdin, "
4694                                           "no file name of %s allowed"),
4695                        quoteaf (files[i]));
4696               else if (files[i][0] == '\0')
4697                 {
4698                   /* Using the standard 'filename:line-number:' prefix here is
4699                      not totally appropriate, since NUL is the separator,
4700                      not NL, but it might be better than nothing.  */
4701                   unsigned long int file_number = i + 1;
4702                   error (SORT_FAILURE, 0,
4703                          _("%s:%lu: invalid zero-length file name"),
4704                          quotef (files_from), file_number);
4705                 }
4706             }
4707         }
4708       else
4709         error (SORT_FAILURE, 0, _("no input from %s"),
4710                quoteaf (files_from));
4711     }
4712 
4713   /* Inheritance of global options to individual keys. */
4714   for (key = keylist; key; key = key->next)
4715     {
4716       if (default_key_compare (key) && !key->reverse)
4717         {
4718           key->ignore = gkey.ignore;
4719           key->translate = gkey.translate;
4720           key->skipsblanks = gkey.skipsblanks;
4721           key->skipeblanks = gkey.skipeblanks;
4722           key->month = gkey.month;
4723           key->numeric = gkey.numeric;
4724           key->general_numeric = gkey.general_numeric;
4725           key->human_numeric = gkey.human_numeric;
4726           key->version = gkey.version;
4727           key->random = gkey.random;
4728           key->reverse = gkey.reverse;
4729         }
4730 
4731       need_random |= key->random;
4732     }
4733 
4734   if (!keylist && !default_key_compare (&gkey))
4735     {
4736       gkey_only = true;
4737       insertkey (&gkey);
4738       need_random |= gkey.random;
4739     }
4740 
4741   check_ordering_compatibility ();
4742 
4743   if (debug)
4744     {
4745       if (checkonly || outfile)
4746         {
4747           static char opts[] = "X --debug";
4748           opts[0] = (checkonly ? checkonly : 'o');
4749           incompatible_options (opts);
4750         }
4751 
4752       /* Always output the locale in debug mode, since this
4753          is such a common source of confusion.  */
4754 
4755       /* OpenBSD can only set some categories with LC_ALL above,
4756          so set LC_COLLATE explicitly to flag errors.  */
4757       if (locale_ok)
4758         locale_ok = !! setlocale (LC_COLLATE, "");
4759       if (! locale_ok)
4760           error (0, 0, "%s", _("failed to set locale"));
4761       if (hard_LC_COLLATE)
4762         error (0, 0, _("text ordering performed using %s sorting rules"),
4763                quote (setlocale (LC_COLLATE, nullptr)));
4764       else
4765         error (0, 0, "%s",
4766                _("text ordering performed using simple byte comparison"));
4767 
4768       key_warnings (&gkey, gkey_only);
4769     }
4770 
4771   reverse = gkey.reverse;
4772 
4773   if (need_random)
4774     random_md5_state_init (random_source);
4775 
4776   if (temp_dir_count == 0)
4777     {
4778       char const *tmp_dir = getenv ("TMPDIR");
4779       add_temp_dir (tmp_dir ? tmp_dir : DEFAULT_TMPDIR);
4780     }
4781 
4782   if (nfiles == 0)
4783     {
4784       nfiles = 1;
4785       free (files);
4786       files = xmalloc (sizeof *files);
4787       *files = (char *) "-";
4788     }
4789 
4790   /* Need to re-check that we meet the minimum requirement for memory
4791      usage with the final value for NMERGE. */
4792   if (0 < sort_size)
4793     sort_size = MAX (sort_size, MIN_SORT_SIZE);
4794 
4795   if (checkonly)
4796     {
4797       if (nfiles > 1)
4798         error (SORT_FAILURE, 0, _("extra operand %s not allowed with -%c"),
4799                quoteaf (files[1]), checkonly);
4800 
4801       if (outfile)
4802         {
4803           static char opts[] = {0, 'o', 0};
4804           opts[0] = checkonly;
4805           incompatible_options (opts);
4806         }
4807 
4808       /* POSIX requires that sort return 1 IFF invoked with -c or -C and the
4809          input is not properly sorted.  */
4810       exit (check (files[0], checkonly) ? EXIT_SUCCESS : SORT_OUT_OF_ORDER);
4811     }
4812 
4813   /* Check all inputs are accessible, or exit immediately.  */
4814   check_inputs (files, nfiles);
4815 
4816   /* Check output is writable, or exit immediately.  */
4817   check_output (outfile);
4818 
4819   if (mergeonly)
4820     {
4821       struct sortfile *sortfiles = xcalloc (nfiles, sizeof *sortfiles);
4822 
4823       for (size_t i = 0; i < nfiles; ++i)
4824         sortfiles[i].name = files[i];
4825 
4826       merge (sortfiles, 0, nfiles, outfile);
4827     }
4828   else
4829     {
4830       if (!nthreads)
4831         {
4832           unsigned long int np = num_processors (NPROC_CURRENT_OVERRIDABLE);
4833           nthreads = MIN (np, DEFAULT_MAX_THREADS);
4834         }
4835 
4836       /* Avoid integer overflow later.  */
4837       size_t nthreads_max = SIZE_MAX / (2 * sizeof (struct merge_node));
4838       nthreads = MIN (nthreads, nthreads_max);
4839 
4840       sort (files, nfiles, outfile, nthreads);
4841     }
4842 
4843   if (have_read_stdin && fclose (stdin) == EOF)
4844     sort_die (_("close failed"), "-");
4845 
4846   main_exit (EXIT_SUCCESS);
4847 }
4848