(莱昂氏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等于文件inode的i_uid,則表示該進程擁有此文件——超級用戶是例外,
超級用戶擁有任何文件。函數owner()執行此項檢查,如果擁有此文件,則返回文件inode,
否則,返回NULL。
?
熟悉unix的同學應該都知道,unix文件的權限控制是在兩個維度上進行的:
(1)???????? 文件權限有三種:Read、write和Exec
(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之中,最高bit為Read權限標志、中bit為write權限標志、低bit為Exec權限標志。
access()函數用于進行權限檢查,萊昂有詳細的介紹,在此不再贅述。
?2.??? 管道
管道是一種特殊的文件,用于unix的進程間通訊。
?
管道均為“小”文件,即小于4096個字節,如下所示:
#define PIPSIZ 4096
?
sys call pipe()用于生成管道,從代碼可以看到,管道最大的特點是它擁有兩個file數組項——分
別用于read和write,正因如此ip->i_count也被初始化為2。該函數需要注意的是其對R0、R1的
設置——如前面所述,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)有特殊的處理,如rdwr、closef等,
由于其實現比較簡單,就請讀者自行查看吧。
?
【思考題】:是解決EXEC sys call的時候了,相信您已經儲備了足夠的知識,這個任務就交給您了。
?
博客地址:http://blog.csdn.net/cszhao1980
博客專欄地址:http://blog.csdn.net/column/details/lions-unix.html
?
轉載于:https://www.cnblogs.com/snake-hand/archive/2013/06/16/3138711.html
總結
以上是生活随笔為你收集整理的(莱昂氏unix源代码分析导读-46)权限、管道的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java解析HTML
- 下一篇: std::string 用法