Home:ALL Converter>Using SIGINT and SIGTSTP to handle foreground processes a unix shell

Using SIGINT and SIGTSTP to handle foreground processes a unix shell

Ask Time:2017-11-15T05:22:36         Author:Karsten Hertenstein

Json Formatter

I have some questions regarding the use of SIGINT and SIGTSTP in relation to managing processes in my own unix shell. But first of the code here:

void execute(vector<char *> argvv, bool x){


     pid_t pid;
     int status;
     int error;

     pid = fork();
     a = pid;

     argvv.push_back(NULL);

     if(pid == -1){
         cout << "error" << endl;
     }else if(pid == 0){
         error = execvp(argvv[0],argvv.data());

         if(error == -1){
             exit(-1);
         }
         // In Child Process

     }else{
         // If no "&", then wait for process

         if(x == false){
             if(wait(&status) != pid){
                 perror("wait()");
             }
         }else{
             cout << "Pid des Hintergrundprozesses: " << pid <<      endl;     
         }

         // in parent process
     }
 }

This function just receives the entered operation and parameters, forks a new process and executes it.

Now my signalhandler functions:

 void signalHandlerSigInt(int signum){
     cout << "Interrupt Signal (" << signum <<") received." << endl;

     kill(a,SIGINT);

     cout << "Killed Process: " << a << endl;
 }

 void signalHandlerSigTStp(int signum){
     cout << "Interrupt Signal (" << signum <<") received." << endl;

     kill(a,SIGTSTP);

     cout << "Stop process..: " << a << endl;
 }

and my main.cpp:

int main(int agc, char** argv) {

     bool opBackground;
     string operation;
     vector<string> arguments;
     vector<char *> argvv(arguments.size() + 1);



     signal(SIGINT, signalHandlerSigInt);
     signal(SIGTSTP, signalHandlerSigTStp);


     while(true){
         cout << "myshell>";
         getline(cin,operation);


         if(operation == "logout"){
             logout();
         }else{
             opBackground = befehlUebersetzen(operation, &arguments);

             vector<char *> argvv(arguments.size() + 1);            
             for(size_t i = 0; i != arguments.size(); ++i){
                 argvv[i] = &arguments[i][0];
             }

             execute(argvv, opBackground);
             arguments.clear();
         }


     }

     return 0;
 }

The shell itself works fine, I now need to extend it to be able to kill the foreground process by pressing CTRL+C or stop the process with CTRL+Z.

I think I understood what a Signalhandler does, but is kill(a,SIGINT) the right way to transmit the signal SIGINT to my process? ("a" is a global variable for my forked pid, that means the last process I forked).

My problem is, when starting a process in the background and then start another process in the foreground it kills both processes when pressing CTRL+C.

Also the SIGTSTP signalhandler doesnt seem to work at all (does nothing - process just keeps running in the foreground).

Am I completely wrong with what im doing?

Author:Karsten Hertenstein,eproduced under the CC 4.0 BY-SA copyright license with a link to the original source and this disclaimer.
Link to original article:https://stackoverflow.com/questions/47295429/using-sigint-and-sigtstp-to-handle-foreground-processes-a-unix-shell
yy