我正在尝试理解该stat命令的stat结构的st_mode字段的标志,但是我有这么难的时间!我找到了这个例子here,但我真的不明白这个代码片段:
if ( mode & S_IRUSR ) str[1] = 'r'; /* 3 bits for user */
if ( mode & S_IWUSR ) str[2] = 'w';
if ( mode & S_IXUSR ) str[3] = 'x';
if ( mode & S_IRGRP ) str[4] = 'r'; /* 3 bits for group */
if ( mode & S_IWGRP ) str[5] = 'w';
if ( mode & S_IXGRP ) str[6] = 'x';
if ( mode & S_IROTH ) str[7] = 'r'; /* 3 bits for other */
if ( mode & S_IWOTH ) str[8] = 'w';
if ( mode & S_IXOTH ) str[9] = 'x';
我知道“&”是按位AND运算符,但没有别的。我甚至不知道该问什么。
PD:对我之前提出的问题感到抱歉。我不知道如何标记回答的问题或类似的问题:(答案 0 :(得分:3)
模式是bitfield,这是打包数据的常用方法。将该字段中的每个位视为切换开关,可将其设置为关闭或打开。要检查切换是否打开,请检查是否已使用&设置了相应的位。运营商。您可以使用|设置位并使用〜bitwise operations清除它们。
答案 1 :(得分:2)
好吧,POSIX spec for <sys/stat.h>
列举了您可以从struct stat
的st_mode字段中学到的所有内容。
您的问题是“这个字段可以告诉我什么”,或者是“我如何提取信息”,或两者兼而有之?
答案 2 :(得分:2)
在操作系统编程中,通常使用无符号整数来保存描述某些内容的一系列位。在这种情况下,模式有9位感兴趣。一位告知所有者是否可以读取,一个用于所有者写入,一个用于所有者执行,以及用于该组和其他的类似位。诀窍是提取是否设置了一个位。
这是一个例子。 S_IRUSR是位掩码的名称,用于描述“所有者读取”位。它在the specs中定义为0400(八进制),转换为二进制的100000000。当您使用掩码获取二进制和此值时,如果设置了掩码的第9位,则获得值100000000(二进制)。否则你会得到0。
如果返回大值,则if语句的计算结果为true,否则返回false。这样,如果该位置位,则将'r'写入字符串到位置1.同样的技术也适用于所有其他位。
答案 3 :(得分:0)
作为一个“新手”,我遇到了这个问题。
我的第一步是'man 2 stat'。(在此之前)
在那里你会找到这段内容丰富的示例代码
EXAMPLE from 'man 2 stat'
The following program calls lstat() and displays selected fields in the returned stat
structure.
#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/sysmacros.h>
int
main(int argc, char *argv[])
{
struct stat sb;
if (argc != 2) {
fprintf(stderr, "Usage: %s <pathname>\n", argv[0]);
exit(EXIT_FAILURE);
}
if (lstat(argv[1], &sb) == -1) {
perror("lstat");
exit(EXIT_FAILURE);
}
printf("ID of containing device: [%lx,%lx]\n",
(long) major(sb.st_dev), (long) minor(sb.st_dev));
printf("File type: ");
switch (sb.st_mode & S_IFMT) {
case S_IFBLK: printf("block device\n"); break;
case S_IFCHR: printf("character device\n"); break;
case S_IFDIR: printf("directory\n"); break;
case S_IFIFO: printf("FIFO/pipe\n"); break;
case S_IFLNK: printf("symlink\n"); break;
case S_IFREG: printf("regular file\n"); break;
case S_IFSOCK: printf("socket\n"); break;
default: printf("unknown?\n"); break;
}
printf("I-node number: %ld\n", (long) sb.st_ino);
printf("Mode: %lo (octal)\n",
(unsigned long) sb.st_mode);
printf("Link count: %ld\n", (long) sb.st_nlink);
printf("Ownership: UID=%ld GID=%ld\n",
(long) sb.st_uid, (long) sb.st_gid);
printf("Preferred I/O block size: %ld bytes\n",
(long) sb.st_blksize);
printf("File size: %lld bytes\n",
(long long) sb.st_size);
printf("Blocks allocated: %lld\n",
(long long) sb.st_blocks);
printf("Last status change: %s", ctime(&sb.st_ctime));
printf("Last file access: %s", ctime(&sb.st_atime));
printf("Last file modification: %s", ctime(&sb.st_mtime));
exit(EXIT_SUCCESS);
}
正如上面其他人所说,这在“switch (sb.st_mode & S_IFMT)”中使用了位掩码。 看来,大部分的管道工作已经为我们完成了。但是,我确实发现在“gcc”下编译时,这些位掩码定义了使用的前导下划线。
我,例如。 '切换(sb.st_mode & __S_IFMT)'
不是很有经验,我猜这个细节可能因版本而异。
我发现这是一个很好的起点(以及 stat 的其他内容) (对于那些在 Linux 的 Windows 子系统上尝试此操作的人的额外观察。您有时可能会得到奇怪的结果!;-))