简体   繁体   中英

bitwise OR in linux open flags

In the linux open system call, what is the meaning of bitwise OR in flags. How this is interpreted by the compiler. Here's an example:

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

Also, what does comma operator do in flags?

Update: What is the effect of using other operators like if we do && operator

How this is interpreted by the compiler

Not differently than any other bitwise OR operation. Consider the following #define s as found for example in /usr/include/asm-generic/fcntl.h (note that values are in octal):

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

Then, in your example, the value passed to the function is 00000000 | 00000100 | 00001000 00000000 | 00000100 | 00001000 00000000 | 00000100 | 00001000 which is 00001100 . By evaluating the various bit positions, open() can reconstruct which of the flags had been set by the caller:

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

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

The bitwise OR is applying a logical OR to the specified values. The flags are defined as a bitmask or individual bits, and with the OR operation you can set the specified bits in the target, without changing other bits.

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

So what happens in this call is that all the flags that you specified are set in the resulting value and passed to the function

#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

So the compiler passes 0x0300 to the open call.

As to your second question:

The open call is defined as int open(const char *pathname, int flags, mode_t mode);

So the comma is simply separating the individual arguments and is not part of the flags. Just like in any other function call.

This is the prototype of the function:

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

This is the way you are calling it:

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

So you are passing the following arguments:

  • pathname = "myfile"
  • flags = O_RDONLY | O_CREAT | O_TRUNC
  • mode = S_IRUSR (user has read permission)

The argument flags must include exactly one of the following access modes: O_RDONLY or O_WRONLY or O_RDWR . These requests will open the file read-only or write-only or read/write, respectively.

When combined with O_CREAT , if the file does not exist then it will be created.

When combined with O_TRUNC , if the file already exists and is a regular file and the open mode allows writing (ie, is O_RDWR or O_WRONLY ) then it will be truncated to length 0.

Please note that the (undefined) effect of O_RDONLY | O_TRUNC O_RDONLY | O_TRUNC varies among implementations. On many systems the file is actually truncated.

Update:

These flags are typically meant to be used only with the bit-wise OR operator ( | ).

If you want to use all possible flags except for a few, then you can use the bit-wise FLIP operator ( ~ ). For example: ~(O_RDONLY | O_CREAT | O_TRUNC) ... but don't try this one in specific at home...

It is pretty pointless to use any other bit-wise operator in this case, and it is most certainly pointless to use any other non-bit-wise operator , such as logical AND ( && ).

Also, what does comma operator do in flags?

It is the third argument mode to the open call.

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

what is the meaning of bitwise OR in flags

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

A combination of these macros would set different bits, in the flags variable, based on which the open call proceeds.

open function call takes 1 argument as file path and second argument for flags,

arguments are comma seperated,

BITWISE OR on flags enables the corresponding bits of that number accordingly.

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

The flags O_RDONLY , O_CREAT are just numbers having a particular bit as 1 . So you can say that their values are in power of 2 . I dont know their exact value but let me give you example of permissions.

There are three settings for permission READ , WRITE and EXECUTE . Read has value 4 , 100 in binary. Similarly WRITE has value 2 , 010 in binary and EXECUTE has value 1 , 001 in binary.

When you want to set a particular setting, you OR it with zero, so that particular bit becomes 1 . So i th bit is reserved for only one particular setting. The function just find which bits are set and works according to that.

If READ and WRITE are set, it means 100 | 010 = 110 , 6 in decimal If all settings are give, it means 111, ie 7 in decimal.

Hence difference flag values corresponds to different combinations of settings.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM