[#44713] パイプ経由コマンド実行? — "morita" <m-morita@...>
もりたと申します。お世話になります。
10 messages
2008/03/03
[#44714] Re: パイプ経由コマンド実行?
— Hidetoshi NAGAI <nagai@...>
2008/03/03
永井@知能.九工大です.
[#44716] Re: パイプ経由コマンド実行?
— "m-morita" <m-morita@...>
2008/03/03
もりた です。
[#44725] Set[Set[1]]==Set[Set[1]] は偽? — "5.5" <5.5@...>
5.5 です。
22 messages
2008/03/04
[#44726] Re: Set[Set[1]]==Set[Set[1]] は偽?
— "Ohto, Yasunori" <Yasunori.Ohto@...>
2008/03/05
大戸です。
[#44744] Re: Set[Set[1]]==Set[Set[1]] は偽?
— "5.5" <5.5@...>
2008/03/06
5.5 です。
[#44728] ダウンロードリンクが古い — Kouhei Yanagita <yanagi@...>
こんにちは。柳田です。
10 messages
2008/03/05
[#44745] [ANN] Rails勉強会@東京 第28回のお知らせ — "MOROHASHI Kyosuke" <moronatural@...>
各位
1 message
2008/03/07
[#44769] Ann: Ruby-1.9.0-1 Windowsインストーラパッケージ — arton <artonx@...>
artonです。
4 messages
2008/03/13
[#44773] PHPとの関数対照表 — "tadashi nagao" <tadashi.nagao@...>
長尾です。
7 messages
2008/03/14
[#44782] $stdin.rewind が exec した子プロセスに伝わらない? — SATOH Fumiyasu <fumiyas@...>
さとうふみやす @ OSS テクノロジです。
11 messages
2008/03/17
[#44783] Re: $stdin.rewind が exec した子プロセスに伝わらない?
— Kazuhiro NISHIYAMA <zn@...>
2008/03/17
西山和広です。
[#44785] Re: $stdin.rewind が exec した子プロセスに伝わらない?
— Nobuyoshi Nakada <nobu@...>
2008/03/17
なかだです。
[#44786] Re: $stdin.rewind が exec した子プロセスに伝わらない?
— SATOH Fumiyasu <fumiyas@...>
2008/03/18
さとうふみやす @ OSS テクノロジです。
[#44787] Re: $stdin.rewind が exec した子プロセスに伝わらない?
— Nobuyoshi Nakada <nobu@...>
2008/03/18
なかだです。
[#44788] Re: $stdin.rewind が exec した子プロセスに伝わらない?
— SATOH Fumiyasu <fumiyas@...>
2008/03/18
さとうふみやす @ OSS テクノロジです。
[ruby-list:44785] Re: $stdin.rewind が exec した子プロセスに伝わらない?
From:
Nobuyoshi Nakada <nobu@...>
Date:
2008-03-17 21:14:37 UTC
List:
ruby-list #44785
なかだです。
At Mon, 17 Mar 2008 20:00:58 +0900,
Kazuhiro NISHIYAMA wrote in [ruby-list:44783]:
> > $stdin.rewind したとき、その後に ruby から実行する
> > 外部コマンドに反映されないことがあるのですが、バグでしょうか?
> >
> > $ ruby -v
> > ruby 1.8.6 (2008-03-03 patchlevel 114) [x86_64-linux]
> >
> > $ cat stdin-rewind.rb
> > $stdin.rewind
> > system('echo -n "1: head: "; head -n 1')
> >
> > $stdin.rewind
> > print "2: stdin.gets: ", $stdin.gets
>
> ここの$stdin.getsで読み込んだ後の$stdin.rewindはFILE*のストリームの
> 先頭に戻る(fseek(3))だけで、ファイルディスクリプタは読み込んだ位置に
> 進んだまま(lseek(2)ではない)だから、execした後のプログラムには
> 影響しないのではないでしょうか?
stdioの実装に依存します。glibcでは、fseek(3)の結果がFILE*のバッ
ファ内に相当する場合には、lseek(2)は発行しないようです。おそらく
パフォーマンスのためでしょう。これは、rubyに限らずstdioとexecを
使えば常に発生する問題で、以下のプログラムでも再現します。
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
int
main(int argc, char **argv)
{
FILE *f = fopen(argv[1], "r");
if (argc > 2) fseek(f, 0L, SEEK_SET);
fgetc(f);
fseek(f, 0L, SEEK_SET);
dup2(fileno(f), 0);
system("head -1");
return 0;
}
$ ./seektest seektest.c
#include <sys/types.h>
$ ./seektest seektest.c 1
2回目のfseek()を1Lにすると1回目のfseek()にかかわらず出力されなく
なるあたり、glibcのバグなのかもしれません。
もしかしたらもっとちゃんとした方法があるのかもしれませんが、
BUFSIZよりも大きなオフセットでfseek()することでもlseek()もされる
ようです。fflush(NULL)のようにすべてのFILE*についてseekさせるほ
うほうがあれば、before_exec()でやったほうがいいと思いますが。
Index: io.c
===================================================================
--- io.c (revision 15790)
+++ io.c (working copy)
@@ -674,5 +674,5 @@ rb_io_tell(io)
}
-static VALUE
+static off_t
rb_io_seek(io, offset, whence)
VALUE io, offset;
@@ -686,7 +686,11 @@ rb_io_seek(io, offset, whence)
pos = io_seek(fptr, pos, whence);
if (pos < 0 && errno) rb_sys_fail(fptr->path);
+#ifdef _STDIO_USES_IOSTREAM /* GNU libc */
+ fseeko(fptr->f, BUFSIZ * 16L, SEEK_CUR);
+ fseeko(fptr->f, pos, SEEK_SET);
+#endif
clearerr(fptr->f);
- return INT2FIX(0);
+ return pos;
}
@@ -725,5 +729,6 @@ rb_io_seek_m(argc, argv, io)
}
- return rb_io_seek(io, offset, whence);
+ rb_io_seek(io, offset, whence);
+ return INT2FIX(0);
}
@@ -743,13 +748,5 @@ rb_io_set_pos(io, offset)
VALUE io, offset;
{
- OpenFile *fptr;
- off_t pos;
-
- pos = NUM2OFFT(offset);
- GetOpenFile(io, fptr);
- pos = io_seek(fptr, pos, SEEK_SET);
- if (pos != 0) rb_sys_fail(fptr->path);
- clearerr(fptr->f);
-
+ off_t pos = rb_io_seek(io, offset, SEEK_SET);
return OFFT2NUM(pos);
}
@@ -776,6 +773,6 @@ rb_io_rewind(io)
GetOpenFile(io, fptr);
- if (io_seek(fptr, 0L, 0) != 0) rb_sys_fail(fptr->path);
- clearerr(fptr->f);
+ if (rb_io_seek(io, INT2FIX(0), SEEK_SET) != 0)
+ rb_sys_fail(fptr->path);
if (io == current_file) {
gets_lineno -= fptr->lineno;
--
--- 僕の前にBugはない。
--- 僕の後ろにBugはできる。
中田 伸悦