From 6986963b4bd8a03263e3631c2b4e58a3877ead20 Mon Sep 17 00:00:00 2001 From: Jonas 'Sortie' Termansen Date: Tue, 22 Nov 2011 17:57:10 +0100 Subject: [PATCH] cp(1) can now support the syntax cp /bin/snake / --- utils/cp.cpp | 39 +++++++++++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 6 deletions(-) diff --git a/utils/cp.cpp b/utils/cp.cpp index 3a8db821..974235ca 100644 --- a/utils/cp.cpp +++ b/utils/cp.cpp @@ -18,23 +18,50 @@ bool writeall(int fd, const void* buffer, size_t len) return true; } +const char* basename(const char* path) +{ + size_t len = strlen(path); + while ( len-- ) { if ( path[len] == '/' ) { return path + len + 1; } } + return path; +} + int main(int argc, char* argv[]) { if ( argc != 3 ) { printf("usage: %s \n", argv[0]); return 0; } - int fromfd = open(argv[1], O_RDONLY); - if ( fromfd < 0 ) { printf("%s: %s: %s\n", argv[0], argv[1], strerror(errno)); return 1; } + const char* frompath = argv[1]; + const char* topath = argv[2]; + char tobuffer[256]; - int tofd = open(argv[2], O_WRONLY | O_TRUNC | O_CREAT, 0777); - if ( tofd < 0 ) { printf("%s: %s: %s\n", argv[0], argv[2], strerror(errno)); return 1; } + int fromfd = open(frompath, O_RDONLY); + if ( fromfd < 0 ) { printf("%s: %s: %s\n", argv[0], frompath, strerror(errno)); return 1; } + + int tofd = open(topath, O_WRONLY | O_TRUNC | O_CREAT, 0777); + if ( tofd < 0 ) + { + if ( errno == EISDIR ) + { + strcpy(tobuffer, topath); + if ( tobuffer[strlen(tobuffer)-1] != '/' ) { strcat(tobuffer, "/"); } + strcat(tobuffer, basename(frompath)); + topath = tobuffer; + tofd = open(topath, O_WRONLY | O_TRUNC | O_CREAT, 0777); + } + + if ( tofd < 0 ) + { + printf("%s: %s: %s\n", argv[0], topath, strerror(errno)); + return 1; + } + } while ( true ) { const size_t BUFFER_SIZE = 4096; char buffer[BUFFER_SIZE]; ssize_t bytesread = read(fromfd, buffer, BUFFER_SIZE); - if ( bytesread < 0 ) { printf("%s: %s: %s\n", argv[0], argv[1], strerror(errno)); return 1; } + if ( bytesread < 0 ) { printf("%s: %s: %s\n", argv[0], frompath, strerror(errno)); return 1; } if ( bytesread == 0 ) { return 0; } - if ( !writeall(tofd, buffer, bytesread) ) { printf("%s: %s: %s\n", argv[0], argv[2], strerror(errno)); return 1; } + if ( !writeall(tofd, buffer, bytesread) ) { printf("%s: %s: %s\n", argv[0], topath, strerror(errno)); return 1; } } }