国产激情自拍_国产9色视频_丁香花在线电影小说观看 _久久久久国产精品嫩草影院

首頁 > 系統 > Unix > 正文

UNIX高級環境編程(4)Files And Directories

2024-06-28 13:21:48
字體:
來源:轉載
供稿:網友
UNIX高級環境編程(4)Files And Directories - umask、chmod、文件系統組織結構和鏈接

本篇主要介紹文件和文件系統中常用的一些函數,文件系統的組織結構和硬鏈接、符號鏈接。

通過對這些知識的了解,可以對linux文件系統有更為全面的了解。

?

1 umask函數

之前我們已經了解了每個文件與權限相關的9個位(bit),我們現在來了解一下當每個進程創建文件時默認會設置該文件的文件權限(the file mode creation mask)。

umask函數設置該進程默認創建文件的權限掩碼(the file mode creation mask),并且返回之前的權限掩碼值。

#include <sys/stat.h>

mode_t umask(mode_t cmask);

the file mode creation mask的作用:當進程創建新文件時,會根據這個掩碼值創建文件,在掩碼值中打開的位,對應的新文件的權限位會被關閉。

umask的功能簡單地說就是創建新文件時屏蔽掉用戶不希望生效的權限位。

Example:

#include "apue.h"

#include <fcntl.h>

?

#define RWRWRW (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)

?

int

main(void)

{

? ? umask(0);

? ? if (creat("foo", RWRWRW) < 0)

? ? ? ? err_sys("creat error for foo");

? ? umask(S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);

? ? if (creat("bar", RWRWRW) < 0)

? ? ? ? err_sys("creat error for bar");

? ? exit(0);

}

運行截圖:

NewImage

結果說明:

shell的umask命令顯示當前文件創建權限掩碼。

0022表示創建出來的新文件,組用戶和other用戶沒有寫該文件的權限。

在程序中,首先用默認的權限設置創建了文件foo,它的權限位666,至于為什么當前用戶也沒有執行權限,我還沒搞清楚,留一個坑 @suzhou。

然后修改umask值為0077,這樣就屏蔽掉了組用戶和其他用戶的讀寫權限位,因此再創建新文件bar,它的權限位是600。

?

2 chmod、fchmod和fchmodat函數

函數作用:修改已有文件的權限位。

函數聲明:

#include <sys/stat.h>

int chmod(const char *pathname, mode_t mode);

int fchmod(int fd, mode_t mode);

int fchmodeat(int fd, const char *pathname, mode_t mode, int flag);

?區別:

  • chmod:作用在某個指定的文件上
  • fchmod:作用在某個指定的已經打開的文件上
  • fchmodat:類似之前的函數,當pathname為絕對路徑,或者fd取值為AT_FDCWD并且pathname為相對路徑時,fchmodat函數的作用和chmod相同;否則,工作目錄為fd指定父目錄路徑加上pathname為父目錄的子目錄。參數flag用來指定fchmodeat的行為:取值為AT_SYMLINK_NOFOLLOW時,該權限修改并不追蹤符號鏈接,只修改該符號鏈接文件的權限。

權限要求:要修改一個文件的權限,需要當前進程的effective user ID和文件的所有者ID相同,或者進程有超級用戶權限。

代表各個權限位的常量如下表所示:

NewImage

Example:

修改在上例中創建的兩個文件foo和bar的權限。

#include "apue.h"

?

int

main(void)

{

? ? struct stat ? ? statbuf;

?

? ? /* turn on set-group-ID and turn off group-execute */

?

? ? if (stat("foo", &statbuf) < 0)

? ? ? ? err_sys("stat error for foo");

? ? if (chmod("foo", (statbuf.st_mode & ~S_IXGRP) | S_ISGID) < 0)

? ? ? ? err_sys("chmod error for foo");

?

? ? /* set absolute mode to "rw-r--r--" */

?

? ? if (chmod("bar", S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) < 0)

? ? ? ? err_sys("chmod error for bar");

?

? ? exit(0);

}

運行結果:

NewImage

結果說明:

  • 執行程序之前,foo的權限為666,程序中首先使用stat函數獲取文件的信息存在statbuf中,置組用戶執行位(S_IXGRP)為0,并置該位為S(S_ISGID)。
  • 執行程序之前,bar的權限位600,程序中設置該文件的組用戶和其他用戶有讀權限,設置成功之后,可以看到bar的文件權限位644.

高級權限(SUID/SGID/Sticky Bit )檔案特殊權限 說明:

  • SUID (Set UID): 會制作出 s 的權限,權限數字是 4 。這個權限只能作用于可執行文件,不可作用于目錄,shell script也不行。使一般使用者在執行文件時,暫時具有該文件擁有者的權限。
  • SGID (Set GID): 制作出 s 權限,權限數字是 2 。這個權限可以作用于目錄和文件。作用于目錄時,在該目錄下建立的所有文件和目錄的group都會是該目錄的group;作用于文件時,則不論使用者是誰,在執行該程序的時候, 他的有效群組 (effective group) 將會變成該程序的群組所有人 (group id)。
  • Sticky Bit: 制作出 t 權限,權限數字是 1 。這個權限只能作用于目錄。在該權限作用的目錄里,如果使用者具有w,x權限,那么他所創建的文件和目錄,只有檔案的擁有者和root才能刪除。
  • 注意:在字符表示權限時,s和t是出現在x的位置的,意思是在可執行的文件和目錄時,它們才是有意義的。如果文件或目錄本身u、g或o就沒有可執行權限,那么它所在的權限組出現的是S或者T,表示空的意思。用數字表示權限,就是在rwx前面加上4、2、1的組合就是了,如1777。

?

3 Sticky Bit(S_ISVTX)

Sticky bit有一個冗長的歷史,這里并不贅述。

作用:如果文件夾的sticky bit被打開,則文件夾中的文件被刪除或者重命名需要滿足一下的條件之一:當前用戶對該文件夾有寫權限;當前用戶是該文件的所有者;當前用戶是該文件夾的所有者;當前用戶是超級用戶。

典型的打開了sticky bit的兩個文件夾是/tmp 和/var/tmp,這兩個文件夾對所有用戶都有讀寫和執行權限,這樣所有用戶都可以在該文件夾下創建文件,但是并不能刪除由其他用戶所有的文件。

NewImage

NewImage

?

4 chown、fchown、fchownat和lchown函數

函數作用:修改文件所屬的用戶ID和組ID,如果參數owner和group有一個的值為-1,對應的ID值不變。

#include <unistd.h>

int chown(const char* pathname, uid_t owner, gid_t group);

int fchown(int fd, uid_t owner, gid_t group);

int fchownat(int fd, const char* pathname, uid_t owner, gid_t grou, int flag);

int lchown(const char* pathname, uid_t owner, gid_t group);

區別:

當目標文件不是一個符號鏈接時,上面的四個函數的作用基本相同。

當目標文件是一個符號鏈接文件時,并且函數lchown和fchownat的flag設置為AT_SYMLINK_NOFOLLOW時,這兩個函數修改符號鏈接文件本身的所有者,而不是符號鏈接指向的文件。

fchown函數修改fd代表的已打開文件的所有者。因為fchown操作的是已經打開的文件,所以它不可以用來修改符號鏈接的所有者。

fchownat函數的行為:當參數pathname是絕對路徑,或者參數fd的值為AT_FDCWD并且pathname為相對路徑時,fchownat函數的行為和chown和lchown類似;具體來說,flag取值AT_SYMLINK_NOFOLLOW時,行為和lchown類似;否則行為和chown類似。當fd代表已打開的文件夾,pathname為一個相對路徑時,目標文件為以fd為父目錄,pathname為相對的子目錄所指的文件。

?

5 文件大?。‵ile Size)

stat結構體中的成員st_size表示文件大小字節數。

字段st_size只對常規文件(regular files)、目錄文件(directories)和符號鏈接文件(symbolic links)。

更多的細節:

  • 常規文件大小允許為0;
  • 目錄文件的大小往往是整數,如16或512;
  • 符號鏈接文件的大小是被鏈接文件名的長度,如符號鏈接lib—>usr/lib,大小為7,正好是字符串“usr/lib”長度,并不需要像C風格字符串一樣+1。

?

6 文件截斷(File Truncation)

有時候我們需要通過丟棄文件結尾一部分來截短文件。

函數聲明:

#include <unistd.h>

int truncate(const char* pathname, off_t length);

itn ftruncate(int fd, off_t length);

函數作用:把目標文件截斷到參數length指定的長度。

參數:如果參數length的值比指定文件的長度小,則文件超過length長度的部分不可讀;如果length的值比指定文件的長度大,文件長度擴大到length,擴充部分填充0(可能是一個hole)

?

7 文件系統(File Systems)

為了理解文件鏈接,我們需要對Unix文件系統的結構有一個概念性地認識。

一個磁盤(disk drive)可以被分為多個分區(partition),每個分區都可以包含一個文件系統(file system)。

inode是一個定長的索引,包含了一個文件的大部分信息。

NewImage

關于 i-nodes和data blocks的內存布局如下圖所示:

NewImage

說明:

  • 兩個目錄索引(directory entry)指向同一個i-node索引(i-node entry)。即多個文件夾包含同一個文件(可能通過硬鏈接或軟鏈接),每一個inode都由一個字段link count,包含指向該i-node的目錄索引數。只有當該數值(link count)為0時,該文件才會被刪除(釋放文件所占用的data blocks)。索引后面介紹的移除目錄的函數不叫delete,而是unlink。在stat數據結構中,link count對應的字段為st_nlink。這里提到的鏈接為硬鏈接。
  • 另外一種鏈接為符號鏈接。符號鏈接文件對應的data block中存有該鏈接指向文件的文件名(之前有提到)。對應的i-node中文件類型字段的值應為S_IFLINK,告訴文件系統當前文件為符號鏈接。
  • i-node包含了對應文件的所有信息:如文件類型,指向文件數據塊的指針,文件權限位,文件大小等。stat數據結構中得大部分字段都是從i-node中獲取。有兩個字段值存在目錄索引中:文件名(file name)和i-node數(i-node number)。i-node數目對應的數據類型為ino_t。

我們再了解一下目錄文件的link count字段。

當我們執行下面的命令:

mkdir testdir

?內存中數據組織結構如下所示:

NewImage

從上圖可以看到,目錄下每多加一個文件或文件夾,link count都會加1。

圖中顯示的都很清楚,不做過多贅述(其實是我懶了,哈哈...)

?

8 link、linkat、unlink、unlinkat和remove函數

從前面可以知道,多個目錄索引可以指向同一個文件,即多個目錄可以包含同一個文件。

link和linkat的作用是創建一個已存在文件的鏈接。

函數聲明:

#include <unistd.h>

int link(const char* existingpath, const char* newpath);

int linkat(int efd, const char* existingpath, int nfd, const char* newpath, int flag);

函數細節:

  • 函數創建一個新目錄索引newpath,關聯到已存在文件existingpath;
  • 如果newpath已經存在,返回錯誤;
  • newpath只有最后一個文件名會被創建,路徑其他部分必須已存在;
  • linkat的參數的作用和前面xxxat函數介紹過的類似,這里不再贅述;
  • 如果被鏈接的文件是一個符號鏈接文件,參數flag用來控制當前新建的鏈接是關聯到該符號鏈接(默認行為),還是該鏈接指向的文件(AT_SYMLINK_FOLLOW);
  • 一般來說不可以擴文件系統創建鏈接,防止文件系統間的硬鏈接循環;
下面再了解一下unlink函數。

函數聲明:

#include <unistd.h>

int unlink(const char* pathname);

int unlinkat(int fd, const char* pathname, int flag);

函數細節:

  • 函數會刪除目錄索引,并且對應文件的inode的link count減1,如果link count不為0,則說明還有其他目錄索引指向該文件,不刪除該文件,否則刪除該文件;
  • 進程必須對該目錄有寫權限和執行權限;
  • 如果pathname是一個符號鏈接,unlink移除該符號鏈接文件,而不是該符號鏈接指向的實體文件。沒有函數實現直接刪除實體文件這個功能。

和unlink類似功能的函數remove:

#include <stdio.h>

int remove(const char* pathname);

函數細節:

  • remove一個文件相當于調用unlink,remove一個文件夾相當于調用rmdir(后面會介紹)。

?

9 rename和renameat函數

函數聲明:

#include <stdio.h>

int rename(const char* oldname, const char* newname);

int renameat(int oldfd, const char* oldname, int newfd, const char* newname);

函數細節:

  • 如果oldname不是一個目錄路徑,說明我們正在重命名一個文件或符號鏈接。這里newname已存在,則不可以是一個已存在目錄的名字。如果newname已存在并且不是目錄名,則刪除已有文件newname,將oldname所指文件重命名為newname。權限要求:我們必須有包含oldname和newname文件的目錄的寫權限。
  • 如果oldname是一個目錄路徑,則我們在重命名一個目錄。如果newname已存在,它必須是一個目錄的名字,并且該目錄必須是空目錄(只有. 和 ..索引)。這種情況下,刪除已存在目錄newname,將待重命名目錄oldname重命名為newname。還需要注意的,newname不能包含oldname。例如:不能將目錄/usr/foo重命名為/usr/foo/testdir,因為/usr/foo是新目錄名的前綴,無法被刪除。
  • 如果oldname或newname為一個符號鏈接名,那么被重命名的時符號鏈接本身,不是符號鏈接指向的文件。
  • 我們不能重命名dot(.)和dot-dot(..),更確切地說,這兩個特殊名不能作為路徑名的最后一部分。
  • 如果oldname和newname相同,則函數返回成功,不做任何事情。

對renameat函數的參數含義不再贅述。

?

10 符號鏈接(Symbolic Links)

符號鏈接可以認為是文件的非直接指針,而硬鏈接(hard link)可以看做是文件的直接指針,因為它直接指向文件的inode。

  • 硬鏈接通常不可以跨文件系統;
  • 只有超級用戶可以對一個目錄創建硬鏈接。

符號鏈接并沒有文件系統間的限制。

由于符號鏈接的存在,我們在操作文件或目錄時,總是需要知道該文件是否是一個符號鏈接,然后判斷該函數的操作對象是符號鏈接指向的文件還是符號鏈接本身。

下圖總結了一些常用函數是否追蹤鏈接,僅供參考:

NewImage

Example:

NewImage

鏈接情況如下圖所示:

NewImage

可以發現,由于符號鏈接而出現了一個環。

再來試驗一下:

NewImage

我們發現,這樣會無限循環下去。

解除循環的方法就是使用unlink刪除該符號鏈接。需要注意的一點是,如果這里出現的鏈接是硬鏈接,則刪除這個循環鏈接會困難得多。因此只有管理員權限才可以用link函數對一個文件建立硬鏈接。

有時候符號鏈接會造成一些迷惑的事情,如果使用者對符號鏈接不熟悉的話。

如下所示:

NewImage

符號鏈接可以鏈接一個不存在的文件,如果使用者對符號鏈接不熟悉,則很容易被這種情況迷惑。

這時,可以使用ls的”-l"命令看到有 “->"符號,或者前面符號位第一位的”l”表示符號鏈接,或者用ls得“-F”命令,符號鏈接文件后面會跟一個@符。

?

11 創建和讀取符號鏈接(Symbolic Links)

函數作用:創建符號鏈接

函數聲明:

#include <unistd.h>

int symlink(const char *actualpath, const char* sympath);

int symlinkat(const char* actualpath, int fd, const char* sympath);

參數說明:

  • 函數并不要求actualpath一定存在,在上面的例子中也看到了這一點。

因為open函數會打開符號鏈接指向的實際文件,所以需要一個函數打開符號鏈接本身。

函數聲明:

#include <unistd.h>

ssize_t readlink(const char* restrict pathname, char* restrict buf, size_t bufsize);

ssize_t readlinkat(int fd, const char* restrict pathname, char* restrict buf, size_t bufsize);

如果調用成功,函數從符號鏈接中讀取buf長的內容。

?

?

參考資料:

《Advanced PRogramming in the UNIX Envinronment 3rd》

?


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
国产激情自拍_国产9色视频_丁香花在线电影小说观看 _久久久久国产精品嫩草影院
亚洲人成电影| 丁香视频五月| 国产香蕉免费精品视频| 免费看成年人视频在线观看| www在线观看播放免费视频日本| www.av在线视频| 欧美日韩国产亚洲沙发| 久久精品最新免费国产成人 | 99热在线观看免费| 国产日韩欧美一区二区三区视频| 国产成人精品自线拍| 亚洲人av在线| 国产探花在线观看| 亚洲精品午夜级久久久久| 国产尤物一区二区三区| 国产精品白浆流出视频| 中文字幕av在线播放| 亚洲欧美国产另类首页| 国产精品偷乱一区二区三区| 国产黄色免费网站| 免费男女羞羞的视频网站中文字幕| 国产理论电影在线观看| av在线free| 国产女主播在线观看| 青青国产在线| av免费在线免费| 国产网友自拍视频导航网站在线观看| 亚洲精品视频在线免费| 国产精品久久麻豆| 好男人社区在线视频| 在线三级中文| 国产网红在线| 午夜视频免费在线观看| 激情视频国产| 九九热精品在线视频| 日本高清不卡中文字幕| 亚洲日本伊人| 欧美性xxxx交| 成年女人在线视频| av在线天堂| 青青草免费在线观看| 日本视频二区| 老司机在线视频二区| 九九精品九九| 先锋影音av中文字幕| 亚洲电影视频在线| 在线观看av网站| av中文在线资源| 啪啪免费视频一区| 国产精品一二三区视频| 国产污视频在线| 国产高清一级片| 99re6在线视频精品免费| 在线中文av| 不卡av免费观看| 五月婷婷在线观看| 国产一二三区在线| 精品麻豆国产| 欧美视频免费一区二区三区| 国产免费高清| 9999在线视频| www.av在线视频| 尤物视频在线观看| 亚洲91av| 国产偷窥洗澡视频| 秋霞av在线| 国产高清在线a视频大全| a视频免费看| 国产一二区在线| www在线视频观看| 国产精品视频一区麻豆| 波多野结衣久久高清免费| 国产人成在线视频| 免费网站看黄yyy222| 国产婷婷视频在线| 天天干天天摸| 国产系列电影在线播放网址| 精品999视频| 麻豆视频国产| 在线免费观看黄色av| 国产精品偷乱一区二区三区| 亚洲www色| 精品三级久久久久久久电影聊斋| 超碰在线人人| 中文国产字幕在线观看| 狠狠操狠狠色| 亚洲an天堂an在线观看| 国产成人高清精品| 国产免费专区| 超碰在线观看免费| 欧美日韩综合高清一区二区| 伊人资源视频在线| 最近中文字幕mv2018在线高清| 香蕉视频在线观看网站| 在线观看中文字幕一区| 精品999视频| av网站大全在线| 精品剧情v国产在线观看| 国产一二三在线观看| 国产麻豆精品一区二区三区v视界| 亚洲最新永久观看在线| av激情在线| 天天插天天射| 青青草免费观看免费视频在线| 伊人影院在线观看| 日韩亚洲一区中文字幕| www.五月色.com| 在线观看国产福利视频| 亚洲国产日韩在线人成电影| 在线三级av| 欧美日韩视频精品二区| 国产精品一区二区三区四区色| 国产精品作爱| 国产区在线视频| 91视频黄色| 日p在线观看| 福利视频网站导航| 国产毛片在线看| 51成人精品网站| eeuss影院在线| 国产女王在线**视频 | 国产精品666| 一个人看的www免费观看视频| av在线中文| 最近高清中文在线字幕在线观看 | 中文字幕在线影院| 精品国内一区二区三区免费视频| 亚洲精品国自产拍在线观看| 久热精品视频在线播放| 国产一卡2卡3卡免费网站| 7777在线| 国产毛片毛片毛片| av人人综合网| 国产黄色片大全| 成人欧美精品久久久久影院| 99久久免费精品国产免费| 天天爱天天做色综合| 在线观看的网站你懂的| 国产网站av| 国产乱xxⅹxx国语对白| 欧美精品久久久久久久小说| 国产精品69xx| 国产精选在线观看| 亚洲精品手机在线| 国产高潮又爽又无遮挡又免费| 日本成人免费网站| 亚洲字幕成人中文在线观看| 国产高清在线视频| 国产精品一二三区视频| 蜜桃视频网站在线| 欧美激情福利视频在线观看免费| 精品国内自产拍在线视频| 国产视频第一区| 中文字幕乱在线伦视频乱在线伦视频| 99爱视频在线观看| av人人综合网| 亚洲综合在线免费| 精品国语对白精品自拍视| 中文字幕在线视频免费观看| 欧美亚洲系列| 免费在线黄色网址| 久久久久久久久免费视频| 在线a人片免费观看视频| 精品日韩av| 亚洲成a人v欧美综合天堂麻豆| 精品亚洲成a人片在线观看| 中文字幕一区免费| 国产午夜精品久久久久免费视| 天堂在线免费av| 尤物视频在线看| 国产精品久久久久永久免费看| 国产激情在线| 99爱视频在线观看| 伊人伊人av电影| 不卡av免费观看| 最近最好的中文字幕2019免费 | 国产美女在线一区二区三区| 国产精品自产拍在线观看2019| 国产日韩精品在线看| 国产黄色av免费看| 日本成a人片在线观看| 成人超碰在线| 国产香蕉在线| 在线视频中文字幕第一页| 欧美成人精品福利网站| 国产免费a∨片在线观看不卡| 国产特黄在线| www.xxx黄| 国产福利在线观看| www.av在线| 在线视频三区| 超碰在线网址| 国产9色视频| 丁香花在线电影| 国产美女视频网站| 亚洲欧美自拍另类| 国产二级片在线| 国产女人伦码一区二区三区不卡| 免费一区二区在线观看| 91资源在线观看|