【问题标题】:bitwise OR in linux open flagslinux打开标志中的按位或
【发布时间】:2014-02-25 08:15:01
【问题描述】:

在linux的open系统调用中,flags中的bitwise OR是什么意思。编译器如何解释它。这是一个例子:

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

另外,逗号运算符在标志中的作用是什么?

更新:如果我们使用&&运算符,使用其他运算符会有什么影响

【问题讨论】:

  • 这不是逗号运算符 - 它是分隔标志参数和模式参数的逗号。
  • 您的问题在这里得到了详细解答:man7.org/linux/man-pages/man2/open.2.html
  • 我在手册页中看到,它结合了所有标志。但我不明白怎么做?因为如果它结合然后它产生一个int值,那么编译器是如何理解的

标签: c linux


【解决方案1】:

编译器是如何解释的

与任何其他按位或运算没有什么不同。考虑以下#defines,例如在/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 */
}
...

【讨论】:

    【解决方案2】:

    按位或对指定值应用逻辑或。标志被定义为位掩码或单个位,通过 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 调用。

    关于你的第二个问题:

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

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

    【讨论】:

      【解决方案3】:

      这是函数的原型:

      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 的(未定义)效果因实现而异。在许多系统上,文件实际上被截断了。

      更新:

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

      如果您想使用除少数之外的所有可能的标志,那么您可以使用按位翻转运算符 (~)。例如:~(O_RDONLY | O_CREAT | O_TRUNC)...但不要在家里专门尝试这个...

      在这种情况下使用任何其他按位运算符毫无意义,使用任何其他非按位运算符肯定毫无意义,例如逻辑与(@987654338 @)。

      【讨论】:

        【解决方案4】:
        Also, what does comma operator do in flags?
        

        这是open 调用的第三个参数模式。

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

        flags中按位或的含义是什么

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

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

        【讨论】:

          【解决方案5】:

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

          权限有READWRITEEXECUTE三种设置。读取具有二进制值 4100 。类似地,WRITE 具有二进制值 2010EXECUTE 具有二进制值 1001

          当您想要设置特定设置时,您将OR 设为零,因此特定位变为1。所以 ith 位只保留给一个特定的设置。该函数只是查找设置了哪些位并根据该位工作。

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

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

          【讨论】:

            【解决方案6】:

            open 函数调用将 1 个参数作为文件路径,第二个参数作为标志,

            参数以逗号分隔,

            标志上的 BITWISE OR 相应地启用该数字的相应位。

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

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2016-11-26
              • 2013-05-12
              • 2012-10-19
              • 1970-01-01
              • 1970-01-01
              • 2020-03-27
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多