Skip to content

Instantly share code, notes, and snippets.

@bfb
Last active August 29, 2015 14:08
Show Gist options
  • Save bfb/a192bc539fa1c4bf52e7 to your computer and use it in GitHub Desktop.
Save bfb/a192bc539fa1c4bf52e7 to your computer and use it in GitHub Desktop.
GzipCat in Ruby using pipes and FIFO
module GzipCat
class File
def initialize(file)
# puts "FILE => #{file}"
@filename = file
begin
@content = open(::File.expand_path(filename)).read
cat!
rescue Exception => e
# File not found and other errors are reported
puts e.message
end
end
attr_accessor :filename, :content
def cat!
# checks if the file is compressed
if ::File.extname(filename) == ".gz"
unzip!
else
puts content
end
end
def unzip!
# creates pipe descriptors
rd, wr = IO.pipe
if fork
# closes unused pipe side
rd.close
# sends file content into the pipe
wr.write content
wr.close
# waits for child process to respect files order
Process.wait
else
# closes unused pipe side
wr.close
# redirects $stdin to pipe descriptor - i.e. dup2 in clang
$stdin.reopen(rd)
# invokes gzip
exec("gzip -d")
end
end
end
class Server
def self.start(fifo_path)
puts "[#{Time.now}] GzipCat server connected into #{fifo_path} fifo"
# opens fifo on read mode
input = open(fifo_path, 'r')
# keeps the server alive
loop do
# puts "Wait"
# gets fifo content blocking if no content has been got
File.new(input.gets.chomp)
end
end
end
end
# run server
GzipCat::Server.start(ARGV.first)
# rd, wr = IO.pipe
# if fork
# wr.close
# $stdin.reopen(rd)
# exec("gzip -d")
# rd.close
# # wait
# else
# rd.close
# wr.write open("./test.txt.gz").read
# wr.close
# end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment