次の例では、デフォルトのファイル番号stderr
を閉じて、fdopen()
を介してテンポラリファイルの2
というテキストファイルをテンポラリファイルディスクリプタからdup()
に再オープンします。次に、我々はこの記述子に直接write()
2
。これはファイル上の最初の書き込み操作であり、したがって空のバッファを持っているので、安全に行うことができます。この後、stderr
にfprintf()
を追加します。次に、stderr
を閉じます(したがって、関連する記述子2
は自動的に閉じます)。元の記述子fd
は有効なままです。それを介して、一時ファイルの先頭に移動し、内容を読み込んで標準出力に出力します。しかし、出力が文字化けしている:lseek()を使用すると、ファイル記述子のread()が失敗するのはなぜですか?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
int main(void)
{
int fd;
char buf[200];
int n;
char fname[] = "/tmp/tst-perror.XXXXXX";
fd = mkstemp (fname);
fclose (stderr);
dup2 (fd, 2);
stderr = fdopen (2, "w");
fd = fileno(stderr);
char *s = "this is a test\n";
n = write(fd, s, strlen(s));
fprintf(stderr, "multibyte string\n");
fclose (stderr);
// close(fd);
// fd = open(fname, O_RDONLY);
lseek (fd, 0, SEEK_SET);
n = read (fd, buf, sizeof (buf));
printf("%.*s", (int) n, buf);
close (fd);
return 0;
}
出力は次のようになります。
$ ./a.out
����
私たちは、「クローズ」と「オープン」行のコメントを解除し、「のlseek」行をコメントした場合、予想通り、出力は次のとおりです。
$ ./a.out
this is a test
multibyte string
write()
はバッファを持っていない、とstderr
たちは近くないトンをすれば、出力が文字化けしているなぜ、 それが閉じている書かれ、オフになっています彼はそれを読む前にファイル?
また、あなたが 'lseek'のストリームを注意してください。 'man 2 lseek'の注釈を見てください。*いくつかのデバイスはシークできず、POSIXはlseek()をサポートしなければならないデバイスを指定していません。 –