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