2016-04-12 8 views
0

私はいくつかのゾンビプロセスをバックグラウンドで実行していますが、私はそれらを殺す方法があまりよく分かりません。私はミニシェルを作っているので、それは基本的にターミナルのようですが、それ自身のバージョンです。ここでゾンビを飼う? [C]

は私のコードです:ここでは

#include <stdio.h> 
#include <string.h> 
#include <stddef.h> 
#include "main.h" 

int main() { 

    /* Declared variables */ 
    char buff[100]; 
    char* args[20]; 
    int arguments = 20; 

    /* Boolean value */ 
    int done = 0; 

    while(done != 1) { 
     /* Print directory */ 
     printf("%s>", getcwd(0,0)); 
     /* Gets input */ 
     fgets(buff, 100, stdin); 

     /* Checks to see if anything was entered */ 
     if (buff[0] == '\n') { 
      printf("Error: Enter a command! (Example: ls -l)\n"); 
     } else { 
      parseArgs(buff, args, 20, &arguments); 

      if (*args[0] == '\n') { 
       printf("Error: Enter a command! (Example: ls -l)\n"); 
      } else if (strcmp(args[0], "exit") == 0) { 
       done = 1; 
      } else if (strcmp(args[0], "cd") == 0) { 
       /* Changes the directory */ 
       int dir = chdir(args[1]); 
       if (dir != 0) { 
        printf("That directory isn't valid!\n"); 
       } 
      } else { 

       int background = 0; 
       int count = 0; 

       /* Create a new process */ 
       int process = fork(); 
       if (process == -1) { 
        printf("Error: Unable to create a process!"); 
       } else if (process == 0) { 

        /* Run user input */ 
        int res = execvp(args[0], args); 
        if (res == -1) { 
         printf("\nError: Enter a command! (Example: ls -l)\n"); 
         done = 1; 
        } 

        int reapingInfo; 
        waitpid(process, &reapingInfo, 0); 
       } 
      } 
     } 
    } 
return (0); 
} 

は、私は数回ls -lを実行し、コマンドを実行したときに、私は出力として取得していますものです:ps

20978 pts /6  00:00:00 bash 
21049 pts /6  00:00:00 main 
21050 pts /6  00:00:00 ls <defunct> 
21051 pts /6  00:00:00 ls <defunct> 
21062 pts /6  00:00:00 ps 

上の任意の手がかりこれらの恩恵を受ける方法defunct

答えて

2

ロジックがfork()のように正しく表示されません。 else if (process == 0)があり、そのブランチ(子プロセス内)にを呼び出そうとしたときにの後に新しいプログラムとを実行します。 execvpは、実行が成功した場合は返さないので、ほとんどの場合、waitpidは呼び出されません。

どこかにelseがありません。 waitpidは、親で行わなければなりません(fork()が厳密に正の値を返すプロセス)。その後、waitpidはゾンビを収穫します。それはその仕事です。

execvpが失敗した場合ところで、あなたはおそらく_exit()を呼びたい。子供が完了するまで実行し続けまかせことはおそらく正しいではありません。例えば、標準入出力バッファ内のデータを二回書くことができます。)

0

ここでは、あなたのコードで動作する必要があるfork/exec/waitpidの使用例を見ることができます:

/* Create a new process */ 
int process = fork(); 
if (process == -1) { 
    printf("Error: Unable to create a process!"); 
} else if (process == 0) { 
    /* Run user input */ 
    int res = execvp(args[0], args); 
    /* execvp only returns if it fails, not need to check if res == -1 */ 
    printf("\nError: Enter a command! (Example: ls -l)\n"); 
    exit(1); /* kill this process, if exec fails! */ 
} else { 
    int reapingInfo; 
    waitpid(process, &reapingInfo, 0); 
} 
関連する問題