From 9b577bdbb1571982f5b7216838cb41d64b5d983e Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Sat, 23 Jul 2016 23:50:28 -0400 Subject: [PATCH] builtin catenate (builtin so cr/lf conversion blocked) --- builtins.cpp | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++ builtins.h | 1 + command.cpp | 1 + 3 files changed, 56 insertions(+) diff --git a/builtins.cpp b/builtins.cpp index 639aaa2..babb912 100644 --- a/builtins.cpp +++ b/builtins.cpp @@ -19,6 +19,7 @@ //MAXPATHLEN #include +#include #include "version.h" @@ -820,6 +821,59 @@ int builtin_which(Environment &env, const std::vector &tokens, cons return 2; // not found. } +int cat_helper(int in, int out) { + static uint8_t buffer[4096]; + + for(;;) { + ssize_t rcount = read(in, buffer, sizeof(buffer)); + if (rcount < 0) { + if (errno == EINTR) continue; + return 2; + } + + if (rcount == 0) break; + + for (;;) { + ssize_t wcount = write(out, buffer, rcount); + if (wcount < 0) { + if (errno == EINTR) continue; + return 2; + } + if (wcount != rcount) return 2; + break; + } + } + return 0; +} + + +int builtin_catenate(Environment &env, const std::vector &tokens, const fdmask &fds) { + + if (tokens.size() == 1) { + int rv = cat_helper(stdin, stdout); + if (rv) fputs("### Catenate - I/O Error\n", stderr); + return rv; + } + + for (const auto &s : make_offset_range(tokens, 1)) { + + std::string path = ToolBox::MacToUnix(s); + int fd = open(path.c_str(), O_RDONLY); + if (fd < 0) { + fprintf(stderr, "### Catenate - Unable to open \"%s\".\n", path.c_str()); + return 1; + } + + int rv = cat_helper(fd, stdout); + close(fd); + if (rv) { + fputs("### Catenate - I/O Error\n", stderr); + return rv; + } + } + return 0; +} + int builtin_version(Environment &env, const std::vector &tokens, const fdmask &fds) { diff --git a/builtins.h b/builtins.h index c86ff11..302aefa 100644 --- a/builtins.h +++ b/builtins.h @@ -9,6 +9,7 @@ class fdmask; class token; int builtin_aboutbox(Environment &e, const std::vector &, const fdmask &); +int builtin_catenate(Environment &e, const std::vector &, const fdmask &); int builtin_directory(Environment &e, const std::vector &, const fdmask &); int builtin_echo(Environment &e, const std::vector &, const fdmask &); int builtin_exists(Environment &e, const std::vector &, const fdmask &); diff --git a/command.cpp b/command.cpp index ca16790..a500eb5 100644 --- a/command.cpp +++ b/command.cpp @@ -191,6 +191,7 @@ namespace { std::unordered_map &, const fdmask &)> builtins = { {"aboutbox", builtin_aboutbox}, {"alias", builtin_alias}, + {"catenate", builtin_catenate}, {"directory", builtin_directory}, {"echo", builtin_echo}, {"exists", builtin_exists},