> Submitted By: Jan Mehnert (janmehnert)

> # eth_mini_test.rbw:32:in `close': Unknown Error (Errno::ENOTSOCK)


  I use the mswin build for Net library work.
  Sockets have never worked for me on bcc build.

  ** ruby 1.9.0 (2005-07-16) [i586-bccwin32]
  Example:

  #----------
  require 'net/http'
  p ['Net::HTTP', Net::HTTP::Revision, Net::HTTP::HTTPVersion]

  h = Net::HTTP.new('www.rubyist.net')
  resp = h.get('/index.html', nil)
  puts resp.body
  #----------

  ["Net::HTTP", "1.126", "1.1"]
  D:/RUBY/SRC_CVSINST/lib/ruby/1.9/net/protocol.rb:70:in `close': Bad file number (Errno::EBADF)
   from D:/RUBY/SRC_CVSINST/lib/ruby/1.9/net/protocol.rb:70:in `close'
   from D:/RUBY/SRC_CVSINST/lib/ruby/1.9/net/http.rb:552:in `do_finish'
   from D:/RUBY/SRC_CVSINST/lib/ruby/1.9/net/http.rb:492:in `start'
   from D:/RUBY/SRC_CVSINST/lib/ruby/1.9/net/http.rb:982:in `request'
   from D:/RUBY/SRC_CVSINST/lib/ruby/1.9/net/http.rb:716:in `get'
   from C:/TEMP/rbD115.TMP:5


EBADF is not important, previous builds have given: Unknown Error (Errno::ENOTSOCK)

Below is a  **very old**  trace to remind myself of the sequence of events.

In summary, fptr_finalize(io.c)  calls  rb_w32_fclose *twice* --
 once for each side of the r/w socket.
My understanding is that Windows requires only _one_ closesocket call.

But mswin build handles it OK.
I think the difference between mswin and bccwin relates to ERRNO ??

 o) msvcrt-ruby1x.dll and socket.so both refer to _errno in msvcr71.dll run-time
     and they see the same copy (passed between each other).

 o) bccwin32-ruby1x.dll and socket.so both refer to _errno in CC3250.dll run-time
     but it seemed evident to me that they had separate copies.
     (i.e. if  socket.c  sets errno, Ruby run-time reads the value from the most
     recent operation in Ruby, *not* in socket extension.)

The two ERRNO implementations are not similar.


I hope your debugging tools are better than mine.
 "is_socket" and "errno" are the things to watch, IMHO.

Let me know if there's anything you want me to try.


daz
-- 


< **very old**  "trace" >

   io  rb_fdopen <- File* [004c6240]  (f)  read
   io  rb_fdopen <- File* [004c6258]  (f2) write
         RETURN( <- ) with OPEN FILE pointers
   ...
   ...

              ENTER( -> )
   io  rb_io_close_m ->
   io     rb_io_close ->
   io        rb_io_fptr_cleanup ->
   io           fptr_finalize ->

     #            fptr_finalize calls fclose [#defined as rb_w32_fclose] twice
     #                  (once for each side of the r/w socket)
     #              fd = fileno(004c6240 -OR- 004c6258) // OK, both yield 4 as file descriptor
     #              TO_SOCKET(fd)                       // OK, [00000090]

     #            First, the write side:

   io               # while (fclose f2 fd#4 [004c6258])
   w32             rb_w32_fclose ->  File* [004c6258] fd#4 sock[00000090]
   w32                 is_socket ->
   w32                 is_socket <- sock[00000090] (TRUE)  l_onoff[0000] l_linger[0000]
   w32                ..(rb_w32_fclose)  sock fclose ->  is_socket?==TRUE
   w32                 is_socket ->
   w32                    ..(is_socket) WSA_GLE(WSAENOTSOCK) errno(0)
   w32                 is_socket <- sock[00000090] (FALSE)
   w32                ..(rb_w32_fclose)  sock fclose <- errcd(0) is_socket?==FALSE
   w32             rb_w32_fclose <- WSA_GLE(WSAENOTSOCK) errno!(WSAENOTSOCK)

            #            Then, the read side:

   io               # while (fclose f1 fd#4 [004c6240])
   w32             rb_w32_fclose ->  File* [004c6240] fd#4 sock[ffffffff]
   w32                 is_socket ->
   w32                    ..(is_socket) WSA_GLE(WSAENOTSOCK) errno(6)
   w32                 is_socket <- sock[ffffffff] (FALSE)
   w32                 ..(rb_w32_fclose) - UnlockFile *error* GLE(6)
   w32                 ..(rb_w32_fclose)  NON-sock fclose ->
   w32              rb_w32_fclose <-  NON-sock fclose <- errcd(-1)

   io              ..(fptr_finalize) ***SYS_FAIL*** err_n1 = 0, err_n2 = WSAENOTSOCK

======END======