So I have a program now that starts off tests on remote machines, and
is supposed to fork itself off, wait for the tests to finish, and
fetch their logfiles back to the server.
Here’s the bit of relevant code:
…
def closeFileHandles
if($opt_debug)
$stdin.close()
$stderr.reopen(’/tmp/stderr’, ‘a’)
$stdout = $stderr
else
$stdout.close(); $stderr.close(); $stdin.close()
end
end
def RunTest(test,run_id)
handle = startTest(@machine, test, run_id)
fork {
logfile = File.open(’/tmp/testout’, ‘a’)
logfile.sync = true
logfile.puts "about to close filehandles"
closeFileHandles()
logfile.puts "waiting for test to finish"
sleep 20 while ProcessRunning?(handle, run_id)
logfile.puts "go get logfiles"
getLogFiles(test, run_id)
logfile.close()
}
end
The problem is, if $opt_debug is not set, and $stdout, $stderr, and
$stdin are closed, then no data past “about to close filehandles” gets
written to /tmp/testout. Actually, something seems to crash the child
during or after closeFileHandles(), since I wrote this code to debug
why the logfiles weren’t getting copied back.
If I’m missing something, then please clue me in; I’ve been tearing my
hair out trying to fix this.
-=Eric
···
–
Come to think of it, there are already a million monkeys on a million
typewriters, and Usenet is NOTHING like Shakespeare.
– Blair Houghton
perhaps something in the parent is writing to stderr/out? i ask because this
works fine for me
def close
$stderr.close
$stdout.close
$stdin.close
end
def method
fork do
f = File.open ‘forkout’, ‘w’
f.puts Time.now
close
#$stdout.puts ‘foobar’
f.puts Time.now
f.close
end
end
method
Process.wait
unless i uncomment the line writing to $stdout, in which case i get the
behaviour you define too.
-a
···
On 14 Nov 2002, Eric Schwartz wrote:
So I have a program now that starts off tests on remote machines, and
is supposed to fork itself off, wait for the tests to finish, and
fetch their logfiles back to the server.
–
====================================
Ara Howard
NOAA Forecast Systems Laboratory
Information and Technology Services
Data Systems Group
R/FST 325 Broadway
Boulder, CO 80305-3328
Email: ahoward@fsl.noaa.gov
Phone: 303-497-7238
Fax: 303-497-7259
====================================
perhaps something in the parent is writing to stderr/out? i ask because this
works fine for me
Why shouldn’t the parent write to stderr/out? The child should
inherit its own copy of all open file descriptors (which at this point
is just stdin, stdout and stderr). Did you mean the child may be
writing?
/tmp/test.rb:8: closed stream (IOError)
from /tmp/test.rb:3:in ‘fork’
from /tmp/test.rb:3
This is what I don’t get: I closed $stdout on the line before. Why
does it appear to be writing to a closed stream on line 8? I get the
same result if I try to replace line 8 with
$stdout = $stderr
-=Eric
···
–
Come to think of it, there are already a million monkeys on a million
typewriters, and Usenet is NOTHING like Shakespeare.
– Blair Houghton
It want to flush $stdout, don’t make an assignement after the close
Why? $stdout.close should flush the filehandle. At least, in every
other programming language I’ve ever used, closing a filehandle
flushes its output. I cannot see any good reason why any filehandle,
once closed, should have any I/O associated with it.
I’m all for blaming myself before the language, but this seems very
clearly a bug to me. Am I just missing something?
-=Eric
···
–
Come to think of it, there are already a million monkeys on a million
typewriters, and Usenet is NOTHING like Shakespeare.
– Blair Houghton
i think this is because sync is false for stdout, stderr etc. eg. the close
is a request to close and flush, but the os may defer the flush. that is,
unless sync were true for all the closed handles…
It want to flush $stdout, don’t make an assignement after the close
Why? $stdout.close should flush the filehandle. At least, in every
other programming language I’ve ever used, closing a filehandle
flushes its output. I cannot see any good reason why any filehandle,
once closed, should have any I/O associated with it.
–
====================================
Ara Howard
NOAA Forecast Systems Laboratory
Information and Technology Services
Data Systems Group
R/FST 325 Broadway
Boulder, CO 80305-3328
Email: ahoward@fsl.noaa.gov
Phone: 303-497-7238
Fax: 303-497-7259
====================================
Why? $stdout.close should flush the filehandle. At least, in every
other programming language I’ve ever used, closing a filehandle
flushes its output. I cannot see any good reason why any filehandle,
once closed, should have any I/O associated with it.
i think this is because sync is false for stdout, stderr etc. eg. the close
is a request to close and flush, but the os may defer the flush. that is,
unless sync were true for all the closed handles…
Yes, but the point is that close() should flush the filehandle from
Ruby’s perspective. If the OS wants to delay its flush, that’s fine,
it’s allowed, but Ruby should not be trying to do a flush (or, indeed, any I/O on any filehandle, be it $stdout or $myfilehandle) after
calling close() on it.
I’ve filed a bug on ruby-lang.org about this, hopefully someone can
take a look at it. In the meantime, I’ve managed to work around it.
-=Eric
···
On 15 Nov 2002, Eric Schwartz wrote:
–
Come to think of it, there are already a million monkeys on a million
typewriters, and Usenet is NOTHING like Shakespeare.
– Blair Houghton