/*
* Copyright ©2026 Soham Pardeshi. All rights reserved.
* Permission is hereby granted to students registered for University of
* Washington CSE 333 for use solely during Summer Quarter 2026 for
* purposes of the course. No other use, copying, distribution, or
* modification is permitted without prior written consent. Copyrights
* for third-party components of this work must be honored. Instructors
* interested in reusing these course materials should contact the author.
*/
#include <errno.h> // errno, EINTR
#include <fcntl.h> // open, O_RDONLY
#include <stdio.h> // printf, fprintf, perror
#include <stdlib.h> // EXIT_FAILURE, EXIT_SUCCESS
#include <unistd.h> // read, close
// ReadAll: read exactly n bytes from fd into buf.
//
// A single read() can come up short (especially on pipes and sockets),
// so we loop, advancing by however many bytes actually landed, and retry
// when the call is interrupted (EINTR). Returns the number of bytes read
// (n on success; fewer only if we hit EOF or a real error).
int ReadAll(int fd, char* buf, int n) {
int bytes_left = n;
int result;
while (bytes_left > 0) {
result = read(fd, buf + (n - bytes_left), bytes_left);
if (result == -1) {
if (errno != EINTR) {
break; // a real error
}
continue; // EINTR: just retry
} else if (result == 0) {
break; // EOF: nothing left to read
}
bytes_left -= result;
}
return n - bytes_left;
}
int main(int argc, char** argv) {
if (argc != 2) {
fprintf(stderr, "usage: ./readN <file>\n");
return EXIT_FAILURE;
}
int fd = open(argv[1], O_RDONLY);
if (fd == -1) {
perror("open");
return EXIT_FAILURE;
}
char buf[16];
int got = ReadAll(fd, buf, sizeof(buf));
printf("read %d bytes\n", got);
close(fd);
return EXIT_SUCCESS;
}