2014-02-25 39 views
1

在linux open系統調用中,標誌中按位OR的含義是什麼。這是如何被編譯器解釋的。下面是一個例子:按位OR在linux中打開標誌

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

此外,逗號運算符在標誌中做什麼?

更新:一樣,如果我們做&&操作

+5

這不是一個逗號運算符 - 它是一個逗號,將flags參數與mode參數分開。 –

+3

而你的問題在這裏得到了詳細的回答:http://man7.org/linux/man-pages/man2/open.2.html –

+0

我在手冊頁中看到,它結合了所有的標誌。但我不明白如何?因爲如果它合併,那麼它會產生一個int值,那麼編譯器如何理解 –

回答

5

什麼是使用其他運營商的效果如何,這是由編譯器解釋

不不同於任何其他位或操作。考慮以下#define S作爲在/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 */ 
} 
... 
0
Also, what does comma operator do in flags? 

這是第三個參數模式爲open通話。

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

什麼是按位的意義或標誌

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

這些宏的組合將基於其開放的呼叫進行設置不同的位,可變標誌。

0

開放函數調用需要1個參數作爲文件的路徑和用於標誌的第二個參數,

參數被逗號分隔,

位或上的標誌使相應該號碼的相應位。

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

0

這是函數的原型:

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

按位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);

所以逗號分隔只是個別參數,而不是標誌的一部分。就像在其他任何函數調用中一樣。

0

標誌O_RDONLYO_CREAT只是具有特定位的數字,如1。所以你可以說他們的價值在於2的力量。我不知道他們的確切價值,但讓我給你舉例說明權限。

有三個權限設置READ,WRITEEXECUTE。讀值爲二進制值4,100。類似地,WRITE具有二進制值2,010以及二進制值EXECUTE具有值1,001

當你想設置一個特定的設置,你OR它與零,使特定的位變成1。所以我位是隻保留一個特定的設置。該功能只是找到哪些位被設置並根據該功能工作。

如果設置READWRITE,則表示100 | 010 = 110,6十進制 如果給出所有設置,則表示111,即十進制的7。

因此差異標誌值對應於不同的設置組合。