#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#define READBUFSIZE 128
#define STDOUT 1
int main(int argc, char **argv) {
  int fd;
  char readbuf[READBUFSIZE];
  size_t readlen;

  // Take the filename from command line argument
  if (argc != 2) {
    fprintf(stderr, "usage: ./fread_example filename\n");
    return EXIT_FAILURE;  // defined in stdlib.h
  }

  // Open, read, and print the file
  fd = open(argv[1], O_RDONLY);  // "man fopen" says the binary flag to fopen is ignored
  if (fd == -1) {
    fprintf(stderr, "%s -- ", argv[1]);
    perror("open failed");
    return EXIT_FAILURE;
  }

  // Read from the file, write to stdout.
  // read() only returns 0 for EOF
  while ((readlen = read(fd, readbuf, READBUFSIZE)) != 0) {
    if (readlen == -1 && errno == EINTR) {
	// benign interruption
	continue;
    } else if (readlen == -1) {
	// A real error
	perror("Error reading from file\n");
	return EXIT_FAILURE;
    }
    size_t written = 0;
    size_t writelen = 0;
    while (written < readlen) {
      writelen = write(STDOUT, readbuf + written, readlen - written);
      if (writelen == -1 && errno == EINTR) {
	// benign interruption
	continue;
      } else if (writelen == -1) {
	// A real error
	perror("Error writing to stdout\n");
	return EXIT_FAILURE;
      }
      written += writelen;
    }
  }

  close(fd);

  return EXIT_SUCCESS;  // defined in stdlib.h
}