| 645 | == I/O バッファ == |
| 646 | sys* な I/O 操作関数の間違った使い方をすると酷い目に遭うというお話 |
| 647 | |
| 648 | * iotest.pl |
| 649 | {{{ |
| 650 | #!perl |
| 651 | use strict; |
| 652 | use warnings; |
| 653 | use IO::File; |
| 654 | use Fcntl qw(:seek); |
| 655 | |
| 656 | my $io = IO::File->new($0); |
| 657 | |
| 658 | $io->sysseek( 0, SEEK_END ); |
| 659 | printf "%s\n", defined( $io->getline() ) ? "defined" : "undef"; |
| 660 | |
| 661 | while (1) { |
| 662 | if ( defined( my $line = $io->getline() ) ) { |
| 663 | my $h = `hostname`; |
| 664 | print $line; |
| 665 | next; |
| 666 | } |
| 667 | sleep(1); |
| 668 | } |
| 669 | |
| 670 | __END__ |
| 671 | }}} |
| 672 | * 実行 |
| 673 | {{{ |
| 674 | $ perl iotest.pl |
| 675 | undef |
| 676 | }}} |
| 677 | * 実行中に別端末から追記 |
| 678 | {{{ |
| 679 | $ echo -en "hogehoge\nfoofoo\n" >> iotest.pl |
| 680 | }}} |
| 681 | |
| 682 | 最大 1 秒後に追記された行が表示されるかと思いきや,そうはならない (少なくとも 5.8.8 では). |
| 683 | |
| 684 | ポインタがファイル先頭から 9 バイト ("hogehoge\n") 目に移動し, |
| 685 | そこからファイル内容が全て読み出される. |
| 686 | |
| 687 | 8 行目の sysseek を seek に変更すれば解決する. |
| 688 | |