Output File Specification
Output File Specification

Allow the user to name a destination file.


Insert user message text
Text insertion
Segment Source
 231:   -o FILE          write result on FILE instead of standard output\n\

Declare output specification variables (minus, outfile, ofp)
Segment Element
Constant definition

1722:   char *minus = "-", *outfile = minus, **files, *tmp;

Segment Element
Variable definition

1722:   char *minus = "-", *outfile = minus, **files, *tmp;

Segment Element
Variable declaration

1723:   FILE *ofp;

Parse OutSpec option (-o)
Code insertion
Segment Source
1960:                   case 'o':
1961:                     if (s[1])
1962:                       outfile = s + 1;
1963:                     else
1964:                       {
1965:                         if (i == argc - 1)
1966:                           error (SORT_FAILURE, 0,
1967:                                  _("option `-o' requires an argument"));
1968:                         else
1969:                           outfile = argv[++i];
1970:                       }
1971:                     goto outer;

Protect against overwriting the output
Code insertion

If the command line specified an output file, use that as the destination. Otherwise, write the sorted results to .
Notes
The case for a specified outfile is later extended to protect against accidental user overwrites.
Segment Source
2064:   if (strcmp (outfile, "-"))
2065:     {
2066:       struct stat outstat;
2067:       if (stat (outfile, &outstat) == 0)
2068:         {
2069:           /* The following code prevents a race condition when
2070:              people use the brain dead shell programming idiom:
2071:                   cat file | sort -o file
2072:              This feature is provided for historical compatibility,
2073:              but we strongly discourage ever relying on this in
2074:              new shell programs. */
2075: 
2076:           /* Temporarily copy each input file that might be another name
2077:              for the output file.  When in doubt (e.g. a pipe), copy.  */
2078:           for (i = 0; i < nfiles; ++i)
2079:             {
2080:               char buf[8192];
2081:               FILE *fp;
2082:               int cc;
2083: 
2084:               if (S_ISREG (outstat.st_mode) && strcmp (outfile, files[i]))
2085:                 {
2086:                   struct stat instat;
2087:                   if ((strcmp (files[i], "-")
2088:                        ? stat (files[i], &instat)
2089:                        : fstat (STDIN_FILENO, &instat)) != 0)
2090:                     {
2091:                       error (0, errno, "%s", files[i]);
2092:                       cleanup ();
2093:                       exit (SORT_FAILURE);
2094:                     }
2095:                   if (S_ISREG (instat.st_mode)
2096:                       && (instat.st_ino != outstat.st_ino
2097:                           || instat.st_dev != outstat.st_dev))
2098:                     {
2099:                       /* We know the files are distinct.  */
2100:                       continue;
2101:                     }
2102:                 }
2103: 
2104:               fp = xfopen (files[i], "r");
2105:               tmp = tempname ();
2106:               ofp = xtmpfopen (tmp);
2107:               while ((cc = fread (buf, 1, sizeof buf, fp)) > 0)
2108:                 write_bytes (buf, cc, ofp);
2109:               if (ferror (fp))
2110:                 {
2111:                   error (0, errno, "%s", files[i]);
2112:                   cleanup ();
2113:                   exit (SORT_FAILURE);
2114:                 }
2115:               xfclose (ofp);
2116:               xfclose (fp);
2117:               files[i] = tmp;
2118:             }
2119:         }
2120:       ofp = xfopen (outfile, "w");
2121:     }
2122:   else
2123:     ofp = stdout;

Add output file to merge
Argument insertion
Segment Source
2126:     merge (files, nfiles, ofp);

Add output file to sort
Argument insertion
Segment Source
2128:     sort (files, nfiles, ofp);

Report errors with file name
Segment Element
Argument modification

2137:     error (SORT_FAILURE, errno, _("%s: write error"), outfile);

Segment Element
Argument modification

2140:     error (SORT_FAILURE, errno, outfile);

Segment Element
Argument modification

2142:     error (SORT_FAILURE, errno, _("%s: write error"), outfile);