Snuggledash icon

bigfilewrite.c

Snuggledash | PRO | 04/28/21 10:00:53 AM UTC | 0 ⭐ | 1111 👁️ | Never ⏰ | []
C |

1.66 KB

|

None

|

0 👍

/

0 👎

#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