Win Pipes and IO

  • Thread starter Kroeger Simon (ext)
  • Start date
K

Kroeger Simon (ext)

Hi all,

I hope there is a guru out there today.
I create a new Pipe on Windows using 'CreatePipe'. This yields two
handles (for input and output) which can be converted to C run-time file
handles with _open_osfhandle. I can call fdopen on the returned values
and write and read to the pipe.=20

What I wanted to do was creating new IO objects instead of calling
fdopen myself, but I can't get it to work. The implementation of IO.new
calls fdopen so I realy have no clue why this should not do the trick.=20

(Yes I can call IO.pipe, but I need the handles from CreatePipe because
CreateProcess needs them and this is the only way to start childs
without unwanted shell windows)

The other way would be to write a C extension but I'm so close....

please help

Simon
---------------------------------------------------------------
require 'Win32API'

SECURITY_ATTRIBUTES_SIZE =3D 12

O_RDONLY =3D 0x0000 # open for reading only
O_WRONLY =3D 0x0001 # open for writing only
O_TEXT =3D 0x4000 # file mode is text (translated)
O_BINARY =3D 0x8000 # file mode is binary (untranslated)

def create_pipe # returns read and write handle
params =3D [
'P', # pointer to read handle
'P', # pointer to write handle
'P', # pointer to security attributes
'L'] # pipe size

createPipe =3D Win32API.new("kernel32", "CreatePipe", params, 'I')

read_handle, write_handle =3D [0].pack('I'), [0].pack('I')
sec_attrs =3D [SECURITY_ATTRIBUTES_SIZE, 0, 1].pack('III')
=20
return [0, 0] if createPipe.Call(read_handle, write_handle, sec_attrs,
0).zero?
=20
[read_handle.unpack('I')[0], write_handle.unpack('I')[0]]
end

open_osfhandle =3D Win32API.new("msvcrt", "_open_osfhandle", ['L','L'],
'L')
fdopen =3D Win32API.new("msvcrt", "_fdopen", ['L','P'], 'L')
fgets =3D Win32API.new("msvcrt", "fgets", ['P', 'L', 'L'], 'L')
fputs =3D Win32API.new("msvcrt", "fputs", ['P', 'L'], 'L')
fclose =3D Win32API.new("msvcrt", "fclose", ['L'], 'L')

h_in, h_out =3D create_pipe

f_in =3D open_osfhandle.call(h_in, O_RDONLY | O_BINARY)
f_out =3D open_osfhandle.call(h_out, O_WRONLY | O_BINARY)

if true
# This code DOES work, so everything is fine up to this point
stream_in =3D fdopen.call(f_in, 'rb')
stream_out =3D fdopen.call(f_out, 'wb')
=20
fputs.call("Hellooooo\000", stream_out)
fclose.call(stream_out)
=20
buffer =3D "\000" * 200
fgets.call(buffer, 200, stream_in)
puts buffer[0..8]
else
# This does NOT work, why oh why?
IO.new(f_in, 'rb')=20
#=3D> No such file or directory (Errno::ENOENT)
IO.new(f_out, 'wb')=20
end
---------------------------------------------------------------
 
N

nobuyoshi nakada

Hi,

At Wed, 14 Sep 2005 18:56:56 +0900,
Kroeger Simon (ext) wrote in [ruby-talk:156055]:
What I wanted to do was creating new IO objects instead of calling
fdopen myself, but I can't get it to work. The implementation of IO.new
calls fdopen so I realy have no clue why this should not do the trick.

It worked successfully, with both of mswin32 and mingw32 ruby.

$ tail -5 pipe.rb
inp = IO.new(f_in, 'rb')
outp = IO.new(f_out, 'wb')
outp.print("Hellooooo\000")
outp.close
p inp.gets

$ ruby18-mswin32.exe -v pipe.rb
ruby 1.8.3 (2005-07-03) [i386-mswin32]
"Hellooooo\000"

$ ruby18-mingw32.exe -v pipe.rb
ruby 1.8.3 (2005-09-12) [i386-mingw32]
"Hellooooo\000"
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,077
Latest member
SangMoor21

Latest Threads

Top