1. 程式人生 > >3.2 Linux檔案屬性(5、6節)

3.2 Linux檔案屬性(5、6節)

3.2.5.檔案許可權管理2

3.2.5.1、access函式檢查許可權設定

(1)文字許可權管控其實蠻複雜,一般很難很容易的確定對一個檔案是否具有某種許可權。設計優秀的軟體應該是:在操作某個檔案之前先判斷當前是否有許可權做這個操作,如果有再做如果沒有則提供錯誤資訊給使用者。

(2)access函式可以測試得到當前執行程式的那個使用者在當前那個環境下對目標檔案是否具有某種操作許可權。

#include <stdio.h>
#include <unistd.h>

#define NAME 	"3.txt"

int main(void)
{
	int ret = -1;
	
	
	ret = access(NAME, F_OK);
	if (ret < 0)
	{
		printf("檔案不存在 \n");
		return -1;
	}
	else
	{
		printf("檔案存在	");
	}
	
	ret = access(NAME, R_OK);
	if (ret < 0)
	{
		printf("不可讀 ");
	}
	else
	{
		printf("可讀 ");
	}

	ret = access(NAME, W_OK);
	if (ret < 0)
	{
		printf("不可寫 ");
	}
	else
	{
		printf("可寫 ");
	}

	ret = access(NAME, X_OK);
	if (ret < 0)
	{
		printf("不可執行 \n");
	}
	else
	{
		printf("可執行 \n");
	}	
	return 0;
}

3.2.5.2、chmod/fchmod與許可權修改

(1)chmod是一個linux命令,用來修改檔案的各種許可權屬性。chmod命令只有root使用者才有權利去執行修改。

(2)chmod命令其實內部是用linux的一個叫chmod的API實現的。

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


int main(int argc, char **argv)
{
	int ret = -1;
	
	
	if (argc != 2)
	{
		printf("usage: %s filename\n", argv[0]);
		return -1;
	}
	
	ret = chmod(argv[1], S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWOTH);
	if (ret < 0)
	{
		perror("chmod");
		return -1;
	}
	
	return 0;
}

3.2.5.3、chown/fchown/lchown與屬主修改

(1)linux中有個chown命令來修改檔案屬主
(2)chown命令是用chown API實現的

3.2.5.4、umask與檔案許可權掩碼

(1)檔案掩碼是linux系統中維護的一個全域性設定,umask的作用是用來設定我們系統中新建立的檔案的預設許可權的。
(2)umask命令就是用umask API實現的

3.2.6.讀取目錄檔案

3.2.6.1、opendir與readdir函式

(1)opendir開啟一個目錄後得到一個DIR型別的指標給readdir使用
(2)readdir函式呼叫一次就會返回一個struct dirent型別的指標,這個指標指向一個結構體變數,這個結構體變數裡面記錄了一個目錄項(所謂目錄項就是目錄中的一個子檔案)。
(3)readdir呼叫一次只能讀出一個目錄項,要想讀出目錄中所有的目錄項必須多次呼叫readdir函式。readdir函式內部戶記住哪個目錄項已經被讀過了哪個還沒讀,所以多次呼叫後不會重複返回已經返回過的目錄項。當readdir函式返回NULL時就表示目錄中所有的目錄項已經讀完了。

3.2.6.2、dirent結構體

#include <stdio.h>
#include <sys/types.h>
#include <dirent.h>


int main(int argc, char **argv)
{
	DIR *pDir = NULL;
	struct dirent * pEnt = NULL;
	unsigned int cnt = 0;
	
	if (argc != 2)
	{
		printf("usage: %s dirname\n", argv[0]);
		return -1;
	}
	
	pDir = opendir(argv[1]);
	if (NULL == pDir)
	{
		perror("opendir");
		return -1;
	}
	
	while (1)
	{
		pEnt = readdir(pDir);
		if(pEnt != NULL)
		{
			// 還有子檔案,在此處理子檔案
			printf("name:[%s]	,", pEnt->d_name);
			cnt++;
			if (pEnt->d_type == DT_REG)
			{
				printf("是普通檔案\n");
			}
			else
			{
				printf("不是普通檔案\n");
			}
		}
		else
		{
			break;
		}
	};
	printf("總檔案數為:%d\n", cnt);
	return 0;
}

3.2.6.3、讀取目錄實戰演練

3.2.6.4、可重入函式介紹

(1)有些函式是可重入的有些是不可重入的,具體概念可以去百度。
(2)readdir函式和我們前面接觸的一些函式是不同的,首先readdir函式直接返回了一個結構體變數指標,因為readdir內部申請了記憶體並且給我們返回了地址。多次呼叫readdir其實readir內部並不會重複申請記憶體而是使用第一次呼叫readdir時分配的那個記憶體。這個設計方法是readdir不可重入的關鍵。
(3)readdir在多次呼叫時是有關聯的,這個關聯也標明readdir函式是不可重入的。
(4)庫函式中有一些函式當年剛開始提供時都是不可重入的,後來意識到這種方式不安全,所以重新封裝了C庫,提供了對應的可重複版本(一般是不可重入版本函式名_r)