掲示板利用宣言

 次のフォームをすべてチェックしてからご利用ください。

 私は

 題名と投稿者名は具体的に書きます。
 課題の丸投げはしません。
 ソースの添付は「HTML変換ツール」で字下げします。
 返信の引用は最小限にします。
 環境(OSとコンパイラ)や症状は具体的に詳しく書きます。
 返信の付いた投稿は削除しません。
 マルチポスト(多重投稿)はしません。

掲示板2

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧

No.24380

FILEポインタ(ファイル記述子)も局所変数なのか?
投稿者---zero(2005/11/27 16:08:34)


例えば次のソースの場合 file_open関数からの返り値であるファイルポインタは
main関数からでも使えるのでしょうか?
普通、局所変数はその関数を抜けるとスタックも解放されるので名前通りその関数の
中だけのもので、その値を外部から参照するとゴミの値となりますが、ファイルポインタの場合も同様なのでしょうか?
それともァイル記述子はプロセステーブルで管理されているので、ファイル記述子の場合は別なのでしょうか?
そのファイルをオープンすれば、そのプロセスの中で、close(2)を呼び出すまでは、
(意図しないclose(2)の自動的な呼び出しは除いて)、どの関数からでも、そのファイル記述子は参照できるのでしょうか?

ご教授の程よろしくお願いします。

#include <stdio.h>

FILE *file_open(char *filename) {
    FILE *fp;
    fp = fopen(filename, "r");
    return fp;
}

int main(int argc, char *argv[]) {
    FILE *fp;
    char buf[1024];

    fp = file_open(argv[1]);
    fgets(buf, sizeof(buf), fp);
    while (!feof(fp)) {
        printf("%s", buf);
        fgets(buf, sizeof(buf), fp);
    }
    return 0;
}



この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:FILEポインタ(ファイル記述子)も局所変数なのか? 24382 zero 2005/11/27 16:43:12
<子記事> Re:FILEポインタ(ファイル記述子)も局所変数なのか? 24383 まきじ 2005/11/27 16:59:43


No.24382

Re:FILEポインタ(ファイル記述子)も局所変数なのか?
投稿者---zero(2005/11/27 16:43:12)


OS: Linux
コンパイラ: gcc

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>

void work(int fd) {
    close(fd);
}

int main(int argc, char *argv[]) {
    int fd;
    char buf[1024];
    ssize_t ret;

    fd = open(argv[1], O_RDONLY);

    work(fd);

    ret = read(fd, buf, sizeof(buf));
    switch (ret) {
    case -1:
        fprintf(stderr, "[*] read() error: %s\n", strerror(errno));
        exit(1);
    default:
        fprintf(stderr, "[+] read() success\n");
    }

    return 0;
}


上記のソースを実行したところ、

[*] read() error: Bad file descriptor

という結果でした。
普通関数を呼び出したとき、呼び出し元の引数はコピーされるだけで、呼び出し元の引数にはなんら影響を与えません(ポインタを使う場合は別ですが)。

しかし、このソースでwork()関数内でclose()を呼び出し、main関数内でオープンした
ファイル記述子をclose()したら、main()関数側でread()のエラーがでます。

ということはやはり、ファイル記述子はプロセステーブルで管理されているので、ある関数でファイルをオープンすると、それは、プログラムの中で、グローバルな記述子になると思うのですが、違うのでしょうか?

説明がへたで、すいません。
ご教授のほどよろしくお願いします。


この投稿にコメントする

削除パスワード

No.24386

Re:FILEポインタ(ファイル記述子)も局所変数なのか?
投稿者---まきじ(2005/11/27 17:33:30)


>普通関数を呼び出したとき、呼び出し元の引数はコピーされるだけで、呼び出し元の引数にはなんら影響を与えません

その通りです。
work() 側の fd を変更しても、main() 側の fd の値は変わりません。

ファイル記述子は、負でない整数なのでコピーされた値とかは関係ありません。
open() の戻り値が 2 であれば close(2) としてやれば
ファイルとのストリームが断たれます。
今回は int 型の変数 fd に記憶しているだけです。

>しかし、このソースでwork()関数内でclose()を呼び出し、main関数内でオープンした
>ファイル記述子をclose()したら、main()関数側でread()のエラーがでます。

close() したファイルを read() できるわけないですね。

>グローバルな記述子になると思うのですが、違うのでしょうか?

open() は int 型として ファイル記述子を返すので
close() しない限りプログラム上のどこでも使えます。
main() 以外の関数で使用したいのなら、引数で渡してやれば良いだけです。


この投稿にコメントする

削除パスワード

No.24387

Re:FILEポインタ(ファイル記述子)も局所変数なのか?
投稿者---zero(2005/11/27 17:40:28)


簡潔な説明ありがとうございす。

今回の件でより理解が深まりました。

ありがとうございました。


この投稿にコメントする

削除パスワード

No.24383

Re:FILEポインタ(ファイル記述子)も局所変数なのか?
投稿者---まきじ(2005/11/27 16:59:43)


>例えば次のソースの場合 file_open関数からの返り値であるファイルポインタは
>main関数からでも使えるのでしょうか?

FILE 型へのポインタを渡してやれば使えます。

>それともァイル記述子はプロセステーブルで管理されているので、ファイル記述子の場合は別なのでしょうか?

ファイル記述子は OS で管理されています。

fopen() は 低水準入力(open()) で OS からファイル記述子を取得して
ファイルの情報を、構造体 FILE 型の変数に代入して、
そのポインタを返してます。
# 構造体 FILE のメンバ fd にファイル記述子が格納されています。

fp は 他の変数と同じで FILE* 型であり自動変数です。


この投稿にコメントする

削除パスワード

No.24384

Re:FILEポインタ(ファイル記述子)も局所変数なのか?
投稿者---zero(2005/11/27 17:07:04)


まきじさん返信ありがとうございます。

ファイル記述子も局所変数だとすると、私の二つめのスレッドのプログラムで、
read()システムコールがエラーを返すのは、なぜなのでしょうか?


この投稿にコメントする

削除パスワード

No.24388

Re:FILEポインタ(ファイル記述子)も局所変数なのか?
投稿者---Ban(2005/11/27 18:16:49)


>read()システムコールがエラーを返すのは、なぜなのでしょうか?

ファイルディスクリプタ自身の自動変数としての有効範囲と、
そのファイルディスクリプタが示す対象の有効範囲は別物で、
無関係だからです。
ディスクリプタとはハンドルの一種であり、
その挙動はポインタを格納した
自動変数に近いです。


この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧