幾天來一直在研究一個簡單的 shell 實作。但我有兩個問題:
1.當您運行該程式并鍵入類似“/bin/ls -l /usr/include”的命令然后按回車鍵時,它將執行該命令,但如果您輸入幾行新行,該程式仍將進入 execvp( ) 并輸出“權限被拒絕”,因為它進入了 execvp 的錯誤處理,而這不應該發生。(我嘗試了一些不同的方法來阻止它進入 main 中的 if() 但它們沒有用。)
2.如果你輸入回車然后輸入命令該命令將不會被執行。(我嘗試釋放 buff 并再次分配記憶體,但這導致了更多問題。)
所以基本上它會進入“if(buff[offset] == '\n')”,即使該行在不應該是空的時候也不會執行,除非它是啟動程式后的第一個輸入,否則它不會執行命令。
代碼:
int fd = 0;
const size_t read_size = 1;
size_t size = read_size;
char *buff = malloc(size 1);
size_t offset = 0;
size_t res = 0;
write(STDOUT_FILENO, "$ ", strlen("$ "));
while((res = read(fd, buff offset, read_size)) > 0)
{
if(buff[offset] == '\n')
{
buff[offset] = '\0';
char **result = parse_cmdline(buff); // turn string into array for execvp()
int exec;
int status;
pid_t pid = fork();
if(pid == -1) {/*error handling*/}
else if(pid == 0)
{
if((exec = execvp(result[0], result)) == -1) {/*error handling*/}
}
else
{
waitpid(pid, &status, 0);
}
offset = 0;
free(result[0]);
free(result);
result = NULL;
write(STDOUT_FILENO, "$ ", strlen("$ "));
}
offset = res;
if (offset read_size > size)
{
size *= 2;
buff = realloc(buff, size 1);
}
buff[offset] = '\0';
}
free(buff);
return 0;
更新:適用于在第一行之后輸入的命令,但在每種情況下都會出現錯誤:
"a.out: malloc.c:2379: sysmalloc: Assertion `(old_top == initial_top (av) && old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && (( unsigned long) old_end & (pagesize - 1)) == 0)' 失敗。中止(核心轉儲)”
更新代碼:
if(buff[offset] == '\n')
{
buff[offset] = '\0';
char **result = parse_cmdline(buff);
if(result[0] != NULL)
{
int exec;
int status;
pid_t pid = fork(); // create the child process
if(pid == -1) // check for fork() errors (no memory, etc.)
{
fork_error();
}
else if(pid == 0) // Handle child process
{
if((exec = execvp(result[0], result)) == -1) // run the command itself and check if an error will occur (invalid command, etc.)
{
file_error(result[0]);
}
}
else // Handle parent process
{
waitpid(pid, &status, 0);
}
offset = 0;
free(buff);
size = read_size;
free(result[0]);
free(result);
result = NULL;
}
write(STDOUT_FILENO, "$ ", strlen("$ "));
}
else
{
offset = res;
if (offset read_size > size)
{
size *= 2;
buff = realloc(buff, size 1);
}
buff[offset] = '\0';
}
uj5u.com熱心網友回復:
您的parse_cmdline()函式應該測驗空行、僅包含空格的行#以及以開頭和回傳的注釋行NULL是這些情況。
然后呼叫代碼應該測驗result這些行是否被忽略。
呼叫代碼還應該result[0]與內部命令的名稱進行比較,例如cdorchdir并在本地處理它們,而不是呼叫forkand exec。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/396792.html
