what is a portable way in Ruby to check where STDIN will block if you attempt to read from it? -


i find out if there portable way check in ruby script whether block if attempts read stdin. following approach works unix (and cygwin) not native win32. (it based on perl approach learned long ago.)


$ cat read-stdin.rb

#! /usr/bin/ruby # test of reading stdin  require 'fcntl'  # trace info on input objects $stdout.sync=true if $debug         # make sure standard output , error synchronized $stderr.print "argv=#{argv}\n" if $debug $stderr.print "argf=#{argf}\n" if $debug  # see if input available, showing usage statement if not blocking_stdin = false if (defined? fcntl::f_getfl)   $stderr.print "f_getfl=#{fcntl::f_getfl} o_rdwr=#{fcntl::o_rdwr}\n" if $debug   flags = stdin.fcntl(fcntl::f_getfl, 0)    $stderr.print "flags=#{flags}\n" if $debug   blocking_stdin = true if ((flags & fcntl::o_rdwr) == fcntl::o_rdwr)   $stderr.print "blocking_stdin=#{blocking_stdin}\n" if $debug end if (blocking_stdin && (argv.length == 0))   $stderr.print "usage: #{$0} [-]\n"   process.exit end  # read input , output $stderr.print "input:\n" if $debug input_text = argf.read() $stderr.print "output:\n" if $debug print "#{input_text}\n" 

here interaction without debugging:

$ grep -v debug read-stdin.rb >| /tmp/simple-read-stdin.rb  $ echo hey | ruby /tmp/simple-read-stdin.rb hey  $ ruby /tmp/simple-read-stdin.rb usage: /tmp/simple-read-stdin.rb [-] 

here interaction debugging:

$ echo hey | ruby -d read-stdin.rb argv= argf=argf f_getfl=3 o_rdwr=2 flags=65536 blocking_stdin=false input: output: hey  $ ruby -d read-stdin.rb argv= argf=argf f_getfl=3 o_rdwr=2 flags=98306 blocking_stdin=true usage: read-stdin.rb [-] 

i don't know if universally portable , don't know if considered idea (blocking isn't such bad concept) there non-blocking read method in io. can use this:

chunk = nil  begin   chunk = stdin.read_nonblock(4096) rescue errno::eagain   # handle case if block   chunk = 'nothing there...' end 

though, think it's quite disappointing doesn't work without specifying buffer size io#read it, working around using loop should quite easy.


Comments

Popular posts from this blog

jasper reports - Fixed header in Excel using JasperReports -

media player - Android: mediaplayer went away with unhandled events -

python - ('The SQL contains 0 parameter markers, but 50 parameters were supplied', 'HY000') or TypeError: 'tuple' object is not callable -