如何重新命名一個檔案?
如果需要對一個檔案進行複製和刪除,那麼最快的方法是重新命名一個檔案。所需要時間就在一個cpu周期裡面,是原子操作。
比如,做一個登入登出記錄檔管理系統,你需要統計每天的記錄檔資訊,這時候,你需要複製系統記錄檔wtmpx,但是如果你一條資料一條資料或者一個位元組一個位元組的複製副本,效率會很低,而且這時候可能還有使用者登入或者登出系統,需要用到記錄檔記錄,而這時候由於你又在使用這個記錄檔,會照成衝突。這時候是不能用檔案鎖解決問題的。因為使用記錄檔的是系統,你不能跟核心協商使用鎖的協議。最好的辦法,重新命名這個記錄檔。
#include<stdio.h>
#include<unistd.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<stdlib.h>
int main()
{
char p[20] = "ttwo.c";
char pt[20] = "two.c";
int pid = fork();
if(pid<0)
{
return -1;
}
else if(pid==0)
{
execl("/bin/mv","mv",pt,p,NULL);
exit(0);
}
int status;
waitpid(pid,&status,0);
printf("open ttwo.c\n");
int fd = open(p,O_RDONLY);
if(fd>0)
printf("open success\n");
close(fd);
return 0;
}
(1)exec函數族說明
fork 函數是用於建立一個子進程,該子進程幾乎拷貝了父進程的全部內容,但是,這個
新建立的進程如何執行呢?這個exec 函數族就提供了一個在進程中啟動另一個程式執行的
方法。它可以根據指定的檔案名稱或目錄名找到可執行檔,並用它來取代原調用進程的資料
段、程式碼片段和堆棧段,在執行完之後,原調用進程的內容除了進程號外,其他全部被新的進
程替換了。另外,這裡的可執行檔既可以是二進位檔案,也可以是Linux 下任何可執行檔
指令檔。
在 Linux 中使用exec函數族主要有兩種情況:
· 當進程認為自己不能再為系統和使用者做出任何貢獻時,就可以調用任何exec 函數族
讓自己重生;
· 如果一個進程想執行另一個程式,那麼它就可以調用fork 函數建立一個進程,然後
調用任何一個exec,這樣看起來就好像通過執行應用程式而產生了一個新進程。(這種情況
非常普遍)(2)exec函數族文法
實際上,在Linux 中並沒有exec()函數,而是有6 個以exec開頭的函數族,它們之間語
法有細微差別,在下面會詳細講解。exec 函數族成員函數文法所需標頭檔#include <unistd.h> 函數原型 int execl(const char *path, const char *arg, ...)
int execv(const char *path, char *const argv[])
int execle(const char *path, const char *arg, ..., char *const envp[])
int execve(const char *path, char *const argv[], char *const envp[])
int execlp(const char *file, const char *arg, ...)
int execvp(const char *file, char *const argv[])函數傳回值-1:出錯這 6 個函數在函數名和使用文法的規則上都有細微的區別,下面就可執行檔尋找方式、
參數表傳遞方式及環境變數這幾個方面進行比較。
· 尋找方式
讀者可以注意到,表7.3 中的前4 個函數的尋找方式都是完整的檔案目錄路徑,而最後
2個函數(也就是以p結尾的兩個函數)可以只給出檔案名稱,系統就會自動從環境變數“$PATH”
所指出的路徑中進行尋找。
· 參數傳遞方式
exec函數族的參數傳遞有兩種方式:一種是逐個列舉的方式,而另一種則是將所有參數
整體構造指標數組傳遞。
在這裡是以函數名的第5 位字母來區分的,字母為“l”(list)的表示逐個列舉的方式,
其文法為char *arg;字母為“v”(vertor)的表示將所有參數整體構造指標數組傳遞,其文法
為*const argv[]。讀者可以觀察execl、execle、execlp的文法與execv、execve、execvp的區別。
它們具體的用法在後面的執行個體講解中會舉例說明。
這裡的參數實際上就是使用者在使用這個可執行檔時所需的全部命令選項字串(包括
該可執行程式命令本身)。要注意的是,這些參數必須以NULL 表示結束,如果使用逐個列
舉方式,那麼要把它強制轉化成一個字元指標,否則exec將會把它解釋為一個整型參數,如果一個整型數的長度char *的長度不同,那麼exec函數就會報錯。
· 環境變數
exec 函數族可以預設系統的環境變數,也可以傳入指定的環境變數。這裡以“e”
(Enviromen)結尾的兩個函數execle、execve 就可以在envp[]中指定當前進程所使用的環境
變數。exec 函數名對應含義
前4位統一為:execl:第5位 l: 參數傳遞為逐個列舉方式execl、execle、execlp
v:參數傳遞為構造指標數組方式execv、execve、execvp第6位 e:可傳遞新進程環境變數execle、execve
p:可執行檔尋找方式為檔案名稱execlp、execvp