#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/ioctl.h>
#include "splice.h"
+#ifndef BLKGETSIZE64
+#define BLKGETSIZE64 _IOR(0x12,114,size_t)
+#endif
+
static int usage(char *name)
{
fprintf(stderr, "%s: infile | ...\n", name);
return 1;
}
-int main(int argc, char *argv[])
+static long long in_size(int fd)
{
+ unsigned long long bytes;
struct stat sb;
+
+ if (fstat(fd, &sb) < 0)
+ return error("fstat");
+
+ if (sb.st_size)
+ return sb.st_size;
+
+ if (ioctl(fd, BLKGETSIZE64, &bytes) < 0)
+ return error("BLKGETSIZE64");
+
+ return bytes;
+}
+
+int main(int argc, char *argv[])
+{
+ long long isize;
int fd;
if (argc < 2)
if (fd < 0)
return error("open input");
- if (fstat(fd, &sb) < 0)
- return error("stat input");
+ isize = in_size(fd);
+ if (isize < 0)
+ return isize;
- do {
- int ret = splice(fd, NULL, STDOUT_FILENO, NULL, sb.st_size, 0);
+ while (isize) {
+ int ret = splice(fd, NULL, STDOUT_FILENO, NULL, isize, 0);
if (ret < 0)
return error("splice");
else if (!ret)
break;
- sb.st_size -= ret;
- } while (1);
+ isize -= ret;
+ }
close(fd);
return 0;