From: "Kroeger Simon (ext)" Date: 2005-09-14T18:56:56+09:00 Subject: Win Pipes and IO 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. 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. (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 = 12 O_RDONLY = 0x0000 # open for reading only O_WRONLY = 0x0001 # open for writing only O_TEXT = 0x4000 # file mode is text (translated) O_BINARY = 0x8000 # file mode is binary (untranslated) def create_pipe # returns read and write handle params = [ 'P', # pointer to read handle 'P', # pointer to write handle 'P', # pointer to security attributes 'L'] # pipe size createPipe = Win32API.new("kernel32", "CreatePipe", params, 'I') read_handle, write_handle = [0].pack('I'), [0].pack('I') sec_attrs = [SECURITY_ATTRIBUTES_SIZE, 0, 1].pack('III') return [0, 0] if createPipe.Call(read_handle, write_handle, sec_attrs, 0).zero? [read_handle.unpack('I')[0], write_handle.unpack('I')[0]] end open_osfhandle = Win32API.new("msvcrt", "_open_osfhandle", ['L','L'], 'L') fdopen = Win32API.new("msvcrt", "_fdopen", ['L','P'], 'L') fgets = Win32API.new("msvcrt", "fgets", ['P', 'L', 'L'], 'L') fputs = Win32API.new("msvcrt", "fputs", ['P', 'L'], 'L') fclose = Win32API.new("msvcrt", "fclose", ['L'], 'L') h_in, h_out = create_pipe f_in = open_osfhandle.call(h_in, O_RDONLY | O_BINARY) f_out = 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 = fdopen.call(f_in, 'rb') stream_out = fdopen.call(f_out, 'wb') fputs.call("Hellooooo\000", stream_out) fclose.call(stream_out) buffer = "\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') #=> No such file or directory (Errno::ENOENT) IO.new(f_out, 'wb') end ---------------------------------------------------------------