2012-02-18 93 views
2

對於我的操作系統類,我有一個應用程序,該應用程序是構建到以前的作業上的。不幸的是,我以前的項目不能正常工作,除了我不知道我需要從哪裏開始下一個項目。下面的代碼假設模仿一個簡單的UNIX/Linux shell,其中包含一些無法使用execvp執行的命令:通過&符號操作符進行後臺處理,'jobs'shell命令:列出所有活動子進程的pid即不是已經終止的那些),「殭屍」進程的「收穫」以及'cd'shell命令:更改shell的工作目錄。UNIX中執行的命令C

我相信,除了「jobs」命令和「cd」命令之外的所有東西都可以工作,但我不確定爲什麼這兩個都不是。

下一個任務是添加一些I/O重定向在 「mysh $ CMD ARG1 ARG2 ARGN> file.out」 我不知道在哪裏,甚至真正開始的形式...

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <strings.h> 
#include <unistd.h> 
#include <wait.h> 
#include <signal.h> 
#include <sys/types.h> 

int main(int argc, char **argv) { 
    char bBuffer[BUFSIZ], *pArgs[10], *aPtr = NULL, *sPtr; 
    int jobs[100]; 
    int jobList = 0; 
    int background; 
    ssize_t rBytes; 
    int aCount; 
    pid_t pid; 
    int status; 
    while(!feof(stdin)) { 
     pid = waitpid(-1, &status, WNOHANG); 
     if (pid > 0) 
     printf("waitpid reaped child pid %d\n", pid); 
     write(1, "\e[1;31mmyBash \e[1;32m# \e[0m", 27); 
     rBytes = read(0, bBuffer, BUFSIZ-1); 
     if(rBytes == -1) { 
     perror("read"); 
     exit(1); 
    } 

    bBuffer[rBytes-1] = '\0'; 
    if(!strcasecmp(bBuffer, "exit")){ 
     exit(0); 
    } 

    sPtr = bBuffer; 
    aCount = 0; 
    do { 
     aPtr = strsep(&sPtr, " "); 
     pArgs[aCount++] = aPtr; 
    } while(aPtr); 
     background = (strcmp(pArgs[aCount-2], "&") == 0); 
     if (background) 
     pArgs[aCount-2] = NULL; 

     if (strlen(pArgs[0]) > 1) { 
      pid = fork(); 
      if (pid == -1) { 
       perror("fork"); 
       exit(1); 
      } else if (pid == 0) { 
       jobs[jobList] = pid; 
       jobList++; 

       if(!strcasecmp(pArgs[0], "jobs")){           
        for(int i; i<jobList; i++) { 
         if(kill(jobs[i],0)==0){ 
          printf(jobs[i]);  
         } 
         printf("these are jobs\n"); 
         exit(1); 
        } 
        if(!strcasecmp(pArgs[0], "cd")){ 
         int ret; 
         if (!pArgs[1]) 
          strcpy(bBuffer, "pwd"); 
         ret = chdir(pArgs[1]); 
         strcpy(bBuffer, "pwd"); 
         exit(1); 
        }         
        fclose(stdin); 
        fopen("/dev/null", "r"); 
        execvp(pArgs[0], pArgs); 
        exit(1); 
       } else if (!background) { 
        pid = waitpid(pid, &status, 0); 
        if (pid > 0) 
         printf("waitpid reaped child pid %d\n", pid); 
       } 
     } 
    } 
    return 0; 
} 
+1

請記住'chdir'不會影響父進程或兄弟進程。此外,一些'退出'看起來被放置在可疑的位置... – 2012-02-18 07:57:04

+0

@pst我明白你現在說的話,但我不知道如何處理chdir然後...任何建議? – 2012-02-19 01:29:30

+0

['while(!feof(file))'總是出錯](http://stackoverflow.com/questions/5431941/while-feof-file-is-always-wrong)。 – 2015-04-07 04:25:34

回答

2

首先,您需要解析您的線路並檢測是否需要重定向到文件。所以我們假設你使用strsep或其他什麼,你會發現輸出是file.out或輸入來自file.in

此時您想要使用dup/dup2重定向輸出。例如,重定向STDOUT

int 
do_redirect(int fileno, const char *name) 
{ 
    int newfd; 

    switch (fileno) { 
    case STDOUT_FILENO: 
     newfd = open(name, O_WRONLY | O_CREAT, S_IRUSR | S_IRUSR); 
     break; 
    } 
    if (newfd == -1) { 
     perror("open"); 
     return -1; 
    } 

    return dup2(fileno, newfd); 
} 
/* ... */ 


pid = fork(); 
do_redirect(STDOUT_FILENO, name); 

注意事項:

  • 我沒有測試的代碼 - 甚至都不編譯
  • 我沒有做太多的錯誤檢查 - 你應該(我爲open的方式)
  • 你需要實現自己的
  • 注意我是如何用一個單獨的函數STDIN_FILENO重定向,您main是方式大,因爲它是
  • 你的代碼有類似7級縮進 - 曾聽說過arrow code
0

由於這是作業,我不會直接給你代碼。

dupdup2freopen是很好看的輸入/輸出重定向。

fork用於啓動併發進程(符號)

您使用waitpid收穫子進程在正確的軌道上。