/* * 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 }