diff options
Diffstat (limited to 'src/split.c')
-rw-r--r-- | src/split.c | 44 |
1 files changed, 30 insertions, 14 deletions
diff --git a/src/split.c b/src/split.c index 53ee2719..e5e75f0f 100644 --- a/src/split.c +++ b/src/split.c @@ -1,5 +1,5 @@ /* split.c -- split a file into pieces. - Copyright (C) 1988-2012 Free Software Foundation, Inc. + Copyright (C) 1988-2013 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -92,6 +92,9 @@ static char const *additional_suffix; /* Name of input file. May be "-". */ static char *infile; +/* stat buf for input file. */ +static struct stat in_stat_buf; + /* Descriptor on which output file is open. */ static int output_desc = -1; @@ -206,11 +209,10 @@ Usage: %s [OPTION]... [INPUT [PREFIX]]\n\ Output fixed-size pieces of INPUT to PREFIXaa, PREFIXab, ...; default\n\ size is 1000 lines, and default PREFIX is 'x'. With no INPUT, or when INPUT\n\ is -, read standard input.\n\ -\n\ -"), stdout); - fputs (_("\ -Mandatory arguments to long options are mandatory for short options too.\n\ "), stdout); + + emit_mandatory_arg_note (); + fprintf (stdout, _("\ -a, --suffix-length=N generate suffixes of length N (default %d)\n\ --additional-suffix=SUFFIX append an additional SUFFIX to file names.\n\ @@ -362,8 +364,20 @@ create (const char *name) { if (verbose) fprintf (stdout, _("creating file %s\n"), quote (name)); - return open (name, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, - (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)); + + int fd = open (name, O_WRONLY | O_CREAT | O_BINARY, MODE_RW_UGO); + if (fd < 0) + return fd; + struct stat out_stat_buf; + if (fstat (fd, &out_stat_buf) != 0) + error (EXIT_FAILURE, errno, _("failed to stat %s"), quote (name)); + if (SAME_INODE (in_stat_buf, out_stat_buf)) + error (EXIT_FAILURE, 0, _("%s would overwrite input; aborting"), + quote (name)); + if (ftruncate (fd, 0) != 0) + error (EXIT_FAILURE, errno, _("%s: error truncating"), quote (name)); + + return fd; } else { @@ -1029,6 +1043,7 @@ no_filters: files[i_file].ofd = OFD_APPEND; } } + IF_LINT (free (files)); } #define FAIL_ONLY_ONE_WAY() \ @@ -1058,10 +1073,8 @@ parse_chunk (uintmax_t *k_units, uintmax_t *n_units, char *slash) int main (int argc, char **argv) { - struct stat stat_buf; enum Split_type split_type = type_undef; size_t in_blk_size = 0; /* optimal block size of input file device */ - char *buf; /* file i/o buffer */ size_t page_size = getpagesize (); uintmax_t k_units = 0; uintmax_t n_units; @@ -1335,16 +1348,16 @@ main (int argc, char **argv) /* Get the optimal block size of input device and make a buffer. */ - if (fstat (STDIN_FILENO, &stat_buf) != 0) + if (fstat (STDIN_FILENO, &in_stat_buf) != 0) error (EXIT_FAILURE, errno, "%s", infile); if (in_blk_size == 0) - in_blk_size = io_blksize (stat_buf); + in_blk_size = io_blksize (in_stat_buf); if (split_type == type_chunk_bytes || split_type == type_chunk_lines) { off_t input_offset = lseek (STDIN_FILENO, 0, SEEK_CUR); - if (usable_st_size (&stat_buf)) - file_size = stat_buf.st_size; + if (usable_st_size (&in_stat_buf)) + file_size = in_stat_buf.st_size; else if (0 <= input_offset) { file_size = lseek (STDIN_FILENO, 0, SEEK_END); @@ -1368,7 +1381,8 @@ main (int argc, char **argv) file_size = MAX (file_size, n_units); } - buf = ptr_align (xmalloc (in_blk_size + 1 + page_size - 1), page_size); + void *b = xmalloc (in_blk_size + 1 + page_size - 1); + char *buf = ptr_align (b, page_size); /* When filtering, closure of one pipe must not terminate the process, as there may still be other streams expecting input from us. */ @@ -1418,6 +1432,8 @@ main (int argc, char **argv) abort (); } + IF_LINT (free (b)); + if (close (STDIN_FILENO) != 0) error (EXIT_FAILURE, errno, "%s", infile); closeout (NULL, output_desc, filter_pid, outfile); |