I want to learn to implement the function like cat, which just take input from a file and print to stdout.
But I am not sure the line of write()
is robust in all cases as it may write less than n
. But I am not able to create a test case to make this case happen. How to make a test case so that it can result in less than n char be written? Also, how to modify the code accordingly to make the program robust (for this case, but also for other cases that I have not described)?
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
int main(int argc, char *argv[]) {
const char *pathname = argv[1];
int fd;
if((fd = open(pathname, O_RDONLY)) == -1) {
perror("open");
return 1;
}
#define BUF_SIZE 1024
char buf[BUF_SIZE];
ssize_t n;
while((n = read(fd, &buf, BUF_SIZE)) > 0) {
if(write(STDOUT_FILENO, &buf, n) == -1) {
perror("write");
return 1;
}
}
if(n == -1) {
perror("read");
return 1;
}
if(close(fd) == -1) {
perror("close");
return 1;
}
return 0;
}
EDIT: I fixed the write()
bug in the previous code based on the pipe-blocking test case mentioned by Armali. Can anybody check whether there are any other bugs?
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
int main(int argc, char *argv[]) {
const char *pathname = argv[1];
int fd;
if((fd = open(pathname, O_RDONLY)) == -1) {
perror("open");
return 1;
}
#define BUF_SIZE 2*65536
char buf[BUF_SIZE];
ssize_t r_n;
while((r_n = read(fd, &buf, BUF_SIZE)) > 0) {
ssize_t w_n;
int i = 0;
while((w_n = write(STDOUT_FILENO, buf+i, r_n)) < r_n) {
if(w_n == -1) {
perror("write");
return 1;
}
r_n -= w_n;
i += w_n;
}
}
if(r_n == -1) {
perror("read");
return 1;
}
if(close(fd) == -1) {
perror("close");
return 1;
}
return 0;
}