List of Input Files to Process
List of Input Files to Process

Allow the user to specify a number of files for processing.

Notes
There are really two interwined concerns here. First, there is the management of a list of filenames. Second, the filename "-" is treated as a synonym for stdin.

Declare have_read_stdin
Variable declaration
Notes
If standard input is read, then the file is not opened by name. Most of the time, files are opened and closed by name. This is part of a scheme that fakes out stdin handling so that it looks like a named file to the rest of sort.
Segment Source
 199: /* Nonzero if any of the input files are the standard input. */
 200: static int have_read_stdin;
 201: 

Minus indicates stdin
Segment Element
Code insertion

 340:   if (strcmp (file, "-") == 0)
 341:     {
 342:       fp = stdin;
 343:     }
 344:   else
 345:     {

Segment Element
Code insertion

 352:     }

Segment Element
Code insertion

 354:   if (fp == stdin)
 355:     have_read_stdin = 1;

Check each input file
Notes
The whole check routine is really just a wrapper where the Modes concern can control mulitple checkfp() calls.
Segment Element
Argument modification

1495: check (char **files, int nfiles)

Segment Element
Variable declaration

1497:   int i, disorders = 0;

Segment Element
Code insertion

1500:   for (i = 0; i < nfiles; ++i)
1501:     {
1502:       fp = xfopen (files[i], "r");

Segment Element
Code insertion

1508:     }

Sort and merge the list of input files
Notes
This part of SrcSpec has significant overlap with LargeFile support. They both use the merge() routine to generate the final results, though the each create intermediates for different reasons.
Segment Element
Parameter modification

1556: sort (char **files, int nfiles, FILE *ofp)

Segment Element
Variable declaration

1562:   FILE *fp, *tfp;

Segment Element
Variable declaration

1563:   struct tempnode *node;
1564:   int n_temp_files = 0;
1565:   char **tempfiles;
1566: 

Segment Element
Code insertion

1573:   while (nfiles--)
1574:     {
1575:       fp = xfopen (*files++, "r");

Segment Element
Code insertion

1591:               ++n_temp_files;
1592:               tfp = xtmpfopen (tempname ());

Segment Element
Argument modification

1598:                 write_bytes (lines.lines[i].text, lines.lines[i].length, tfp);
1599:                 putc (eolchar, tfp);

Segment Element
Code insertion

1601:           if (tfp != ofp)
1602:             xfclose (tfp);

Segment Element
Code insertion

1604:       xfclose (fp);
1605:     }
1606: 

Segment Element
Code insertion

1611:   if (n_temp_files)
1612:     {
1613:       tempfiles = (char **) xmalloc (n_temp_files * sizeof (char *));
1614:       i = n_temp_files;
1615:       for (node = temphead.next; i > 0; node = node->next)
1616:         tempfiles[--i] = node->name;
1617:       merge (tempfiles, n_temp_files, ofp);
1618:       free ((char *) tempfiles);
1619:     }

Define input list variables
Variable definition
Notes
The handling of the "minus" variable is a bit inconsistant. First, it is only a coincidence that the same symbol is used for both <stdin> and <stdout>. This works only because they never share the same role. (Note that there is no standard way to redirect to <stderr>). Also, OutSpec uses "minus" sometimes, and the literal dash ("-") at other times.
Segment Source
1721:   int checkonly = 0, mergeonly = 0, nfiles = 0;
1722:   char *minus = "-", *outfile = minus, **files, *tmp;

Initialize have_read_stdin
Code insertion
Segment Source
1735:   have_read_stdin = 0;

Allocate space for file list
Code insertion
Notes
This works only because the first argv entry is never an input file specification. Otherwise, at line 2021, there is a potential for under-allocated file list.
Segment Source
1776:   files = (char **) xmalloc (sizeof (char *) * argc);
1777: 

Build input file list
Code insertion
Segment Source
2019:       else                      /* Not an option. */
2020:         {
2021:           files[nfiles++] = argv[i];
2022:         }

Default to stdin
Code insertion

If no input is specified on the command line, cause stdin to be used as the input file.
Notes
This establishes a default for the input list.
Segment Source
2051:   if (nfiles == 0)
2052:     {
2053:       nfiles = 1;
2054:       files = −
2055:     }
2056: 

Check each input file
Argument modification
Segment Source
2061:       exit (check (files, nfiles) == 0 ? 0 : 1);

Sort each input file
Argument modification
Segment Source
2128:     sort (files, nfiles, ofp);

Close stdin if it was used.
Code insertion
Segment Source
2139:   if (have_read_stdin && fclose (stdin) == EOF)
2140:     error (SORT_FAILURE, errno, outfile);