static off_t
input_file_size (int fd, struct stat const *st, char *buf, size_t bufsize)
{
+ off_t cur = lseek (fd, 0, SEEK_CUR);
+ if (cur < 0)
+ {
+ if (errno == ESPIPE)
+ errno = 0; /* Suppress confusing seek error. */
+ return -1;
+ }
+
off_t size = 0;
do
{
}
while (size < bufsize);
- /* The file contains at least BUFSIZE bytes. Infer its size via
- st->st_size if this seems reliable, or via lseek if not. */
- off_t cur = lseek (fd, 0, SEEK_CUR);
- off_t end;
- if (cur < 0)
- return -1;
- if (cur < size)
+ /* Note we check st_size _after_ the read() above
+ because /proc files on GNU/Linux are seekable
+ but have st_size == 0. */
+ if (st->st_size == 0)
{
- /* E.g., /dev/zero on GNU/Linux, where CUR is zero and SIZE == BUFSIZE.
- Assume there is no limit to the file size. */
+ /* We've filled the buffer, from a seekable file,
+ which has an st_size==0, E.g., /dev/zero on GNU/Linux.
+ Assume there is no limit to file size. */
errno = EOVERFLOW;
return -1;
}
+
+ cur += size;
+ off_t end;
if (usable_st_size (st) && cur <= st->st_size)
end = st->st_size;
else
quotef (files[i_file].of_name));
}
- wrote = true;
+ if (! ignorable (errno))
+ wrote = true;
if (file_limit)
{
char *buf = ptr_align (b, page_size);
size_t initial_read = SIZE_MAX;
- if ((split_type == type_chunk_bytes || split_type == type_chunk_lines)
- && n_units != 1)
+ if (split_type == type_chunk_bytes || split_type == type_chunk_lines)
{
file_size = input_file_size (STDIN_FILENO, &in_stat_buf,
buf, in_blk_size);
. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
print_ver_ split
+require_sparse_support_ # for 'truncate --size=$OFF_T_MAX'
+eval $(getlimits) # for OFF_T limits
xz --version || skip_ "xz (better than gzip/bzip2) required"
for total_n_lines in 5 3000 20000; do
# split does not run the command (and effectively elides the file)
# only when the output to that command would have been empty.
split -e -n 10 --filter='xz > $FILE.xz' /dev/null || fail=1
-stat x?? 2>/dev/null && fail=1
+returns_ 1 stat x?? 2>/dev/null || fail=1
# Ensure this invalid combination is flagged
returns_ 1 split -n 1/2 --filter='true' /dev/null 2>&1 || fail=1
# where they would result in a non zero exit from split.
yes | head -n200K | split -b1G --filter='head -c1 >/dev/null' || fail=1
-# Ensure that endless input is ignored when all filters finish
-timeout 10 yes | split --filter="head -c1 >/dev/null" -n r/1 || fail=1
-timeout 10 split --filter="head -c1 >/dev/null" -n 1 /dev/zero || fail=1
+# Ensure that "endless" input is ignored when all filters finish
+timeout 10 sh -c 'yes | split --filter="head -c1 >/dev/null" -n r/1' || fail=1
+if truncate -s$OFF_T_MAX zero.in; then
+ timeout 10 sh -c 'split --filter="head -c1 >/dev/null" -n 1 zero.in' || fail=1
+fi
Exit $fail
# invalid number of chunks
echo "split: invalid number of chunks: '1o'" > exp
-split -n l/1o 2>err && fail=1
+returns_ 1 split -n l/1o 2>err || fail=1
compare exp err || fail=1
-echo > exp
-echo | split -n l/1 || fail=1
-compare exp xaa || fail=1
+echo "split: -: cannot determine file size" > exp
+: | returns_ 1 split -n l/1 2>err || fail=1
+compare exp err || fail=1
# N can be greater than the file size
# in which case no data is extracted, or empty files are written
# Ensure --elide-empty-files is honored
split -e -n l/10 /dev/null || fail=1
-stat x?? 2>/dev/null && fail=1
+returns_ 1 stat x?? 2>/dev/null || fail=1
# 80 bytes. ~ transformed to \n below
lines=\
if test -z "$ELIDE_EMPTY"; then
split ---io-blksize=$IO_BLKSIZE -n l/2/$N in > chunk.k
- stat x* 2>/dev/null && fail=1
+ returns_ 1 stat x* 2>/dev/null || fail=1
fi
split ---io-blksize=$IO_BLKSIZE $ELIDE_EMPTY -n l/$N in