[#44725] Set[Set[1]]==Set[Set[1]] は偽? — "5.5" <5.5@...>

5.5 です。

22 messages 2008/03/04

[#44782] $stdin.rewind が exec した子プロセスに伝わらない? — SATOH Fumiyasu <fumiyas@...>

さとうふみやす @ OSS テクノロジです。

11 messages 2008/03/17
[#44783] Re: $stdin.rewind が exec した子プロセスに伝わらない? — Kazuhiro NISHIYAMA <zn@...> 2008/03/17

西山和広です。

[ruby-list:44784] Re: $stdin.rewind が exec した子プロセスに伝わらない?

From: SATOH Fumiyasu <fumiyas@...>
Date: 2008-03-17 11:22:02 UTC
List: ruby-list #44784
さとうふみやす @ OSS テクノロジです。

At Mon, 17 Mar 2008 20:00:58 +0900,
Kazuhiro NISHIYAMA wrote:
> > $stdin.rewind
> > print "2: stdin.gets: ", $stdin.gets
> 
> ここの$stdin.getsで読み込んだ後の$stdin.rewindはFILE*のストリームの
> 先頭に戻る(fseek(3))だけで、ファイルディスクリプタは読み込んだ位置に
> 進んだまま(lseek(2)ではない)だから、execした後のプログラムには
> 影響しないのではないでしょうか?

そうは思えないです。元々は以下のようなコードでした。

$ cat stdin-rewind2.rb
require 'tempfile'

tmp = Tempfile.new('test')
tmp.print "Foo Bar #{$$}";

pid = Process.fork
unless pid
  $stdin.reopen(tmp)

  $stdin.rewind
  system('cat'); print "\n"
  exit
end
Process.waitpid(pid)

これを実行すると、先のスクリプトと同様の結果になります:

$ ruby stdin-rewind2.rb
(改行だけ出力される)

以下のようにすると、ちゃんと動きます。

$ cat stdin-rewind3.rb
require 'tempfile'

tmp = Tempfile.new('test')
tmp.print "Foo Bar #{$$}";
tmp.rewind

pid = Process.fork
unless pid
  $stdin.reopen(tmp)

  system('cat'); print "\n"
  exit
end
Process.waitpid(pid)

$ ruby stdin-rewind3.rb
Foo Bar 3505

最初は fork か reopen 絡みの問題かと思ったのですが、
単純化(?)していったら先メールのコードで再現した次第です。

-- 
-- Name: SATOH Fumiyasu (fumiyas @ osstech co jp)
-- Business Home: http://www.OSSTech.co.jp/
-- Personal Home: http://www.SFO.jp/blog/

In This Thread