From: Brian Candler Date: 2003-07-28T08:27:11+09:00 Subject: 1.8.0, fcgi and $stdout/$stderr --gBBFr7Ir9EOA20Yy Content-Type: text/plain; charset=us-ascii Content-Disposition: inline I have just been trying to get fcgi to run under 1.8.0, and I have found a problem: /usr/local/lib/ruby/site_ruby/1.8/fcgi.rb:476: warning: assignment to $stdout is deprecated; use STDOUT.reopen() instead /usr/local/lib/ruby/site_ruby/1.8/fcgi.rb:476:in `each_cgi': $stdout is a read-only variable (NameError) from /usr/local/lib/ruby/site_ruby/1.8/fcgi.rb:473:in `each' from /usr/local/lib/ruby/site_ruby/1.8/fcgi.rb:473:in `each_cgi' (One problem is that Ruby gives both a warning and an error; either assignment should be allowed with a warning, or disallowed, not both :-) This is caused by the following code: $stdout, $defout, $stderr = request.out, request.out, request.err Now, 'request.out' and 'request.err' are objects which respond to IO-like calls, but are not actually IO objects (following the Ruby principle of Duck Typing). However, I now can't change $stdout/$stderr, and nor can I reopen them since the new objects are not IO: /usr/local/lib/ruby/site_ruby/1.8/fcgi.rb:475:in `reopen': cannot convert FCGI::Stream into IO (TypeError) I guess this makes sense, since $stdout/$stderr are supposed to refer to the actual system standard input/standard output channels attached to the process. So it looks like the best I can do now is: $defout, $deferr = request.out, request.err although in that case, any existing programs which do $stderr.puts "Some warning message" are now going to send to the system stderr rather than the fastcgi "stderr". Anyway, I think the attached patch does the job for ruby-fcgi, although I've not actually tested it under 1.6.8 Cheers, Brian. --gBBFr7Ir9EOA20Yy Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=ruby-fcgi-180patch --- ruby-fcgi-0.8.3/README.orig Mon Jul 28 00:09:32 2003 +++ ruby-fcgi-0.8.3/README Mon Jul 28 00:09:40 2003 @@ -14,7 +14,7 @@ $ ruby install.rb config (Pure Ruby Version: ruby install.rb config --without-ext) - (Some systems need: ruby install.rb config --with-fcgi-include=/usr/local/include --with-fcgi-lib=/usr/local/lib) + (Some systems need: ruby install.rb config -- --with-fcgi-include=/usr/local/include --with-fcgi-lib=/usr/local/lib) $ ruby install.rb setup # ruby install.rb install --- ruby-fcgi-0.8.3/lib/fcgi.rb.orig Mon Jul 28 00:09:48 2003 +++ ruby-fcgi-0.8.3/lib/fcgi.rb Mon Jul 28 00:21:33 2003 @@ -468,15 +468,20 @@ else exit_requested = false trap('SIGPIPE','IGNORE') - o_stdout, o_defout, o_stderr = $stdout, $defout, $stderr + rb16 = RUBY_VERSION < "1.8.0" + $deferr ||= $stderr if rb16 + o_defout, o_deferr = $defout, $deferr + o_stdout, o_stderr = $stdout, $stderr if rb16 FCGI::each {|request| trap('SIGUSR1') { exit_requested = true } - $stdout, $defout, $stderr = request.out, request.out, request.err + $defout, $deferr = request.out, request.err + $stdout, $stderr = request.out, request.err if rb16 yield CGI.new(request, *args) - $stdout, $defout, $stderr = o_stdout, o_defout, o_stderr + $defout, $deferr = o_defout, o_deferr + $stdout, $stderr = o_stdout, o_stderr if rb16 request.finish trap('SIGUSR1','DEFAULT') raise SignalException, 'SIGUSR1' if exit_requested --gBBFr7Ir9EOA20Yy--