[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Net::HTTP Closes STDIN

James Gray

1/28/2007 1:13:00 AM

Kenneth Kalmer has brought up a HighLine issue and I'm trying to look
into it. Oddly, it seems to happen when interacting with the
Net::HTTP library. I've narrowed it done to the following example on
my box:

$ cat stdin_closed_issue.rb
require 'net/http'
require 'io/wait'

Net::HTTP.start('www.ruby-lang.org', 80) do |http|
body = http.get('/en/license.txt').body
end
p $stdin.eof?
$ ruby stdin_closed_issue.rb
true

Can anyone explain why $stdin is closed after the page read?

James Edward Gray II


29 Answers

Eric Hodel

1/28/2007 1:40:00 AM

0

On Jan 27, 2007, at 17:13, James Edward Gray II wrote:
> Kenneth Kalmer has brought up a HighLine issue and I'm trying to
> look into it. Oddly, it seems to happen when interacting with the
> Net::HTTP library. I've narrowed it done to the following example
> on my box:
>
> $ cat stdin_closed_issue.rb
> require 'net/http'
> require 'io/wait'
>
> Net::HTTP.start('www.ruby-lang.org', 80) do |http|
> body = http.get('/en/license.txt').body
> end
> p $stdin.eof?
> $ ruby stdin_closed_issue.rb
> true
>
> Can anyone explain why $stdin is closed after the page read?

$stdin isn't closed, its at the end of file. Use #closed? to test if
an IO has been closed or not.

$ cat test.rb
require 'net/http'
require 'io/wait'

Net::HTTP.start('www.ruby-lang.org', 80) do |http|
body = http.get('/en/license.txt').body
end
p $stdin.closed?
p $stdin.eof?

$ ruby test.rb
false # hit ^D to close $stdin on the sending side.
true
$
$ echo hi | ruby test.rb
false
false


--
Eric Hodel - drbrain@segment7.net - http://blog.se...

I LIT YOUR GEM ON FIRE!


James Gray

1/28/2007 2:38:00 AM

0

On Jan 27, 2007, at 7:39 PM, Eric Hodel wrote:

> $stdin isn't closed, its at the end of file. Use #closed? to test
> if an IO has been closed or not.

Right, good point.

However, when I call eof?() before the Net::HTTP call it behaves
differently (stalls and prints false). Why does it not behave the
same after that page read?

James Edward Gray II

Eric Hodel

1/28/2007 2:49:00 AM

0

On Jan 27, 2007, at 18:38, James Edward Gray II wrote:
> On Jan 27, 2007, at 7:39 PM, Eric Hodel wrote:
>
>> $stdin isn't closed, its at the end of file. Use #closed? to test
>> if an IO has been closed or not.
>
> Right, good point.
>
> However, when I call eof?() before the Net::HTTP call it behaves
> differently (stalls and prints false). Why does it not behave the
> same after that page read?

$ cat test.rb
puts "closed? %p" % $stdin.closed?
puts "eof? %p" % $stdin.eof?

require 'net/http'
require 'io/wait'

Net::HTTP.start('localhost', 80) do |http|
body = http.get('/').body
end

puts "closed? %p" % $stdin.closed?
puts "eof? %p" % $stdin.eof?

$ ruby test.rb
closed? false
type some text here
eof? false
closed? false
eof? false
$

For the first #eof? no data written, so Ruby waits until something's
been flushed. I typed some text and hit return to flush the
terminal's stdout (Ruby's $stdin). At the second #eof? no input on
$stdin has been consumed, so Ruby doesn't need to check for #eof?
again by waiting.

$ cat test.rb
puts "eof? %p" % $stdin.eof?
gets
puts "eof? %p" % $stdin.eof?
$ ruby test.rb
aoeu
eof? false
aoeu
eof? false

--
Eric Hodel - drbrain@segment7.net - http://blog.se...

I LIT YOUR GEM ON FIRE!


James Gray

1/28/2007 6:01:00 AM

0

On Jan 27, 2007, at 8:48 PM, Eric Hodel wrote:

> On Jan 27, 2007, at 18:38, James Edward Gray II wrote:
>> On Jan 27, 2007, at 7:39 PM, Eric Hodel wrote:
>>
>>> $stdin isn't closed, its at the end of file. Use #closed? to
>>> test if an IO has been closed or not.
>>
>> Right, good point.
>>
>> However, when I call eof?() before the Net::HTTP call it behaves
>> differently (stalls and prints false). Why does it not behave the
>> same after that page read?
>
> $ cat test.rb
> puts "closed? %p" % $stdin.closed?
> puts "eof? %p" % $stdin.eof?
>
> require 'net/http'
> require 'io/wait'
>
> Net::HTTP.start('localhost', 80) do |http|
> body = http.get('/').body
> end
>
> puts "closed? %p" % $stdin.closed?
> puts "eof? %p" % $stdin.eof?
>
> $ ruby test.rb
> closed? false
> type some text here
> eof? false
> closed? false
> eof? false
> $
>
> For the first #eof? no data written, so Ruby waits until
> something's been flushed.

OK, that makes sense. However, why does moving that eof?() check
below a Net::HTTP page fetch change this? In that case, why does
Ruby not need for something to be flushed in that case and why is eof?
() then +true+?

James Edward Gray II


Eric Hodel

1/29/2007 9:55:00 AM

0

On Jan 27, 2007, at 22:01, James Edward Gray II wrote:
> On Jan 27, 2007, at 8:48 PM, Eric Hodel wrote:
>> On Jan 27, 2007, at 18:38, James Edward Gray II wrote:
>>> On Jan 27, 2007, at 7:39 PM, Eric Hodel wrote:
>>>
>>>> $stdin isn't closed, its at the end of file. Use #closed? to
>>>> test if an IO has been closed or not.
>>>
>>> Right, good point.
>>>
>>> However, when I call eof?() before the Net::HTTP call it behaves
>>> differently (stalls and prints false). Why does it not behave
>>> the same after that page read?
>>
>> $ ruby test.rb
>> closed? false
>> type some text here
>> eof? false
>> closed? false
>> eof? false
>> $
>>
>> For the first #eof? no data written, so Ruby waits until
>> something's been flushed.
>
> OK, that makes sense. However, why does moving that eof?() check
> below a Net::HTTP page fetch change this?

I don't see this behavior. With your original example I have to hit
^D to get a prompt back.

$ ruby -v
ruby 1.8.5 (2006-12-04 patchlevel 2) [i686-darwin8.8.2]

> In that case, why does Ruby not need for something to be flushed

Because #eof? reads a character if feof(3) is not true and there's no
data pending:

rb_io_eof(io)
VALUE io;
{
OpenFile *fptr;
int ch;

GetOpenFile(io, fptr);
rb_io_check_readable(fptr);

if (feof(fptr->f)) return Qtrue;
if (READ_DATA_PENDING(fptr->f)) return Qfalse;
READ_CHECK(fptr->f);
clearerr(fptr->f);
TRAP_BEG;
ch = getc(fptr->f);
^^^^^^^^^^^^^^^^^^^

Analysis of sampling pid 15640 every 10.000000 milliseconds
Call graph:
[...]
300 rb_io_eof
300 getc
[...]

> in that case and why is eof?() then +true+?

#eof? will only be true when there's no more data to read.

--
Eric Hodel - drbrain@segment7.net - http://blog.se...

I LIT YOUR GEM ON FIRE!


James Gray

1/29/2007 6:20:00 PM

0

On Jan 29, 2007, at 3:54 AM, Eric Hodel wrote:

> On Jan 27, 2007, at 22:01, James Edward Gray II wrote:
>> OK, that makes sense. However, why does moving that eof?() check
>> below a Net::HTTP page fetch change this?
>
> I don't see this behavior. With your original example I have to
> hit ^D to get a prompt back.
>
> $ ruby -v
> ruby 1.8.5 (2006-12-04 patchlevel 2) [i686-darwin8.8.2]

I just upgraded to Ruby 1.8.5 to see if it would make a difference,
but I still don't get prompted for input and it still tells me $stdin
is closed:

Firefly:~/Desktop$ ruby -v
ruby 1.8.5 (2006-12-25 patchlevel 12) [i686-darwin8.8.1]
Firefly:~/Desktop$ cat stdin_eof_issue.rb
require 'net/http'
require 'io/wait'

Net::HTTP.start('www.ruby-lang.org', 80) do |http|
body = http.get('/en/license.txt').body
end
p $stdin.eof?
Firefly:~/Desktop$ ruby stdin_eof_issue.rb
true

James Edward Gray II

James Gray

1/29/2007 6:21:00 PM

0

On Jan 29, 2007, at 12:20 PM, James Edward Gray II wrote:

> I still don't get prompted for input and it still tells me $stdin
> is closed:

I'm sorry, I meant it still claims $stdin is at eof?().

James Edward Gray II

Jacob Fugal

1/29/2007 6:32:00 PM

0

On 1/29/07, James Edward Gray II <james@grayproductions.net> wrote:
> I just upgraded to Ruby 1.8.5 to see if it would make a difference,
> but I still don't get prompted for input and it still tells me $stdin
> is [eof]:

I can confirm on my machine:

lukfugl@hephaestus:~$ ruby -v
ruby 1.8.5 (2006-08-25) [i486-linux]
lukfugl@hephaestus:~$ cat test.rb
require 'net/http'
require 'io/wait'

Net::HTTP.start('www.ruby-lang.org', 80) do |http|
body = http.get('/en/license.txt').body
end
p $stdin.eof?
lukfugl@hephaestus:~$ ruby test.rb
true

One note: the first time I ran it, I thought it was waiting for input
too, but it was really just a few second delay while fetching
http://www.ruby-lang.org/en/l....

Jacob Fugal

Eric Hodel

1/30/2007 6:39:00 PM

0

On Jan 29, 2007, at 10:32, Jacob Fugal wrote:
> On 1/29/07, James Edward Gray II <james@grayproductions.net> wrote:
>> I just upgraded to Ruby 1.8.5 to see if it would make a difference,
>> but I still don't get prompted for input and it still tells me $stdin
>> is [eof]:
>
> I can confirm on my machine:

Then your getc may do something different than mine (BSD-ish).

James Gray

1/30/2007 6:42:00 PM

0

On Jan 30, 2007, at 12:38 PM, Eric Hodel wrote:

> On Jan 29, 2007, at 10:32, Jacob Fugal wrote:
>> On 1/29/07, James Edward Gray II <james@grayproductions.net> wrote:
>>> I just upgraded to Ruby 1.8.5 to see if it would make a difference,
>>> but I still don't get prompted for input and it still tells me
>>> $stdin
>>> is [eof]:
>>
>> I can confirm on my machine:
>
> Then your getc may do something different than mine (BSD-ish).

In other words, you don't feel this is a Ruby issue, right?

James Edward Gray II