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
---------------------------------------------------------------
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
---------------------------------------------------------------