我有一个简单的程序,它打印路径名参数是否是目录、具有执行权限的常规文件、常规文件、符号链接或其他。
我有以下 if 语句来确定这一点(mode_t 模式源自 struct stat):
if (mode & S_IFDIR){
mode_s[n] = 'd';
} else if (is_user_exec(mode, ouid, ogid) && (mode & S_IFREG)){
mode_s[n] = 'e';
}else if (mode & S_IFREG){
mode_s[n] = 'f';
} else if (mode & S_IFLNK){
mode_s[n] = 'l';
} else {
mode_s[n] = 'o';
}
前三个都运行良好,但是当我传递应该分类为“o”的内容时,它会将其列为“l”。
谁能弄清楚为什么我的代码会导致这个问题?
仅供参考,我正在 MINIX 3.2.1 上编译并运行该程序,有问题的麻烦路径名是 /dev/ptyp8
答案1
虽然我没有可用的 MINIX 系统,但我确信问题是“模式”没有针对各种文件类型的不同位。您应该使用类似的宏S_ISDIR
而不是比较S_IFDIR
(S
而不是F
)。这是 GNU C 库。
以下是 Linux 机器上的旧版本。前导0
意味着这些值是八进制的。
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#define S_IFMT 00170000
#define S_IFSOCK 0140000
#define S_IFLNK 0120000
#define S_IFREG 0100000
#define S_IFBLK 0060000
#define S_IFDIR 0040000
#define S_IFCHR 0020000
因此,您的代码正在测试 (mode & 0120000) 是否非零,如果设置了 0100000 或 020000 位,则该位将用于 S_IFSOCK、S_IFLNK、S_IFREG、S_IFBLK 和 S_IFCHR 。您的 pt 类型将为 S_IFCHR。