web-dev-qa-db-ja.com

`S_ISREG()`とは何ですか?それは何をしますか?

ファイル属性を取得するCプログラムでマクロS_ISREG()に出会いました。残念ながら、このマクロに関する基本的な情報はオンラインにありません。いくつかのより高度な議論がありますが、彼らは私が探しているものを超えています。

S_ISREG()とは何ですか?ファイル属性を取得するプログラムのコンテキストでは、それはどのような目的を果たし、正確に何をしますか?

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

14
The Pointer

S_ISREG()は、システムコールstat()から返されるstat-structの値を解釈するために使用されるマクロです。引数(struct statのst_modeメンバー)が通常のファイルである場合、trueと評価されます。

詳細については、man statまたはman fstatを参照してください。 manページの関連部分は次のとおりです。

   Because tests of the above form are common, additional macros are defined by POSIX to allow the test of the file type in st_mode to be written more concisely:

       S_ISREG(m)  is it a regular file?

       S_ISDIR(m)  directory?

       S_ISCHR(m)  character device?

       S_ISBLK(m)  block device?

       S_ISFIFO(m) FIFO (named pipe)?

       S_ISLNK(m)  symbolic link?  (Not in POSIX.1-1996.)

       S_ISSOCK(m) socket?  (Not in POSIX.1-1996.)

   The preceding code snippet could thus be rewritten as:

       stat(pathname, &sb);
       if (S_ISREG(sb.st_mode)) {
           /* Handle regular file */
       }
22
Bjorn A.

S_ISREGを定義するPOSIX標準は、実際にはオンラインです。

http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_stat.h.html

見積もり:

ファイルが指定されたタイプであるかどうかをテストするために、次のマクロが提供されます。マクロに提供される値mは、stat構造体からのst_modeの値です。テストが真の場合、マクロはゼロ以外の値に評価されます。テストが偽の場合は0。

[...]

S_ISFIFO(m

パイプまたはFIFO特殊ファイルをテストします。

S_ISREG(m

通常のファイルをテストします。

S_ISLNK(m

シンボリックリンクをテストします。

[...]

S_ISREGを使用する一般的な方法は、最初にstat関数を呼び出して、struct statオブジェクトにファイルに関する情報を入力することです。次に、この構造体のst_modeメンバーの値(整数型)をこのマクロでテストできます。

標準に加えて、さまざまなシステムのオンラインのmanページと、statを使用したプログラミングに関するチュートリアルがあります。ウィキペディアには statのページ があり、明らかに完全なコード例があります。 S_ISREGを備えていませんが、簡単に操作できます。

4
Kaz

stat()関数を使用して取得したstat構造体のst_modeメンバーをテストして、ファイルが通常のファイル(つまり、ディスクまたは大容量ストレージ上にあるかどうか)ディレクトリ、ソケット、シンボリックリンクなど。

struct stat sb;
if( stat( file_path, &sb) != -1) // Check the return value of stat
{
    if( S_ISREG( sb.st_mode ) != 0 )
    {
        printf( "%s is a file", file_path ) ;
    }
    else
    {
        printf( "%s is not a file", file_path ) ;
    }
}

st_modeメンバーには、S_IFMT(0170000)でマスクされた4ビットが含まれます。これらのビットの値は次のとおりです。

       S_IFSOCK   0140000   socket
       S_IFLNK    0120000   symbolic link
       S_IFREG    0100000   regular file
       S_IFBLK    0060000   block device
       S_IFDIR    0040000   directory
       S_IFCHR    0020000   character device
       S_IFIFO    0010000   FIFO

したがって、マクロS_ISREGは次のように定義されます。

#define S_ISREG( m ) (((m) & S_IFMT) == S_IFREG)

これはマクロなので、ヘッダーファイルsys/stat.hで実際の定義を確認できます。 GNUヘッダーでは、次のように定義されています。

#define __S_ISTYPE(mode, mask)  (((mode) & __S_IFMT) == (mask))
...
#define S_ISREG(mode)    __S_ISTYPE((mode), __S_IFREG)

これは私の簡易版でも基本的に同じです。

4
Clifford