diff --git a/examples/cat.lua b/examples/cat.lua new file mode 100644 index 0000000..b7a03c7 --- /dev/null +++ b/examples/cat.lua @@ -0,0 +1,78 @@ +#!/bin/env lua +-- Trimmed down cat(1) utility. +-- +-- Concatenate files to stdout, making sure bytes are actually written +-- out successfully. +-- +-- SYNOPSIS: +-- cat.lua [-u] +-- +-- NOTE: utility doesn't explicitly allow to concatenate stdin. +local osx = require 'osx' +local io = require 'io' + +local uflag = false + +local function cat(path) + local ferr = io.stderr + + local f, err = io.open(path, 'r') + if err then + ferr:write(err, "\n") + return false + end + + local success = true -- unless it happens to be a failure + local fout = io.stdout + + while true do + local buf, err = f:read(4096) + if err then + ferr:write(err, "\n") + success = false + end + if not buf then + break -- done with file + end + assert(fout:write(buf)) + end + f:close() + + assert(fout:flush()) + if not osx.isatty(fout) then + assert(osx.commit(fout)) + end + return success +end + +local function parseargs(...) + local files = {} + for i = 1, select('#', ...) do + local arg = select(i, ...) + if arg == '-u' then + uflag = true + else + files[#files+1] = arg + end + end + if #files == 0 then + error("Missing file arguments") + end + return files +end + +local files = parseargs(...) + +io.stdout:setvbuf(uflag and 'no' or 'full') + +local success = true +for _, path in ipairs(files) do + if not cat(path) then + success = false + end +end + +if not success then + os.exit(1) +end +