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);