/*
* Copyright 2011 Steven Gribble
*
* This file is part of the UW CSE 333 course project sequence
* (333proj).
*
* 333proj is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* 333proj is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with 333proj. If not, see .
*/
#include
#include
#include
#include
#include
#include
#include
#define READBUFSIZE 128
int main(int argc, char **argv) {
int fd_in, fd_out;
char readbuf[READBUFSIZE];
ssize_t readlen, writelen, written;
// Take the filenames from command line arguments
if (argc != 3) {
fprintf(stderr, "usage: ./cp_example infile outfile\n");
return EXIT_FAILURE; // defined in stdlib.h
}
// Open the input file
while (1) {
fd_in = open(argv[1], O_RDONLY);
if (fd_in == -1) {
if ((errno == EINTR) || (errno == EWOULDBLOCK)) {
// Try again.
continue;
}
// Fail.
fprintf(stderr, "Couldn't open %s for reading: ", argv[1]);
perror(NULL);
exit(EXIT_FAILURE);
}
// The open succeeded, so break out of the loop.
break;
}
// Open the output file
while (1) {
fd_out = open(argv[2],
O_WRONLY | O_TRUNC | O_CREAT,
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if (fd_out == -1) {
if ((errno == EINTR) || (errno == EWOULDBLOCK)) {
// Try again.
continue;
}
// Fail.
fprintf(stderr, "Couldn't open %s for writing: ", argv[2]);
perror(NULL);
exit(EXIT_FAILURE);
}
// The open succeeded, so break out of the loop.
break;
}
// Do the copy.
while (1) {
// Try to read READBUFSIZE bytes from the input file.
readlen = read(fd_in,
(void *) readbuf,
(size_t) READBUFSIZE);
if (readlen == 0) {
// we hit the end of file
break;
} else if (readlen == -1) {
if ((errno == EINTR) ||
(errno == EWOULDBLOCK) ||
(errno == EAGAIN))
continue;
perror("read failed");
exit(EXIT_FAILURE);
}
// Try to write readlen bytes to the output file.
written = 0;
while(readlen > 0) {
writelen = write(fd_out,
(void *) (readbuf + written),
(size_t) readlen);
if (writelen == -1) {
if ((errno == EINTR) ||
(errno == EWOULDBLOCK) ||
(errno == EAGAIN))
continue;
perror("write failed");
exit(EXIT_FAILURE);
}
written += writelen;
readlen -= writelen;
}
}
// Done!
close(fd_in);
close(fd_out);
return EXIT_SUCCESS; // defined in stdlib.h
}