- ベストアンサー
access関数を説明できる方いますか?
C言語に、ファイルの存在の有無を確認できる accessという関数があったと思うのですが 使用するヘッダファイルや引数、戻り値などを 説明できる方いらっしゃいましたらどうかお願いします。 accessを使用したらR_OK,F_OKとかいうマクロが 必要になったと思うのですが・・・
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
acceess()は元々UNIXのシステムコールであり、POSIX準拠OS以外では互換性が保証されません。 これはsignal()などとともに「移植性を阻害する標準関数」の筆頭に分類されます。 環境が指定されていないのでPOSIXのaccess(2)を想定します。 #inclue <io.h> int access(const char *, int) ; 第1引数:ファイルパス名 第2引数:チェックするモード(0=存在、2=書きこみ、4=読み出し,6=読み書き) 関数値が-1の時、グローバル変数errnoに以下の値がセットされます。 EACCESS=指定したアクセス権が許可されていない ENOENT=ファイルが損さしない (errnoを使用するためにはerrno.hが必要) ファイルの存在チェックだけならmacros.hのexist()マクロかstat(2)の方が楽なのではないでしょうか。 #include <sys/types.h> #include <sys/stat.h> int stat(const char *, struct stat *) ; #include <sys/types.h> #include <sys/stat.h> #include <macros.h> int exist(const char *) ; POSIX以外の処理系の場合、OSとコンパイラを指定してください。
その他の回答 (3)
- punchan_jp
- ベストアンサー率55% (155/280)
それから、補足ですが、stat() を使うか、access() を使うかは、 用途が違うと考えてください。「ファイルの存在の有無を確認」の 意味によって、どちらを使うかが決まります。 本当に、存在するかどうかだけで以降の処理が決まるなら、stat() を使うのがいいでしょう。ただし、シンボリックリンクとしてだけ 存在して、その先がなくてもいいなら、lstat() がいいかもしれま せん。 それを読めるかどうか、書けるかどうかが重要な場合は access() を使うべきです。しかし、単に読めるかどうか、書けるかどうかだ けじゃなくてそれがファイルなのか、ディレクトリなのか、シンボ リックリンクなのか、といった様々な可能性もチェックして正しい 処理をしたいという場合には、stat(), lstat() も併用する必要が あります。 さらに、stat() してから、次のアクションを起こすまでに、誰か がファイルを消したり、パーミションを落としたりしたら、どうし たらいいかまで考えはじめると、きりがないですが…。
- punchan_jp
- ベストアンサー率55% (155/280)
stat() や access() 等のUNIXのシステムコール関数は、通常 man に必要十分な情報が載っています。 man 2 stat man 2 access 等、されてみたでしょうか?英語であったとしても、難しい文法は 使っていませんので、すぐに慣れると思います。OSによっては、日 本語のマニュアルが用意されている場合もありますが、かえってわ かりにくいこともあるので、原文を参照する習慣をつけるのがいい です。 例えば、FreeBSDの man によると、stat() の RETURN VALUES は、 Upon successful completion a value of 0 is returned. Otherwise, a value of -1 is returned and errno is set to indicate the error. ですので、「stat() が成功したとき(ファイルの属性が得られた とき)に 0 を返し、それ以外では -1 を返して errno に値がセッ トされる」という意味になります。どういうときに属性が得られな いことがあるかというと、ERRORS の項を見ると、パスの途中にディ レクトリでないものがあった、とか、名前が長すぎる、とか、ファ イルが存在しない、とか、途中のディレクトリにアクセス許可がな かった、とか、などなどです。 access() に関しても同様ですが、これの主な用途は、自分にとっ てそのファイルが本当に読み書きできるかを調べるものですので、 可能なら 0 を返し、そうでなければ -1 を返します。ERRORS に関 しては似たようなものですが、-1 を返すかどうかは、どういうモー ドでのアクセス可能性を問い合わせたかによって変化します。その 意味では、単にファイルのモード等を取り出すだけの stat() とは 異なります。また、access() では、ファイルシステムが readonly のときに、書き込みができないこともチェックできます。(EROFS がセットされる) MSDNというのがマイクロソフトのサービスのことだとすれば、UNIX に関する情報はあんまり期待できないのではないかと思いますが、 試したことがないのでわかりません。 errno を知りたければ、/usr/include/sys/errno.h を見るのはい かがですか?ただし、各システムコールで、異なるエラーを同じ errno で表現したりもしますから、結局 man を見て errno ごとの 意味を読み取るのが正確ですが。 manだけでは不安とか実例がいっぱい欲しいという場合には、書籍 もありますので、「UNIX システムコール プログラミング」などを キーワードにして、検索してみてください。
お礼
とてもためになるお話をありがとうございます。おかげさまで自由に使えるくらいの知識ができたと思います。 書籍の件でもUNIXと聞いて、はっとしました。そういう本を探したことがありませんでした。そういえば他の方で書籍についての質問をしていた方がいましたので、そこを見れば非常に興味深い回答がありました。 それにしてもある程度Cができるようになったらその先はまずUNIXを学ばねばならないのでしょうか? その辺に関わることをまた別の質問をしたいと思いますのでお暇がありましたらどうかよろしくお願いします。 では、回答をくださったおふた方様、ありがとうございました。
- toysmith
- ベストアンサー率37% (570/1525)
実は数日前にOSをクリーンインストールしてまして、GCC(Cygnus GNU Win32ですが)が入ってないんです。 すみません、GCCについてはちょっと時間がかかりますので他の方の回答が早いかもしれません。 POSIXを想定してたのでmacros.hを持ち出したのですが、ANSI標準ではないので他の処理系では存在しないかもしれません。 access()の関数値は 0=処理が正常に終了 -1=失敗 です。 第2引数が0の場合関数値が0なら「ファイルは存在する」なのですが、-1であっても「存在しない」とは限りません。 そこで、errnoで詳細を確認する必要が出てくるのです。 代表的な例としてはEINTRで、「割り込み発生」を示します。 この場合はファイルは存在します。 stat()の第2引数には常にstruct statのアドレスを渡します。 struct stat st ; if (stat("c:\\xxx.dat", &st) == -1) { switch (errno) { case ENOENT :/* ファイル無し */ case EINTR : /* 割り込み発生(正常) */ default : /* その他のエラー */ perror("c:\\xxx.dat") ; } } このような使い方になります。 なぜ、access()よりstat()をお勧めするかと言うと…。 access()の第2引数は処理系依存だからです。 MSDNでも_access()となっており互換性はWin95/NTです。
補足
本当にありがとうございます。おかげさまでファイルの存在チェックがだいたいマスターできました。 最後に少々お聞きしたいのですが、 stat関数の関数値とaccess関数の関数値は同じ意味であると解釈してもいいのでしょうか? それと、どのような本を探せばこのような内容が説明してあるのでしょうか?このような内容や、errnoの全ての値の意味などを勉強してみたいと思うのですが、探し方が悪いのか、それとも住んでる所が田舎すぎるのか、sys内のヘッダファイルを使うような本を見たことがありません。 それともこれらの事はmanやMSDNで調べるべきなのでしょうか?
補足
さっそくのご回答ありがとうございます。 さっそくWindows98のVisualC++と VineLinuxとFreeBSDのgccで試してみました。 VCではio.hが存在したのですがgccでは存在しませんでした。又、macros.hはどちらにも存在しませんでした。 そこで、申し訳ないのですが、再び教えていただけないでしょうか? VCでaccess関数を使ってみたのですが、戻り値が何を意味してるかがわかりません。 0と-1だけを返してるように見えますが、 0なら「O.Kです」、-1なら「ダメです」、というような解釈をしていいのでしょうか? それとstat関数ですが、ファイルの存在チェックをする場合、 第2引数には何を与えればいいのでしょうか? ちなみにVCのstat.h中の構造体statは以下のようになっています。 struct stat { _dev_t st_dev; _ino_t st_ino; unsigned short st_mode; short st_nlink; short st_uid; short st_gid; _dev_t st_rdev; _off_t st_size; time_t st_atime; time_t st_mtime; time_t st_ctime; };