linux中的按位OR打开标志

时间:2014-02-25 08:15:02

标签: c linux

在linux open系统调用中,flags中按位OR的含义是什么。这是如何由编译器解释的。这是一个例子:

fd = open("myfile", O_RDONLY | O_CREAT | O_TRUNC, S_IRUSR);

另外,逗号运算符在标志中做了什么?

更新:使用其他运营商会产生什么影响,例如&&运营商

6 个答案:

答案 0 :(得分:11)

  

编译器如何解释

与任何其他按位OR运算没有什么不同。考虑以下#define,例如在/usr/include/asm-generic/fcntl.h中找到的(注意值是八进制的):

#define O_RDONLY        00000000
#define O_CREAT         00000100
#define O_TRUNC         00001000

然后,在您的示例中,传递给函数的值为00000000 | 00000100 | 00001000,即 00001100 。通过评估各种位位置,open()可以重建调用者设置的标志:

if (oflag & O_CREAT) {
   /* caller wants the file to be created */
}

if (oflag & O_TRUNC) {
   /* caller wants the file to be truncated */
}
...

答案 1 :(得分:2)

按位OR正在对指定值应用逻辑OR。标志定义为位掩码或单个位,使用OR操作,您可以设置目标中的指定位,而无需更改其他位。

A: 1 1 0 0
B: 1 0 1 0
-----------
 = 1 1 1 0

所以在这个调用中发生的是你指定的所有标志都在结果值中设置并传递给函数

#define _O_RDONLY       0    <- Bit 0
#define _O_WRONLY       1    <- Bit 0
#define _O_RDWR         2    <- Bit 1

#define _O_CREAT    0x0100  /* Create the file if it does not exist. */
#define _O_TRUNC    0x0200  /* Truncate the file if it does exist. */

O_RDONLY | O_CREAT | O_TRUNC = 0x0000 + 0x0100 + 0x0200 = 0x0300

0000 0000 0000 0000 O_RDONLY
0000 0001 0000 0000 O_CREAT
0000 0010 0000 0000 O_TRUNC
---------------------------
0000 0011 0000 0000 = 0x0300

因此编译器将0x0300传递给公开调用。

至于你的第二个问题:

open来电定义为int open(const char *pathname, int flags, mode_t mode);

因此逗号只是将各个参数分开,而不是标志的一部分。就像在任何其他函数调用中一样。

答案 2 :(得分:1)

这是该功能的原型:

int open(const char *pathname, int flags, mode_t mode);

这就是你打电话的方式:

fd = open("myfile", O_RDONLY | O_CREAT | O_TRUNC, S_IRUSR);

所以你传递了以下参数:

  • pathname = "myfile"
  • flags = O_RDONLY | O_CREAT | O_TRUNC
  • mode = S_IRUSR(用户已阅读权限)

参数flags必须包含以下一种以下访问模式:O_RDONLYO_WRONLYO_RDWR。这些请求将分别以只读或只写或读/写方式打开文件。

当与O_CREAT结合使用时,如果该文件不存在,则会创建该文件。

当与O_TRUNC结合使用时,如果文件已存在并且是常规文件且开放模式允许写入(即O_RDWRO_WRONLY),那么它将被截断为长度0。

请注意O_RDONLY | O_TRUNC的(未定义)效果因实现而异。在许多系统上,文件实际上都被截断了。

<强>更新

这些标志通常仅用于按位OR运算符(|)。

如果要使用除少数之外的所有可能标志,则可以使用逐位FLIP运算符(~)。例如:~(O_RDONLY | O_CREAT | O_TRUNC) ...但不要在家中具体尝试这个......

在这种情况下使用任何其他按位运算符是毫无意义的,使用任何其他非按位运算符绝对没有意义,例如逻辑AND({{ 1}})。

答案 3 :(得分:0)

Also, what does comma operator do in flags?

这是open电话的第三种参数模式。

int open(const char *pathname, int flags, mode_t mode);

标志中按位OR的含义是什么

#define O_RDONLY             00
#define O_CREAT            0100 
#define O_TRUNC           01000 

这些宏的组合将在flags变量中设置不同的位,基于打开的调用继续进行。

答案 4 :(得分:0)

open function call将1个参数作为文件路径,将第二个参数作为flags,

参数是逗号分隔的,

BITWISE OR on flags会相应地启用该数字的相应位。

http://linux.die.net/man/3/open

答案 5 :(得分:0)

标志O_RDONLYO_CREAT只是具有特定位1的数字。所以你可以说他们的价值是2的力量。我不知道他们的确切价值,但让我举几个权限的例子。

权限READWRITEEXECUTE有三种设置。读取的值为4100为二进制。同样,WRITE的值为2010为二进制,EXECUTE的值为1001为二进制。

如果要设置特定设置,则OR为零,以使特定位变为1。所以我 th 位只保留一个特定的设置。该函数只是找到哪些位被设置并根据它工作。

如果设置了READWRITE,则表示100 | 010 = 110,小数点后6位 如果给出所有设置,则表示111,即十进制的7。

因此,差异标记值对应于不同的设置组合。