如何设置进程C的状态终止?

时间:2018-06-20 16:45:45

标签: c process signals kill-process

我的程序是基本的小外壳。 它允许您以参数ls,cd ...的形式在PATH中运行程序。 要从终端“ ./myshell2”运行程序类型,它将启动,您可以插入所需的命令。

它启动子进程,运行execvp,返回并重新启动,因此您可以键入新命令。 当键入“ Q”或“ q”时,整个程序应终止。 问题是我不知道如何停止它,下面的代码。 我的想法是,当键入“ Q”或“ q”时,杀死所创建的子进程并发送信号以消除其错误终止(子进程)。 因此(来自父项的)最终状态将不是1,并且该函数返回。 我评论了代码的某些部分,希望它更容易理解。 它起作用的问题是要停止它,我需要ctrlC。 我想对子进程说,他必须以一个非零值结尾。

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

int main(int argc, char * argv[]) {
while(1)
{
    pid_t pid = fork();

    if (pid == -1) {
        perror("fork error");
        exit(EXIT_FAILURE);
    }

    if (pid == 0) { // child process
        printf("type the command to start (and arguments if required) \n"
            "Q to quit\n");
        char *dest[10]; // allow you to insert
        char line[4096];//commands from terminal
        if (fgets(line,sizeof(line),stdin)==0) return 1;
        int i;
        line[strcspn(line, "\n")] = '\0';  
        char *st = line;
        for (i=0; i< 10 && (dest[i]=strsep(&st," "))!=NULL;i++)
            continue;//now you typed the command
        if ( ( memcmp(dest[0],"Q",1)==0 ) // if Q or q the program
             || (memcmp(dest[0],"q",1)==0) ) //must end
        {
            printf("got it!\n");
            if (kill(getpid(),SIGSEGV)==-1) printf("kill error\n");
            //in theory the process should terminates with bad status
            // and the value of the variable "status" 'll be not 0
           // I think that the problem is in this part of the code
        }


        if( strcmp(dest[0]," ")!=0 )
        {
            int res = execvp(dest[0], dest);    
         }
        else
            { int res= execvp(dest[1],dest+1);}

       perror("execvp error");
       exit(EXIT_FAILURE);
    }

    int status;
    pid_t child = wait(&status);

    if (child == -1) {
        perror("wait error");
     exit(EXIT_FAILURE);
    }
    if (status==1)
        break; //so it can exit from the loop that creates new process
    setenv("WAIT","TRUE",0);                    //dont' worry about
    //perror("setenv error\n");
    if (memcmp("TRUE",getenv("WAIT"),4) == 0 )  //these 6 lines
        printf("WAIT=TRUE\n");
    else if(memcmp("FALSE",getenv("WAIT"),4) == 0 )
        printf("WAIT=FALSE\n");                     
printf("end current process (status=%d, child=%d)\n", WEXITSTATUS(status), son);
 }
return EXIT_SUCCESS;
}

1 个答案:

答案 0 :(得分:3)

在所有情况下,您都将打印WEXITSTATUS(),但这是不对的。您需要使用wait检查WIFEXITED()返回的状态是否是退出状态。如果非零,则孩子正常退出。否则,您可以使用WIFSIGNALED()查看孩子是否被解雇,并且您将从WTERMSIG()处获得信号

if(WIFEXITED(status))
  {
  printf("end current process (status=%d, child=%d)\n", WEXITSTATUS(status), son);
  }
else if(WIFSIGNALED(status))
  {
  printf("end current process (signal=%d, child=%d)\n", WTERMSIG(status), son);
  }

您确实应该让父进程处理命令的输入,而让子进程运行它。