[Home]POPFile/ReadWrite

Amatubu_Wiki | POPFile | RecentChanges | Preferences

読み書き混合モードについてのメモ

Perl で、読み書き混合モードでファイルを開き、読み込み・書き込みを連続して行った場合に予期せぬことが起こるというような問題。IMAP モジュールにて一部問題が起こっている。

検証用コード1

#!/usr/bin/perl

use strict;
use Fcntl;

my $file="imap.tmp";
my $p;
my $i = 0;
my $current_filehandle;
my $buf;

sysopen $p, $file, O_RDWR | O_CREAT | O_TRUNC;
binmode($p);

sysseek $p, 0, 1;

while ( $i < 10 ) {
    syswrite $p, "$i\n";
    $i++;
}

sysseek $p, 0, 0;

print "---HEADER---\n";
while (sysread( $p, $buf, 3 ) > 0) {
    print $buf;
}

sysseek $p, 0, 1; # <- これがないと、一部環境で問題が生じる?

while ( $i < 20 ) {
    syswrite $p, "$i\n";
    $i++;
}

sysseek $p, 0, 0;

print "---HEADER and BODY---\n";
while (sysread( $p, $buf, 3 ) > 0) {
    print $buf;
}

close $p;
# unlink $file;

検証用コード 2

#!/usr/bin/perl

open(LOG, "+>logfile3.txt");
binmode(LOG);
print LOG "aaaaaaaaaa\n";
seek(LOG, 0, 0);
$a = <LOG>;print '$a='.$a;
seek(LOG, 0, 1); # <- ここをはずすと、環境によって問題が生じる? Win32 では、binmode にしていれば問題なし
print LOG "bbbbbbbbbb\n";
seek(LOG, 0, 0);
$a = <LOG>;print '$a='.$a;
$b = <LOG>;print '$b='.$b;
close(LOG); 

関連情報

Due to the rules and rigors of ANSI C, on some systems you have to do a seek whenever you switch between reading and writing. Amongst other things, this may have the effect of calling stdio's clearerr(3). A WHENCE of 1 (SEEK_CUR ) is useful for not moving the file position:
seek(TEST,0,1);

sysseek には seek に書かれているようなことが書かれていないことから、こちらであれば問題が起こらないのかもしれないが、相変わらず問題が起こっていることを考えると、

sysseek(...,0,1);
を試してみる価値はあるだろう。

Amatubu_Wiki | POPFile | RecentChanges | Preferences
This page is read-only | View other revisions
Last edited November 20, 2007 15:40 by Amatubu (diff)
Search:

Copyright (c) 1996-2006 naoki iimura e-mail