summaryrefslogtreecommitdiff
path: root/src/split.c
diff options
context:
space:
mode:
authorIgor Pashev <pashev.igor@gmail.com>2013-02-16 14:42:43 +0000
committerIgor Pashev <pashev.igor@gmail.com>2013-02-16 14:42:43 +0000
commit7548e75065063dae256d94e6c7f4f9f43bd7f210 (patch)
treef23b000f8822f6eb70249c1106a3275deaa03bac /src/split.c
parentddefcddae2e97579f82320f4fd70d0ba14a52392 (diff)
parent974ab3dd887985e3aa347f3c6521f819296396a0 (diff)
downloadcoreutils-7548e75065063dae256d94e6c7f4f9f43bd7f210.tar.gz
Merge tag 'upstream/8.21'
Upstream version 8.21
Diffstat (limited to 'src/split.c')
-rw-r--r--src/split.c44
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);