Last active
August 29, 2015 14:06
-
-
Save thinkerbot/5dc190f2c2145c29b086 to your computer and use it in GitHub Desktop.
Hold open a fifo from both ends, allowing input from external processes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
begin | |
require 'optparse' | |
options = { | |
:direction => "in" | |
} | |
OptionParser.new do |opts| | |
opts.banner = %{ | |
usage: pipe-exec [options] FIFO_FILE COMMAND.... | |
Executes the command with stdin reading from the fifo and FD 3 holding open | |
the fifo on the write side. As a result other processes can write to the | |
fifo, and thereby to the command, without the fifo closing. It's a | |
persistent pipe. | |
Use the --direction option to do the same but flipping stdin with stdout. | |
options: | |
}.lstrip | |
opts.on("-d", "--direction IN_OR_OUT", "the direction of the pipe (#{options[:direction]})") do |value| | |
options[:direction] = value | |
end | |
opts.on("-h", "--help", "print this help") do | |
puts opts | |
exit | |
end | |
end.parse! | |
case ARGV.length | |
when 0 | |
$stderr.puts "no fifo specified" | |
exit | |
when 1 | |
$stderr.puts "no command specified" | |
exit | |
end | |
fifo = ARGV.shift | |
# The trick here is using NONBLOCK and opening the fifo for read first such | |
# that the process will not deadlock with a fifo open for write, waiting for | |
# the reader that will never open. | |
# | |
# See http://man7.org/linux/man-pages/man7/fifo.7.html | |
# Or better 'The Linux Programming Interface' p917 | |
case options[:direction].downcase | |
when "in" then exec(*ARGV, 0 => [fifo, File::RDONLY | File::NONBLOCK], 3 => [fifo, File::WRONLY]) | |
when "out" then exec(*ARGV, 3 => [fifo, File::RDONLY | File::NONBLOCK], 1 => [fifo, File::WRONLY]) | |
else raise "invalid direction: #{options[:direction]} (should be 'in' or 'out')" | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment