[Win32utils-devel] IO.socketpair addition -- very helpful!
Daniel Berger
djberg96 at gmail.com
Thu Mar 27 19:03:07 EDT 2008
Steve,
Thanks for this.
May I recommend joining the win32utils-devel mailing list? You would
be most welcome with ideas like this!
Regards,
Dan
On Thu, Mar 27, 2008 at 9:52 AM, Steve Shreeve <steve.shreeve at gmail.com> wrote:
>
>
> Dan,
>
> I had nearly pulled my hair out over the past week trying to figure out why
> I couldn't spawn a process on Windows and communicate with it. A few things
> I found out later:
>
> 1) The 'fork' implementation is totally gorked and should be renamed to
> something other that 'fork'... it's more like 'clone_me_and_do_over()'.
> 2) On Windows, pipes are essentially worthless because select() always says
> there's data, which will take you into a black hole if you try to read it.
>
> I *did* figure out, however, that sockets actually behave quite nicely on
> Windows. Also, I found your latest win32/process has some nice additions
> (modulo the few tweakers we've been discussing recently).
>
> In order to create a fairly clean way to interact with subprocesses, I've
> now got the code below.
>
> Let me know if this is helpful.
>
> Thanks,
>
> Steve
>
> ==
>
> require 'socket'
>
> STDIN.sync = STDOUT.sync = STDERR.sync = true
>
> class IO
> def self.socketpair(sync=true)
> if RUBY_PLATFORM.include?('win32')
> tcp = TCPServer.new('127.0.0.1', 0)
> one = TCPSocket.new('127.0.0.1', tcp.addr[1])
> two = tcp.accept and tcp.close
> else
> one, two = UNIXSocket.socketpair
> end
> one.sync = two.sync = true if sync
> [one, two]
> end
>
> def self.spawn(cmd=nil)
> io, child_io = IO.socketpair
>
> require 'win32/process'
> child = Process.create(
> 'app_name' => "cmd /k #{cmd}", # the "/k" keeps the process around
> when it's done
> 'process_inherit' => true, # not yet sure if this one is actually
> needed
> 'thread_inherit' => true, # not yet sure if this one is actually
> needed
> 'startup_info' => {
> 'stdin' => child_io,
> 'stdout' => child_io,
> 'stderr' => File.open('nul', 'wb') # ignore STDERR, for now (what
> about sync? close?)
> }
> )
> at_exit do
> Process.TerminateProcess(child.process_handle, child.process_id)
> Process.CloseHandle(child.process_handle)
> end
> child_io.close
>
> io
> end
> end
>
> io = IO.spawn('date')
>
> # communicate using "io" and control threads...
>
More information about the win32utils-devel
mailing list