GNU/Linux >> Linux の 問題 >  >> Linux

ハウツー:Linux でのディレクトリを使用した C プログラミング

Linux ではすべてがファイルであると言われますが、それは本当のことです。ファイルに対して実行できる操作のほとんどは、ソケット、パイプ、ディレクトリなどの他のエンティティに対して実行できます。

ソフトウェア ユーティリティが Linux システムのディレクトリ間を移動しなければならない場合があります。何かを見つけたり一致させたりする。これは、そのユーティリティのプログラマがディレクトリ プログラミングを処理しなければならないユース ケースです。そのため、この記事では、ディレクトリ プログラミングの次の基本について、例を挙げて説明します。

<オール>
  • ディレクトリの作成
  • ディレクトリを読む
  • ディレクトリを削除しています。
  • ディレクトリを閉じる
  • 現在の作業ディレクトリを取得しています。
  • 上記の各ステップで使用される関数を見ていき、最後に、すべてのディレクトリ操作を要約する例を見ていきます.

    1.ディレクトリの作成

    Linux システムは、ディレクトリを作成するために次のシステム コールを提供します:

    #include <sys/stat.h>
    #include <sys/types.h>
    int mkdir(const char *pathname, mode_t mode);

    「パス名」引数は、ディレクトリの名前に使用されます。

    マニュアルページから:

    <ブロック引用>

    引数モードは、使用するパーミッションを指定します。通常の方法で、プロセスの umask によって変更されます。作成されたディレクトリのパーミッションは (mode &~umask &0777) です。作成されるディレクトリのその他のモード ビットは、オペレーティング システムによって異なります。 Linux については、以下を参照してください。

    新しく作成されたディレクトリーは、プロセスの実効ユーザー ID によって所有されます。ファイルを含むディレクトリに set-group-ID ビットが設定されている場合、またはファイル システムが BSD グループ セマンティクス (mount -o bsdgroups または同義の mount -o grpid) でマウントされている場合、新しいディレクトリはグループ所有権をその親;それ以外の場合は、プロセスの実効グループ ID によって所有されます。親ディレクトリに set-group-ID ビットが設定されている場合、新しく作成されたディレクトリも設定されます。

    2.ディレクトリを読む

    ディレクトリの内容を読み取るために、一連の関数が使用されます。

    1. まず、ディレクトリ ストリームを開く必要があります。これは、次のシステム コールによって行われます:

    #include <sys/types.h>
    #include <dirent.h>
    DIR *opendir(const char *name);

    マニュアルページから:

    <ブロック引用>

    opendir() 関数は、ディレクトリ名に対応するディレクトリ ストリームを開き、ディレクトリ ストリームへのポインタを返します。ストリームは、ディレクトリの最初のエントリに配置されます。

    2. 次に、ディレクトリ内のエントリを読み取るために、上記の開かれたストリームが次のシステム コールによって使用されます。

    #include
    struct dirent *readdir(DIR *dirp);

    マニュアルページから:

    <ブロック引用>

    readdir() 関数は、dirp が指すディレクトリ ストリーム内の次のディレクトリ エントリを表す dirent 構造体へのポインタを返します。ディレクトリ ストリームの最後に到達した場合、またはエラーが発生した場合は、NULL を返します。

    Linux では、dirent 構造は次のように定義されます:

    struct dirent
    {
        ino_t          d_ino;       /* inode number */
        off_t          d_off;       /* offset to the next dirent */
        unsigned short d_reclen;    /* length of this record */
        unsigned char  d_type;      /* type of file; not supported
                                       by all file system types */
        char           d_name[256]; /* filename */
    };

    3.ディレクトリの削除

    Linux システムは、ディレクトリを削除する次のシステム コールを提供します:

    #include <unistd.h>
    int rmdir(const char *pathname);

    マニュアルページから:

    <ブロック引用>

    rmdir() は、'pathname' が表すディレクトリが空の場合、そのディレクトリを削除します。ディレクトリが空でない場合、この関数は成功しません。

    4.ディレクトリを閉じる

    Linux システムは、ディレクトリを閉じるために次のシステム コールを提供します:

    #include <sys/types.h>
    #include <dirent.h>
    int closedir(DIR *dirp);

    マニュアルページから:

    <ブロック引用>

    closedir() 関数は、dirp に関連付けられたディレクトリ ストリームを閉じます。また、closedir() の呼び出しが成功すると、dirp に関連付けられた基になるファイル記述子も閉じられます。この呼び出しの後、ディレクトリ ストリーム記述子 dirp は使用できません。

    5.現在の作業ディレクトリの取得

    Linux システムは、CWD を取得するために次のシステム コールを提供します:

    #include <unistd.h>
    char *getcwd(char *buf, size_t size);

    マニュアルページから:

    <ブロック引用>

    getcwd() 関数は、現在の作業ディレクトリの絶対パス名を、長さ size の buf が指す配列にコピーします。この関数は、絶対パス名を含む null で終わる文字列を返します。呼び出しプロセス。パス名は、関数の結果として返され、存在する場合は引数 buf を介して返されます。現在の作業ディレクトリの絶対パス名の長さが、終端の null バイトを含めて size バイトを超える場合、NULL が返され、errno が ERANGE に設定されます。アプリケーションはこのエラーをチェックし、必要に応じてより大きなバッファーを割り当てる必要があります。

    6.例

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<dirent.h>
    #include <sys/stat.h>
    #include <sys/types.h>
    #include <unistd.h>
    
    int main (int argc, char *argv[])
    {
        if(2 != argc)
        {
            printf("\n Please pass in the directory name \n");
            return 1;
        }
    
        DIR *dp = NULL;
        struct dirent *dptr = NULL;
        // Buffer for storing the directory path
        char buff[128];
        memset(buff,0,sizeof(buff));
    
        //copy the path set by the user
        strcpy(buff,argv[1]);
    
        // Open the directory stream
        if(NULL == (dp = opendir(argv[1])) )
        {
            printf("\n Cannot open Input directory [%s]\n",argv[1]);
            exit(1);
        }
        else
        {
            // Check if user supplied '/' at the end of directory name.
            // Based on it create a buffer containing path to new directory name 'newDir'
            if(buff[strlen(buff)-1]=='/')
            {
                strncpy(buff+strlen(buff),"newDir/",7);
            }
            else
            {
                strncpy(buff+strlen(buff),"/newDir/",8);
            }
    
            printf("\n Creating a new directory [%s]\n",buff);
            // create a new directory
            mkdir(buff,S_IRWXU|S_IRWXG|S_IRWXO);
            printf("\n The contents of directory [%s] are as follows \n",argv[1]);
            // Read the directory contents
            while(NULL != (dptr = readdir(dp)) )
            {
                printf(" [%s] ",dptr->d_name);
            }
            // Close the directory stream
            closedir(dp);
            // Remove the new directory created by us
            rmdir(buff);
            printf("\n");
        }
    
        return 0;
    }

    上記の例は自明です。

    上記の例の出力は次のとおりです:

    # ./direntry /home/himanshu/practice/linux
    
     Creating a new directory [/home/himanshu/practice/linux/newDir/]
    
     The contents of directory [/home/himanshu/practice/linux] are as follows
     [redhat]  [newDir]  [linuxKernel]  [..]  [ubuntu]  [.]

    Linux
    1. procps-ngを使用してターミナルでLinuxシステムを監視します

    2. noatimeでLinuxシステムのパフォーマンスを向上させる

    3. Linuxシャットダウンコマンド(例付き)

    1. Linuxでのディレクトリの作成、削除、および管理

    2. LinuxでのCronを使用したシステムタスクのスケジューリング

    3. Linuxでディレクトリの名前を変更する方法

    1. straceを使用したLinuxでのシステムコールの理解

    2. Howto:Linux での一時ファイルを使用した C プログラミング

    3. Linux でのファイル/ディレクトリの最大数は?