2

ジョブ コントロール シェルを構築しようとしていますが、現在バックグラウンド プロセスを処理しています。このプログラムでは、各バックグラウンド プロセスを処理する子プロセスをフォークし、フォークの直後にプロンプ​​トを表示します。しかし、問題は、バックグラウンド プロセスが戻ったときに、プロンプト メッセージが再度出力されることです。この問題を解決するのを手伝ってくれる人はいますか? ありがとう ##

char prompt[] = "myShell";
set_sighandler_SIGCHLD();  //wait for background process return
while(1){
       char cmd[BUFFERSIZE] = "";
       write(1, prompt, sizeof(prompt));
       if(read(0, cmd, 1024) <= 1)){
              //parse command
              //and execute
       }
}
//Here is the background process.
int put_to_background(int (*func)(char** arg), char ** cmd){
     pid_t pid;
     if((pid = fork()) < 0){
         perror("fork");
         return -1;
     }
     else if(pid == 0){
         func(cmd);     //call the function the execute the command
         _exit(0);
     }
     else{
         if(setpgid(pid, 0)){
             perror("setpgid");
             return -1;
         }
         printf("running: %d\n", pid);

     }

関数を呼び出した後、すぐにプロンプ​​ト「myShell」が出力されますが(これは私が期待していたものです)、バックグラウンドプロセスが戻った後にもう一度出力されます。

私はまだ信号処理に取り組んでいます...

 JobList list;
 void sighandler(int signum, siginfo_t *sip, void *ucp){
     if(signum == SIGCHLD){
        pid_t pid;
        while((pid = waitpid(-1, NULL, WNOHANG)) > 0){
           Job * job = (Job*)malloc(sizeof(Job));
           job->pid = pid;
           insert(&list, job);  
       }
     }
     else if(signum == SIGTTOU){
       printf("SIGTTOU: pid = %d\n", (int) sip->si_pid);
     }
     else if(signum == SIGTTIN){
      printf("SIGTTIN: pid = %d\n", (int) sip->si_pid);
     }
 }  

int set_sighandler_SIGCHLD(){

struct sigaction sa;
sigemptyset(&sa.sa_mask);

sigaddset(&sa.sa_mask, SIGCHLD); 
sigaddset(&sa.sa_mask, SIGTTIN);
sigaddset(&sa.sa_mask, SIGTTOU);
sa.sa_sigaction = sighandler;
sa.sa_flags = SA_SIGINFO;
//sigprocmask(SIG_BLOCK, &sa.sa_mask, NULL);

if(sigaction(SIGCHLD, &sa, NULL)){
    perror("sigaction");
    return -1;
}
if(sigaction(SIGTTOU, &sa, NULL)){
    perror("sigaction");
    return -1;
}
if(sigaction(SIGTTIN, &sa, NULL)){
    perror("sigaction");
    return -1;
}
return 0;

}

4

1 に答える 1

0

ループはread信号によって中断されているため、プロンプトを出力します。(つまり、シグナルが到着するとreadすぐに戻ります。)読み取りが-1を返し、が原因で戻ったかどうかを確認するか、シグナルハンドラーにEINTR設定してみてください。これは常に機能するとは限らず(実装に依存し、さまざまな実装に多くのバグがあります)、IMOでは回避するのが最善であるSA_RESTARTことに注意してください。SA_RESTART

于 2012-05-28T13:00:18.653 に答える