簡體   English   中英

c 中的 shell 實現問題

[英]Problems with shell implementation in c

幾天來一直致力於簡單的 shell 實現。 但我有兩個問題:

( ) 和 output “權限被拒絕”,因為它進入了 execvp 的錯誤處理,這不應該發生。 (我嘗試了一些不同的方法來阻止它進入 main 中的 if() 但它們沒有用。)

2.如果你輸入回車然后輸入一個命令,該命令將不會被執行。 (我嘗試釋放 buff 並再次分配 memory 但這會導致更多問題。)

所以基本上它進入“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: 斷言`(old_top == initial_top (av) && old_size == 0) || ((unsigned long) (old_size) >= MINSIZE (old_size) >= MINSIZE (old_size) >= MINSIZE 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';
        }

您的parse_cmdline() function 應該測試空行、只有空白行和以#開頭的注釋行並返回NULL是這些情況。

然后,調用代碼應該測試這些行的result是否被忽略。

調用代碼還應該將result[0]與內部命令的名稱進行比較,例如cdchdir並在本地處理它們,而不是調用forkexec

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM