1. 程式人生 > >(萊昂氏unix原始碼分析導讀-46)許可權、管道

(萊昂氏unix原始碼分析導讀-46)許可權、管道

    by cszhao1980

 1.    檔案與許可權控制

程序u結構中,身份相關的資訊有:

0420: char u_uid; /* effective user id */

0421: char u_gid; /* effective group id */

0422: char u_ruid; /* real user id */

0423: char u_rgid; /* real group id */

如果程序為超級使用者,則u_uid 0。函式suser()執行檢查,如果為超級使用者則返回1

inode結構中,記錄了檔案的所屬關係:

5609: char i_uid;

5610: char i_gid;

如果程序的u_uid等於檔案inodei_uid,則表示該程序擁有此檔案——超級使用者是例外,

超級使用者擁有任何檔案。函式owner()執行此項檢查,如果擁有此檔案,則返回檔案inode

否則,返回NULL

熟悉unix的同學應該都知道,unix檔案的許可權控制是在兩個維度上進行的:

(1)         檔案許可權有三種:ReadwriteExec

(2)         不同使用者所允許的許可權不同,具體來說:

1)   檔案owner(包括超級使用者);

2)   group

3)   其他。

檔案的許可權資訊記錄在(indoe的)i_mode變數的低9bit中,每3 bit

1組,分為三組:

(1)         8~6:用於檔案owner

(2)         5~3:用於同group

(3)         2~0:用於其他使用者

在這3 bit之中,最高bitRead許可權標誌、中bitwrite許可權標誌、低bitExec許可權標誌。

access()函式用於進行許可權檢查,萊昂有詳細的介紹,在此不再贅述。

 2.    管道

管道是一種特殊的檔案,用於unix的程序間通訊。

管道均為“小”檔案,即小於4096個位元組,如下所示:

#define PIPSIZ 4096

sys call pipe()用於生成管道,從程式碼可以看到,管道最大的特點是它擁有兩個file

陣列項——分

別用於readwrite,正因如此ip->i_count也被初始化為2。該函式需要注意的是其對R0R1

設定——如前面所述,falloc()會隱含的設定R0

首先,看一下管道寫函式writep(fp),其引數為file陣列指標,指向該管道的“寫”file entry

(1)         plock鎖定inode,因此,管道的讀、寫是互斥的,同一時間僅有一種操作可行;

(2)         檢查管道的i_count,如<2證明Read已關閉,則管道的“寫”功能也無意義,故error,併發訊號;

(3)         管道最大為PIPSIZ個位元組,在“寫”時需要注意:

i.       ip->i_size1 == PIPSIZ,管道已寫“滿”,故睡眠;

ii.     7844 ~ 7847計算所能寫的byte數,和剩餘位元組數;

(4)         7850 ~ 7853:喚醒因“讀完”而等待的程序。

readp(fp)是管道讀函式,與寫函式的實現互相呼應,需要注意的是:

(1)         其引數為指向該管道的“寫”file entry的指標:

(2)         7772行表示,已經讀“完”了管道的內容——會清空管道;

除了這幾個函式之外,還有一些函式對管道(FPIPE)有特殊的處理,如rdwrclosef等,

由於其實現比較簡單,就請讀者自行檢視吧。

【思考題】:是解決EXEC sys call的時候了,相信您已經儲備了足夠的知識,這個任務就交給您了。