2012-02-18 13 views
2

私のオペレーティングシステムクラスでは、以前の割り当てに基づいて割り当てが行われています。残念ながら、私の前のプロジェクトは、私が次のプロジェクトのためにどこから始める必要があるか分からず、正しく機能しません。以下のコードは、単純なUNIX/Linuxシェルを模倣して、execvpで実行できないいくつかの追加のコマンド、アンパサンド演算子によるバックグラウンド処理、 'jobs'シェルコマンドを模倣すると仮定しています。つまり、終了していないもの)、 "ゾンビ"プロセスの "刈り取り"、 "cd"シェルコマンド:シェルの作業ディレクトリを変更します。Cで実装されたUNIXコマンド

"jobs"コマンドと "cd"コマンドを除いてすべてが機能すると信じていますが、なぜこれら2つの理由がわからないのでしょうか。

次の割り当てが

#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; 
} 
...私も本当に開始するか分からない「mysh $ cmdの引数1 arg2のARGN> file.out」の形でいくつかのI/Oリダイレクションを追加することです
+1

'chdir'は親プロセスや兄弟プロセスに影響しないことに注意してください。また、出口のいくつかは疑わしい場所に配置されるように見える... –

+0

@pst私はあなたが今言っていることを間違いなく理解していますが、その後chdirと何をするべきかわかりません...アドバイス? –

+0

['while(!feof(file))'は常に間違っています。](http://stackoverflow.com/questions/5431941/while-feof-file-is-always-wrong) –

答えて

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); 

物事に注意すること:

  • 私は、コードをテストしていない - それも私がずっとエラーチェックをしませんでした
  • コンパイルしない可能性があります - もしあなたが、私は別の関数を使用する方法、独自の
  • STDIN_FILENOリダイレクトを実装する必要が
  • (私はopenのために行った方法)、あなたべきはそれなりに広く
  • コードには7レベルのインデントがあります。これまでにarrow codeについて聞いたことがありますか?
0

これは宿題なので、直接コードを与えることはありません。

dup,dup2およびfreopenは、入出力リダイレクトを調べるのに適しています。あなたは子プロセスを享受するためにwaitpidを使用して正しい軌道に乗っている同時プロセス(アンパサンド)

を開始するための

fork

関連する問題