20165322 第七週 mybash 的實現
阿新 • • 發佈:2018-11-25
mybash的實現
要求
- 使用fork,exec,wait實現mybash
- 寫出虛擬碼,產品程式碼和測試程式碼
- 發表知識理解,實現過程和問題解決的部落格
相關函式的作用
- fork
- fork()函式通過系統呼叫建立一個與原來程序(父程序)幾乎完全相同的程序(子程序是父程序的副本,它將獲得父程序資料空間、堆、棧等資源的副本。注意,子程序持有的是上述儲存空間的“副本”,這意味著父子程序不共享這些儲存空間。linux將複製父程序的地址空間內容給子程序,因此,子程序由了獨立的地址空間。),也就是這兩個程序做完全相同的事。
- 在父程序中,fork返回新建立子程序的程序ID;
- 在子程序中,fork返回0;
- 如果出現錯誤,fork返回一個負值
- exec
- exec函式族可以根據指定的檔名或目錄名找到可執行檔案,並用它來取代原呼叫程序的資料段、程式碼段和堆疊段。在執行完後,原呼叫程序的內容除了程序號外,其它全部被新程式的內容替換了。另外,這裡的可執行檔案既可以是二進位制檔案,也可以是Linux下任何可執行指令碼檔案。
- exec函式族可以根據指定的檔名或目錄名找到可執行檔案,並用它來取代原呼叫程序的資料段、程式碼段和堆疊段。在執行完後,原呼叫程序的內容除了程序號外,其它全部被新程式的內容替換了。另外,這裡的可執行檔案既可以是二進位制檔案,也可以是Linux下任何可執行指令碼檔案。
- wait
- wait()會暫時停止現在程序的執行,直到有訊號來到或子程序結束。假如在呼叫wait()時子程序已結束,則wait()會立即返回子程序結束狀態值。
- wait()會暫時停止現在程序的執行,直到有訊號來到或子程序結束。假如在呼叫wait()時子程序已結束,則wait()會立即返回子程序結束狀態值。
虛擬碼
while(1) { 輸出使用者資訊 讀取使用者輸入命令存入陣列和檔案 呼叫fork()函式,若返回值不為0,則呼叫wait() 若返回值為0,呼叫exec() }
產品程式碼
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pwd.h>
#include <sys/wait.h>
#define N 100
#define order_length 128
#define order_num 64
#define empty 0
#define chars 1
void main()
{
while(1) {
struct passwd *my_info;
char path[N];
my_info = getpwuid(getuid());
getcwd(path, sizeof(path));
printf("[% [email protected]%s]$ ", my_info->pw_name, path);//輸出使用者及路徑
char str[N];
char a[N];
char *argv[N]={NULL};
char *envp[]={0,NULL};
int i,j = 0, flag=1;
fgets(str,N,stdin); //讀取輸入的命令
str[N - 1] = '\0';
if(feof(stdin))
{
printf("error");
exit(0);
}
for(i=0;str[i]!='\0'&&i<N&&j<N;i++) {
if(str[i] == ' ' || str[i] == '\n') {
flag=1;
str[i] = '\0';
}
else if(flag==1) {
argv[j++] = &str[i];
flag=0;
}
}
if(fork() != 0) wait(NULL); //呼叫fork()
else {
execvp(argv[0], argv);
perror("execlp error");
exit(0);
}
}
}
測試結果
測試了ls
,ls -l``tree``clear
指令,測試截圖如下:
尚有一部分命令無法實現,例如“cd”等等……