[APUE]文件和目錄

来源:http://www.cnblogs.com/orlion/archive/2016/12/23/6209120.html
-Advertisement-
Play Games

一、APUE這一章中的各種晦澀名詞 我在讀這一章時遇到了各種ID,根據名字完全不清楚什麼意思,幸好看到了這篇文章,http://blog.csdn.net/ccjjnn19890720/article/details/6990656,總結一下 每一個進程其實對應了6個以上的ID,它們分別是:實際用戶 ...


一、APUE這一章中的各種晦澀名詞

  我在讀這一章時遇到了各種ID,根據名字完全不清楚什麼意思,幸好看到了這篇文章,http://blog.csdn.net/ccjjnn19890720/article/details/6990656,總結一下

  每一個進程其實對應了6個以上的ID,它們分別是:實際用戶ID、實際組ID(我們實際上是誰,執行這個程式的用戶和組),有效用戶ID、有效組ID、附加組ID(用於文件訪問許可權檢查),保存設置用戶ID,保存設置組ID(由exec函數保存)

  實際用戶ID/實際組ID:當前執行這個進程的ID,比如我現在是orlion用戶,那麼我執行foo程式,那麼這個foo進程的實際用戶ID就是orlion。組同理

  有效用戶ID/有效組ID:這個ID是unix一直在使用的一個ID,因為即使你只是一個很簡單的訪問文件,那也是要通過這個有效用戶ID的,因為每一個文件都有一定的訪問許可權,而一個進程或者一個程式去訪問它,操作系統本身就是根據你的有效用戶ID給與一定的許可權.

  實際用戶ID與有效用戶ID到底什麼區別?!:這兩個ID在一般情況下是相同的,比如當前用戶是orlion,那麼它的實際用戶ID是orlion,而有效用戶ID也是orlion。可是在不一般的情況下那麼這兩個ID就可能不一樣了,那麼什麼樣的情況下是不一樣的呢?那就是當一個用戶要進行一個合理的特權的時候就需要啦,那麼到底是怎麼樣的情況呢?

      比如我們在Linux系統中的passwd這個命令或者這個passwd這個程式,一個用戶對自己進行修改密碼是一種很正常的事情,可是保存密碼的文件/etc/passwd卻是root用戶可寫的這樣的權利,那麼也就是用如果你要修改密碼,必須通過root用戶幫你修改

  這個事情的處理是這樣的,讓用戶去運行passwd這個程式的時候,os給與root用戶的權利,然後用戶就可以修改自己的密碼。具體的講就是讓用戶去運行passwd這個程式的時候,unix將它的有效用戶ID變成了擁有passwd的用戶的ID,也就是root,所以就可以修改這個/etc/passwd這個文件。

  保存設置用戶ID:這個ID是用來保存有效ID的副本,讓我們運行程式的過程其實就是os調用exec系列函數來調用我們程式的main函數,exec函數是kernel唯一執行程式的方法,或者那麼講不管什麼用戶程式的運行,其實也就是os的exec的調用過程。而exec在調用過程中會將這個程式的有效用戶ID拷貝給保存用戶ID。

  文件的設置用戶ID位:每一個文件都有一個文件模式字(st_mode),這個字可以通過stat函數去獲取,而這個模式字包含了很多文件的屬性,包括文件的類型,以及文件的訪問許可權的,當然設置用戶ID位也在其中。通過設置這個位,就能當執行這個文件的時候,進程的有效ID設置為該文件本身的用戶,這裡這個文件可以認為是可執行文件,當運行這個文件的時候,進程會改變其有效用戶ID,變成這些文件本身的ID

  終端中我們查看/usr/bin/passwd這個文件

$ ll /usr/bin/passwd
-rwsr-xr-x. 1 root root 30768 2月  22 2012 /usr/bin/passwd

  可以看到有一個s許可權,這就是設置了設置用戶ID位的標誌。

  

#include <stdio.h>  
#include <stdlib.h>  
#include <sys/stat.h>  
#include <unistd.h>  
  
int main()  
{  
    printf("real user ID = %d\n",getuid());  
    printf("effect user ID = %d\n",geteuid());  
  
    return 0;  
}  
 
終端中執行: orlion$ .
/main real user ID = 1000 effect user ID = 1000 orlion$ su root# chown root main root# chmod u+s main root# ll main -rwsr-xr-x 1 root orlion 9809 2016-12-21 22:20 main root# exit orlion$ exit orlion$ ./main real user ID = 1000 effect user ID = 0

  從以上可以看到有效用戶id發生了變化

二、chmod和fchmod函數

  這兩個函數使我們可以更改現存文件的存取許可權(許可權)

#include <sys/types.h>
#include <sys/stat.h>

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

int fchmod(int fileds, mode_t mode); fileds即為文件句柄

返回值: 若成功則為0,若出錯則為-1

  為了改變一個文件的許可權,進程的有效用戶ID必須等於文件的所有者,或者有root許可權

  參數mode是下麵所示逐位或運算

  

mode                說明明

S_ISUID            執行時設置 -用戶-ID
S_ISGID            執行時設置 -組-ID
S_ISVTX            保存正文
S_IRWXU          用戶(所有者)讀、寫和執行
S_IRUSR           用戶(所有者)讀
S_IWUSR          用戶(所有者)寫
S_IXUSR           用戶(所有者)執行
S_IRWXG          組讀、寫和執行
S_IRGRP           組讀
S_IWGRP          組寫
S_IXGRP           組執行
S_IRWXO 其他讀、寫、和執行
S_IROTH 其他讀
S_IWOTH 其他寫
S_IXOTH 其他執行

   實例:

#include <stdio.h>
#include <sys/stat.h>

int main(void)
{
    struct stat statbuf;

    if (stat("foo", &statbuf) < 0) {
        fprintf(stderr, "stat error for foo\n");
    }

    if (chmod("foo", (statbuf.st_mode & -S_IXGRP) | S_ISGID) < 0) {
        fprintf(stderr, "chmod error for foo\n");
    }

    /* set absolute mode to "rw-r--r--" */
    if (chmod("bar", S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) < 0) {
        fprintf(stderr, "chmod error for bar\n");
    }

    return 0;
}

 

三、 粘住位
  上一小節中S_ISVTX位,UNIX早期版本中,有一位被稱為粘住位(sticky bit)。如果一個可執行程式文件的這一位被設置了,那麼在該程式第一次執行並結束時,該程式正文的一個文本被保存在交換區。 (程式的正文部分是機器指令部分。 )這使得下次執行該程式時能較快地將其裝入記憶體區。其原因是:在交換區,該文件是被連續存放的,而在一般的 U N I X文件系統中,文件的各數據塊很可能是隨機存放的。對於常用的應用程式,例如文本編輯程式和編譯程式的各部分常常設置它們所在文件的粘住位。後來的UNIX版本稱之為保存 -正文位( saved-text bit ),因此也就有了常數 S _ I S V T X。現今較新的UNIX系統大多數都具有虛存系統以及快速文件系統,所以不再需要使用這種技術。
S V R 4和4 . 3 + B S D中粘住位的主要針對目錄。如果對一個目錄設置了粘住位,則只有對該目錄具有寫許可權的用戶並且滿足下列條件之一,才能刪除或更名該目錄下的文件:
• 擁有此文件。
• 擁有此目錄。
• 是超級用戶。
目錄/tmp和/var/spool/uucppublic是設置粘住位的候選者 —,這兩個目錄任何用戶都可在其中創建文件。這兩個目錄對任一用戶 (用戶、組和其他 )的許可權通常都是讀、寫和執行。但是用戶不應能刪除或更名屬於其他人的文件,為此在這兩個目錄的文件方式中都設置了粘住位。

四、 chown、fchown和lchown函數

#include <sys/types.h>
#include <unistd.h>

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

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

int lchown(const char *pathname, uid_t owner, gid_t group);
返回值:成功0,失敗-1.

  lchown更改符號連接本身的所有者,而不是符號鏈接所指向的文件

  根據_POSIX_CHOWN_RESTRICTED的值,POISX.1可以選擇只有超級用戶才能更改某個文件的所有者或者任何用戶都能修改他們所擁有的文件的所有者。

  若_POSIX_CHOWN_RESTRICTED對指定的文件起作用,則

  (1) 只有超級用戶進程能更改該文件的用戶 ID。
  (2) 若滿足下列條件,一個非超級用戶進程可以更改該文件的組 ID:
    (a) 進程擁有此文件(其有效用戶 ID等於該文件的用戶 ID)。
    (b) 參數owner等於文件的用戶ID,參數group等於進程的有效組ID或進程的添加組ID之一。
  這意味著,當 _ P O S I X _ C H O W N _ R E S T R I C T E D有效時,不能更改其他用戶的文件的用戶ID。你可以更改你所擁用的文件的組 ID,但只能改到你所屬於的組。
  如果這些函數由非超級用戶進程調用,則在成功返回時,該文件的設置 -用戶-ID位和設置-組-ID位都被清除。

五、 文件長度
  stat結構的成員st_size包含了以位元組為單位該文件的長度。此欄位只對普通文件、目錄、符號連接有意義。
  對於目錄文件長度通常市一個數,例16或512的整數倍;
  對於符號連接,文件長度是實際文件的長度。

六、 文件截短
  有時我們需要在文件尾端截去一些數據以縮短文件,截短文件可以調用以下函數

#include <sys/types.h>
#include <unistd.h>

int truncate(const char *pathname, off_t length);
int ftruncate(int filedes, off_t length);
返回值:成功0,失敗-1.

  這兩個函數將文件的長度截短為length, 如果之前文件長度大於length,則超過length以外的數據就不再存取,如果以前的長度小於length,則其結果與系統有關。如果某個系統的處理是擴展該文件,則超過舊文件尾端與新文件尾端數據將讀作0。

七、 文件系統

  傳統的UNIX系統V文件系統,可以將一個硬碟分為多個分區,每個分區可以包含一個文件系統

  

 

    i節點是固定長度的記錄項,包含有關文件的信息。

  

  • 上圖中有兩個目錄指向同一i節點。每個i節點中都有一個連接計數,其值是指向該i節點的目錄項數。只有當連接計數為0時才能刪除該文件(也就是可以釋放該文件所占的數據塊)。在stat結構中連接計數包含在st_nlink中,其基本系統數據類型是nlink_t。這種連接稱為硬連接。POSIX.1常數LINK_MAX指定了一個文件連接的最大值。
  • 另外一種連接是符號連接(symbolic link)。對於這種連接,該文件的實際內容(在數據塊中)包含了該符號連接所指向的文件的名字。
  • i節點包含了所有與文件有關的信息:文件類型、文件存取許可權位、文件長度和指向該文件所占用的數據塊的指針等。stat結構中大多數信息都取自i節點。只有兩項數據存放在目錄項中:文件名和i節點編號數。i節點編號數的數據類型是ino_t。
  • 因為目錄項中的i節點編號數指向同一文件系統中的i節點,所以不能使一個目錄項指向另一個文件系統的i節點。(所以ln命令不能跨文件系統)
  • 當在不更改文件系統的情況下為一個文件更名時,該文件的實際內容並未移動,只需構造一個指向現存i節點的新目錄項。

 

  對於目錄文件的連接計數欄位:假如我們創建了一個testdir目錄:

$ mkdir testdir

  下圖顯示了其結果,顯式的顯示了.和..目錄項

  

  2549的i節點,其類型欄位表示它是一個目錄,其類型欄位表示它是一個目錄。而連接計數為2。任何一個葉目錄(不包含任何目錄(子目錄)的目錄)其連接計數總是2,數值2來自於命名該目錄(testdir)的目錄以及在該目錄中的.項。編號為1267的i節點,其類型欄位表示它是一個目錄,而其連接計數則大於或等於3。它大於等於3的原因是至少有三個目錄項指向它:一個是命名它的目錄項,一個是在該目錄中的.項,第三個是在自子目錄testdir中的..項。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1、ViewBag Controller:ViewBag.Message = "Hello, Word"; View:@ViewBag.Message 註:ViewBag的類型是動態的,不確定的,直接就可以使用,它的傳值範圍是:controller向view傳值,view自己和自己傳值。2、View ...
  • 實現效果如下: 1.在前臺Web的Category Menu顯示 Vendor; 2.點擊Vendor 顯示Vendor List列表; 主要配置步驟: 1.運行網站 Admin 後臺 Categorys 增加 Vendor 並配置其SEO 如vendor-all 2.代碼層面 Nop.Web In ...
  • 然ASP.NET Core應用的路由是通過RouterMiddleware這個中間件來完成的,但是具體的路由解析功能都落在指定的Router對象上,不過我們依然有必要以代碼實現的角度來介紹一下這個中間件。 ...
  • 有時需要追求效率,會代替一些算術運算。 求商:a >> n <=> a / 2^n 求積:a << n <=> a * 2^n 求餘:a & ((1 << n) - 1) <=> a % 2^n 奇偶判斷:a & 1 == 1 <==> a % 2 == 1 一般1表示選中或者開啟項,0表示未選或者 ...
  • 背景 由於工作的一些原因,需要從C#轉成JAVA。之前PetaPoco用得真是非常舒服,在學習JAVA的過程中熟悉了一下JAVA的數據組件: MyBatis 非常流行,代碼生成也很成熟,性能也很好。但是DEBUG的時候不方便,且XML寫SQL也不是很適應,尤其是團隊比較小沒有專職DBA的情況下。 H ...
  • 使用對象來管理資源,可以避免因個人疏忽帶來的一些低級錯誤,但是不是每件事都是稱心如意的。 一些函數依然使用原始的資源對象,那麼我們就需要為這些函數提供一個介面,讓他們可以獲取到原始對象。 繼續拿13節的智能指針說事,先上代碼: //SFAutoPtr.h #pragma once template ... ...
  • 在上一篇Java集合框架之Collection介面中我們知道List介面是Collection介面的子介面,List介面對Collection進行了簡單的擴充,List介面中的元素的特點為有序,可重覆,允許null值,因為List繼承了Collection介面,所以繼承自Collection介面中的 ...
  • 這裡我們用Windows下的shell來舉例: 為了方便你理解,我們用一個很簡單的一段代碼來說明: 可以看見我們利用Popen實例化了一個p,創建了子程式cmd.exe,然後我們給他的的Stdin(標準輸入流)Stdout(標準輸出流); 同時使用了subprocess.PIPE 作為參數,這個是一 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...