[#29170] Call for Papers Linux Conference 2001 — akira yamada / やまだあきら <akira@...>

18 messages 2001/04/10
[#30213] Re: Call for Papers Linux Conference 2001 — akira yamada / やまだあきら <akira@...> 2001/06/13

[#29190] Time Stamp Copy of File.copy — "たけ(tk)" <ggb03124@...>

 ftools.rb の move では utime を行っていて日付が同じになりますが、copy

42 messages 2001/04/11
[#29193] Re: Time Stamp Copy of File.copy — matz@... (Yukihiro Matsumoto) 2001/04/11

まつもと ゆきひろです

[#29201] Re: Time Stamp Copy of File.copy — " たけ (tk)" <ggb03124@...> 2001/04/11

たけ(tk)です。

[#29203] Re: Time Stamp Copy of File.copy — WATANABE Hirofumi <eban@...> 2001/04/11

わたなべです.

[#29212] Re: Time Stamp Copy of File.copy — Minero Aoki <aamine@...> 2001/04/12

あおきです。

[#29215] Re: Time Stamp Copy of File.copy — " たけ (tk)" <ggb03124@...> 2001/04/12

たけ(tk)です。

[#29220] Re: Time Stamp Copy of File.copy — Minero Aoki <aamine@...> 2001/04/12

あおきです。

[#29234] Re: Time Stamp Copy of File.copy — " たけ (tk)" <ggb03124@...> 2001/04/13

たけ(tk)です。

[#29236] Re: Time Stamp Copy of File.copy — matz@... (Yukihiro Matsumoto) 2001/04/13

まつもと ゆきひろです

[#29238] Array#include! — " たけ (tk)" <ggb03124@...> 2001/04/13

たけ(tk)です。

[#29244] Re: Array#include! — matz@... (Yukihiro Matsumoto) 2001/04/13

まつもと ゆきひろです

[#29348] Open3 — NISHIO Mizuho <mzh@...>

どうも西尾です。

16 messages 2001/04/20

[#29397] rnet.rb 〜高レベルネットライブラリ〜 — rubikitch <rubikitch@...>

るびきちです。

11 messages 2001/04/24

[ruby-list:29376] Re: Open3

From: nobu.nakada@...
Date: 2001-04-23 02:36:13 UTC
List: ruby-list #29376
なかだです。

At Sat, 21 Apr 2001 19:04:37 +0900,
NISHIO Mizuho <mzh@portnet.ne.jp> wrote:
> ちょっと見てみたんですが、
> どの辺りが肝なのかよく分かりませんでした。

  むぅ、たしかに。あれだけじゃ話になりません。だいたいにゃすさ
んの方は CreateProcess() 入ってませんでした。

  一応それらしいのを作ってみましたが、Windows で動くかどうかは
知りません。たぶんどっかバグってるでしょう。分かる人直してくだ
さい。あと popen を使ってないので、 io#pid が nil になるとか、
wait できないとかいろいろありますが、仕様です(笑)。

# やっぱり Windows のプロセス生成のモデルはこういうときに融通が
# 効かない。
## つーか、構造体めんどくさすぎ。

  で、MoonWolf さんの Win32Module を使ってますが、定数・関数だ
けじゃなくて構造体も入れてもらえませんか? > MoonWolf さん。


case RUBY_PLATFORM
when /mswin32/, /mingw32/
  require 'win32/winbase'

  module IO
    def handle
      Win32::GetOSFHandle(fileno)
    end
  end

  module Win32
    GetOSFHandle = Win32API.new('msvcrt', '_get_osfhandle', 'I', 'I')
    GetLastError = Win32API.new('kernel32','GetLastError','V','I')
    GetStdHandle = Win32API.new('kernel32','GetStdHandle','L','L')

    class Struct < ::Struct
      def to_s; pack; end
    end

    STARTUPINFOA = Struct.new(:desktop, :title, :x, :y, :xsize, :ysize,
			      :xcountchars, :ycountchars,
			      :fillattribute, :flags, :showwindow,
			      :stdinput, :stdoutput, :stderror)
    class STARTUPINFOA
      TEMPLATE = "I x8 p p I8 S x6 I3"
      STD_HANDLES = {STDIN => :stdinput=, STDOUT => :stdoutput=, STDERR => :stderror=}
      def pack
	to_a.unshift(68).pack(TEMPLATE)
      end
      def self.unpack(s)
	new(*s.unpack(TEMPLATE)[1..-1])
      end
      def redirect(from, to)
	to = STD_HANDLES[to] and send(to, from ? from.handle : INVALID_HANDLE_VALUE)
      end
    end

    SECURITY_ATTRIBUTES = Struct.new(:securitydescriptor, :inherithandle)
    class SECURITY_ATTRIBUTES
      def pack
	to_a.unshift(12).pack(securitydescriptor ? "IPI" : "III")
      end
      def self.unpack(s)
	new(*s.unpack("IPI")[1..-1])
      end
    end

    PROCESS_INFORMATION = Struct.new(:process, :thread, :processid, :threadid)
    class PROCESS_INFORMATION
      TEMPLATE = "I4"
      def pack
	to_a.pack(TEMPLATE)
      end
      def self.unpack(s)
	new(*s.unpack(TEMPLATE))
      end
    end

    def self.spawn(*cmd)
      sa = SECURITY_ATTRIBUTES.new(nil, inherit)
      si = STARTUPINFOA.new
      si.flags = STARTF_USESTDHANDLES
      if Hash === cmd.last
	opt = cmd.pop
	dir = opt[:directory] and Dir.chdir(dir)
	if Hash === (env = opt[:environment])
	  env = env.collect {|k, v| "#{k}=#{v}"}.push("\0").join("\0")
	end
	opt.each {|io, newio| si.redirect(newio, io) if IO === io}
	si.stdinput ||= GetStdHandle(STD_INPUT_HANDLE)
	si.stdoutput ||= GetStdHandle(STD_OUTPUT_HANDLE)
	si.stderror ||= GetStdHandle(STD_ERROR_HANDLE)
      end
      cmd, *arg = cmd
      if Array === cmd
	arg.unshift(cmd.pop)
	cmd, = cmd
      else
	arg.unshift(cmd)
	cmd = nil
      end
      arg = arg.collect! {|s| /\s/ =~ s ? "\"#{s}\"" : s}.join(' ')
      pri = NORMAL_PRIORITY_CLASS
      sa = sa.pack
      si = si.pack
      pi = PROCESS_INFORMATION.new.pack
      ret = CreateProcessA.call(cmd, arg, sa, sa, inherit, pri, env, dir, si, pi)
      raise "CreateProcess failed: %d", GetLastError.call if ret == 0
      pi = PROCESS_INFORMATION.unpack(pi)
      CloseHandle(pi.thread)
      pi.process
    end
  end
  def system(*args)
    Win32.spawn(*args)
  end
when /human/, /macos/, /emx/
  # fork not implemented
else
  def system(*cmd)
    fork do
      if Hash === cmd.last
	opt = cmd.pop
	dir = opt[:directory] and Dir.chdir(dir)
	if Hash === (env = opt[:environment])
	  ENV.each_key {|e| ENV[e] = nil}
	  env.each {|e, v| ENV[e] = v}
	end
	opt.each do |io, newio|
	  newio ? io.reopen(newio) : io.close if IO === io
	end
      end
      exec(*cmd)
    end
  end
end

module Open3
  def popen3(*cmd)
    ri, wi = IO.pipe
    ro, wo = IO.pipe
    re, we = IO.pipe
    cmd << {STDIN => ri, STDOUT => wo, STDERR => we, wi => nil, ro => nil, re => nil}
    pid = system(*cmd)
    [ri, wo, we].each {|p| p.close}
    pi = [wi, ro, re]
    defined? yield or return pi << pid
    begin
      yield(*pi)
    ensure
      pi.each {|p| p.close unless p.closed?}
      Process.waitpid(pid)
    end
  end
  module_function :popen3
end


-- 
--- 僕の前にBugはない。
--- 僕の後ろにBugはできる。
    中田 伸悦

In This Thread