Linux環境(四) 臨時檔案與使用者資訊

2021-08-22 15:47:36 字數 4412 閱讀 2050

臨時檔案

通常,程式需要以檔案的形式使用臨時儲存。這也許是儲存計算的中間結果,或者是在實際操作之前所做的檔案拷貝備份。例如,乙個資料程式在刪除記錄時會使用臨時檔案。檔案會收集需要儲存的資料庫實體,然後在操作結束時,臨時檔案會成為新的資料庫而原始的會被刪除。

臨時檔案的大量使用隱藏了他的乙個缺點。我們必須小心來確保程式會選擇乙個唯一的名字來使用臨時檔案。如果不是這樣,因為linux是乙個多工系統,也許會有另乙個程式選擇了相同的名字,而這兩個彼此之間會相互影響。

乙個唯一的臨時檔名可以由tmpnam函式生成:

#include

char *tmpnam(char *s);

tmpnam函式會返回乙個與現存的檔案不同的可用的檔名。如果字串不為null,檔名也就會被寫入其中。後續的tmpnam函式呼叫會覆蓋返回值所用的表態儲存區,所以如果tmpnam函式被呼叫多次,實際上是使用乙個字串引數。這個字串假定至少為l_tmpnam字元長。乙個程式中,tmpnam至多可以被呼叫tmp_max次,而且每次都會生成乙個不同的檔名。

如果臨時檔案被立即使用,那麼我們可以同時使用tmpfile函式來對其命名並且開啟。這一點很重要,因為另乙個程式會使用tmpnam返回的相同的名字建立乙個檔案。tmpfile函式避免這種情況的發生:

#include

file *tmpfile(void);

tmpfile函式會返回乙個指向唯一的臨時檔案的流指標。這個檔案會為讀和寫開啟,而且在所有到檔案的引用被關閉以後,這個檔案會被自動刪除。

如果發生錯誤,tmpfile會返回乙個空指標,並且設定errno變數。

試驗--tmpnam與tmpfile

下面讓我們實際的看一下這兩個函式的使用:

#include

int main()

當我們編譯執行程式tmpnam.c時,我們可以看到由tmpnam生成的唯一的檔名:

$ ./tmpnam

temporary file name is: /tmp/file2s64zc

opened a temporary file ok

工作原理

這個程式呼叫tmpnam生成乙個唯一檔名的臨時檔案。如果我們要使用這個臨時檔案,我們可以立即開啟,從而來減小另乙個程式會使用同乙個檔名開啟這個檔案的風險。tmpfile呼叫會同時建立並開啟乙個臨時檔案,從而避免了這種風險。實際上,當編譯乙個使用這個函式的程式時,gnu c編譯器也會給出乙個使用tmpnam的警告。

老版本unix系統還有另乙個使用mktemp與mkstemp函式來生成臨時檔名的方法。這些與被linux系統支援,並且與tmpnam相似,所不同的是我們可以為臨時檔名指定乙個模板,這樣我們就可以更好的控制其位置與名字:

#include

char *mktemp(char *template);

int mkstemp(char *template);

mktemp函式由指定的模板生成乙個唯一的檔名。template必須以6個x開始。mktemp函式使用唯一可用的檔名字元來替換這些x字元。他返回乙個指向所生成的字串的指標,如果不可以生成乙個唯一的檔名,則會返回乙個null指標。

mkstemp函式在建立與開啟臨時檔案方面與tmpfile相類似。檔名由與mktemp相同的方式生成的,但是返回的結果是乙個開啟的,底層檔案描述符。

通常,我們應使用建立與開啟函式tmpfile與mkstemp,而不是tmpnam與mktemp。

使用者資訊

當乙個使用者登陸進linux系統時,他就有乙個使用者名稱與密碼。如果這些通過驗證,系統就會使用者提供乙個shell。通常,使用者具有乙個稱之為uid的唯一的使用者標識。linux執行的所有程式都是執行在使用者的行為以及與其相關的uid上的。

我們可以設定乙個程式的執行,使其看起來就像是另乙個使用者啟動的。當乙個程式具有其uid的許可權集合時,他的執行看起來就像是可執行檔案的擁有者啟動的。當執行su命令時,程式的執行看起來就像是超級使用者啟動的。然後他會驗證使用者的訪問許可權,將其uid改變為目標使用者的uid,然後執行目標使用者的登陸shell。這會允許乙個程式的執行看起來就像是另乙個不同的使用者啟動的,而這通常為系統管理員用來執行維護任務。

因為uid是使用者標識的關鍵,我們就從這裡開始討論。

uid有其自己的型別--uid_t--在sys/types.h中進行了定義。他通常是乙個小整數。一些是由系統預先定義的;另乙個些是當有新使用者要新增到系統時,由系統管理員建立的。通常,使用者的uid值大於100。

#include

#include

uid_t getuid(void);

char *getlogin(void);

getuid函式會返回與程式相關的uid值。這通常是啟動程式的使用者的uid值。

getlogin函式會返回與當前使用者相關聯的登陸名。

系統檔案/etc/passwd包含乙個處理使用者帳戶的資料庫。每個使用者一行,其中包含使用者名稱,加密密碼,使用者標識uid,組標識gid,全名,主目錄,以及預設的shell。下面是其中的乙個例子:

neil:zbqxfqedfpk:500:100:neil matthew:/home/neil:/bin/bash

如果我們要編寫乙個程式來確定啟動程式的使用者uid,我們會對其進行擴充套件來檢視密碼檔案以查詢使用者的登陸名與全名。我們並不推薦這樣做,因為現在的類unix系統都由使用簡單的密碼檔案遷移到加強的系統安全。許多系統,包括linux,有乙個選項可以使用影子密碼(shadwo password)檔案,其中根本就不包含任何有用的加密密碼資訊(這通常存放在使用者不可讀取的/etc/shadow中)。正是因為這個原因,系統定義了一系列函式來為使用者資訊提供標準而高效的程式介面:

#include

#include

struct passwd *getpwuid(uid_t uid);

struct passwd *getpwnam(const char *name);

密碼資料庫結構,passwd,定義在pwd.h中,包含下列成員:

成員 描述

char *pw_name 使用者登陸名

uid_t pw_uid uid值

gid_t pw_gid gid值

char *pw_dir 使用者主目錄

char *pw_gecos 使用者全名

char *pw_shell 使用者預設shell

getpwuid與getpwnam函式都會返回乙個指向對應於乙個使用者的密碼結構指標。對於getpwuid函式,使用者是由uid標識的,而對於getpwnam函式,使用者是由登陸來標識的。如果出錯,他們都會返回乙個空指標並且設定errno變數。

試驗--使用者資訊

這裡有乙個程式,user.c,這會由密碼資料庫中得到一些使用者資訊:

#include

#include

#include

#include

int main()

其程式輸出如下所示,也許在不同的系統上其輸出結果會略有不同:

$ ./user

user is neil

user ids: uid=500, gid=100

uid passwd entry:

name=neil, uid=500, gid=100, home=/home/neil, shell=/bin/bash

root passwd entry:

name=root, uid=0, gid=0, home=/root, shell=/bin/bash

工作原理

這個程式會呼叫getuid函式來得到當前使用者的uid值。這個uid會用在getpwuid函式中來得到詳細的密碼檔案資訊。作為乙個對照,我們演示了如何在getpwnam函式中指定使用者名稱root來得到使用者資訊。

要遍歷密碼檔案資訊,我們可以使用getpwent函式。這會取得連續的檔案實體:

#include

#include

void endpwent(void);

struct passwd *getpwent(void);

void setpwent(void);

getpwent函式會依次返回每個使用者資訊。當到達檔案結尾時,他會返回乙個空指標。一旦搜尋完畢所有的有效實體,我們可以使用endpwent函式來結束處理過程。setpwent函式可以在密碼檔案中重新設定指標使其指向檔案的開頭,這樣當下次呼叫getpwent函式時可以重新開始遍歷。這些函式的操作與我們在第3章所討論的目錄遍歷函式opendir,readdir,closedir相類似。

使用者與組標識可由其他的乙個通常不用的函式來得到:

#include

#include

uid_t geteuid(void);

gid_t getgid(void);

gid_t getegid(void);

int setuid(uid_t uid);

int setgid(gid_t gid);

我們可以檢視系統手冊頁來得到關於組標識與有效使用者標識的更為詳細的內容,儘管我們會發現我們根本就不需要來操作這些函式。

LINUX環境(四) 臨時檔案與使用者資訊

使用臨時檔案要考慮幾個問題 保證臨時檔案間的檔名不互助衝突。保證臨時檔案中內容不被其他使用者或者黑客偷看 刪除和修改。linux中提供了mkstemp 和 tmpfile 函式來處理臨時檔案。mkstemp函式 mkstemp函式在系統中以唯一的檔名建立乙個檔案並開啟,而且只有當前使用者才能訪問這個...

Linux環境(四) 臨時檔案與使用者資訊

臨時檔案 通常,程式需要以檔案的形式使用臨時儲存。這也許是儲存計算的中間結果,或者是在實際操作之前所做的檔案拷貝備份。例如,乙個資料程式在刪除記錄時會使用臨時檔案。檔案會收集需要儲存的資料庫實體,然後在操作結束時,臨時檔案會成為新的資料庫而原始的會被刪除。臨時檔案的大量使用隱藏了他的乙個缺點。我們必...

Linux環境(四) 臨時檔案與使用者資訊

臨時檔案 通常,程式需要以檔案的形式使用臨時儲存。這也許是儲存計算的中間結果,或者是在實際操作之前所做的檔案拷貝備份。例如,乙個資料程式在刪除記錄時會使用臨時檔案。檔案會收集需要儲存的資料庫實體,然後在操作結束時,臨時檔案會成為新的資料庫而原始的會被刪除。臨時檔案的大量使用隱藏了他的乙個缺點。我們必...