ファイル・ディレクトリ [Linux]

ファイルは 「内容」 + 「名前」 + 「管理情報」 で構成される。「管理情報」 はファイルシステム内の i ノードと呼ばれるデータブロックに格納 される。

デバイスファイル

  • /dev/console  -  システムのコンソールを表す
  • /dev/tty  -  プロセスが制御端末を持っている場合の制御端末のエイリアス
  • /dev/null  -  ヌルデバイス

資料 [1] にはおよそ上記のように説明がありました。制御端末の話題を考えるときに、Windows ではウィンドウステーションを忘れてはなりません。WinSta0 というウィンドウステーションに作成されたプロセスのみがコンソールとの対話を許可されるからです。しかし、[1] をざっと見る限りウィンドウステーションという概念自体 Linux にはないのかもしれません。(そもそもウィンドウハンドルなんてものも無いのでしょうね)

システムコール

  • open
  • read
  • write
  • close
  • ioctl
ファイルディスクリプタ
  • 0 - 標準入力
  • 1 - 標準出力
  • 2 - 標準エラー
ディレクトリ

opendir でディレクトリをオープンし、そのディレクトリの情報を readdir で読む。プロトタイプは以下:

DIR *opendir (const char *);

struct dirent *readdir (DIR *);

特定のディレクトリ内のファイル・ディレクトリを列挙するには次のようにする。

#include <unistd.h>
#include <dirent.h>
#include <sys/stat.h>

int main () {

    DIR* pDir;
    struct dirent* pDirEnt = NULL;
    struct stat StatBuf;
   
    pDir = opendir ( "/home/user1" );

    if ( !pDir ) {
        printf ("Failed to open the directory.\n");
        return 1;
    }

    while ( (pDirEnt = readdir ( pDir )) != NULL ) {

        memset ( &StatBuf, 0, sizeof (StatBuf) );

        lstat ( pDirEnt->d_name, &StatBuf );

        if ( StatBuf.st_mode & S_IFDIR ) {
            printf ("[%s]\n", pDirEnt->d_name );
        }
        else {
            printf ( "%s\n", pDirEnt->d_name );
        }

    }
    
    closedir ( pDir );

    return 0;
}

ただし、ここでは lstat の戻り値をチェックしていないがこれはするべき。Windows 上で実行すると上記のコードでは lstat が失敗するためディレクトリであるかファイルであるか判定できなかった。(Windows では FindFirstFile を使い、引数の WIN32_FIND_DATA 型の構造体の dwFileAttributes フラグをチェックする) エラーコードは 2 (No such file or directory) だったので lstat にフルパスを渡したら成功した。この点で Linux 上と Windows 上では動作が異なったので注意するべきだろう。
# 私見としては、DIR * を取得しており呼び出しのコンテキストを把握可能であるのだから、相対パスだけで判別可能な Linux 風の実装の方が良い動きだと思う。

参考資料

[1] ニール・マシュー&リチャード・ストーンズ著 葛西訳 『Linux プログラミング 例題で学ぶ UNIX プログラミング環境のすべて』, SOFTBANK

ここまでお読みいただき、誠にありがとうございます。SNS 等でこの記事をシェアしていただけますと、大変励みになります。どうぞよろしくお願いします。

© 2024 Web/DB プログラミング徹底解説