#include <sys/mman.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/uio.h>
#include <limits.h>
// test file with INT_MAX+2 bytes, I used this command to create one:
// % truncate -s 2147483649 garbage.bin # sparse
// % (openssl rand 2147483647; echo .) > garbage.bin # filled with randomness
#define INFILE "./garbage.bin"
//#define WRITESIZE 65536
// size limit for FreeBSD
#define WRITESIZE INT_MAX
//#define WRITESIZE ((size_t)INT_MAX+1)
#define MAPSIZE WRITESIZE
//#define MAPSIZE ((size_t)INT_MAX+4097)
#define FAIL ret = 1; goto fail
static void printerr(const char *what) {
fprintf(stderr, "%s: %s\n", what, strerror(errno));
}
int main(void) {
void *ptr = NULL;
int ret = 0;
int ifd = -1, ofd = -1;
ssize_t res;
struct iovec lonevec[1];
ifd = open(INFILE, O_RDONLY);
if (ifd == -1) {
printerr("open (in)");
FAIL;
}
ptr = mmap(NULL, MAPSIZE, PROT_READ, MAP_PRIVATE, ifd, 0);
if (ptr == MAP_FAILED) {
printerr("mmap");
FAIL;
}
ofd = open("/dev/null", O_WRONLY);
if (ofd == -1) {
printerr("open (out)");
FAIL;
}
res = write(ofd, ptr, WRITESIZE);
if (res == -1) {
printerr("write");
ret = 1;
} else {
printf("write: %ld\n", res);
}
lonevec[0].iov_base = ptr;
lonevec[0].iov_len = WRITESIZE;
res = writev(ofd, lonevec, 1);
if (res == -1) {
printerr("writev");
ret = 1;
} else {
printf("writev: %ld\n", res);
ret = 1;
}
fail:
if (ofd >= 0) {
close(ofd);
ofd = -1;
}
if (ptr) {
munmap(ptr, MAPSIZE);
ptr = NULL;
}
if (ifd >= 0) {
close(ifd);
ifd = -1;
}
return ret;
}
Comments