Advertisement
Guest User

Untitled

a guest
May 27th, 2015
225
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.26 KB | None | 0 0
  1. //fragen / logout braucht mehrere aufrufe wenn davor ungültige eingabe war (z.B. asdf)
  2.  
  3. #include <cstdlib>
  4. #include <stdio.h>
  5. #include <iostream>
  6. #include <sys/wait.h>
  7. #include <unistd.h>
  8. #include <sys/types.h>
  9. #include <sstream>
  10. #include <cstring>
  11. #include <vector>
  12. #include <signal.h>
  13.  
  14. using namespace std;
  15.  
  16.  
  17.  
  18. pid_t pid; //globale variable als übergabeparameter für handler, handler braucht PID
  19. pid_t pid_stopped;
  20. pid_t parentid;
  21.  
  22.  
  23.  
  24. void handle_SIGTSTP(int signum){        //normalerweise: stop/abbruch von FG prozess durch ctrl-z, z.B. sleep
  25.     cout << "caught SIGTSTP" << endl;  
  26.     cout << pid << endl;
  27.     pid_stopped=pid;                    //pid_stopped erhält die PID von gedit/firefox
  28.     kill(pid_stopped,SIGSTOP);          //hält gedit/firefox an
  29.     return;
  30. }
  31.  
  32. void handle_SIGINT(int signum){         //ausschließlich tastaturinterrupt durch ctrl-c
  33.     cout << "SIGINT aufgerufen " << endl;    
  34.     kill(pid_stopped,SIGINT);           //gedit/firefox wird SIGINT zugestellt, dadurch wird es beendet
  35.     return;
  36. }
  37.  
  38. void handle_SIGCHLD_zombiekiller(int signum){    //beim Beenden von Kindprozess,z.B. gedit aufgerufen
  39.     int stat;
  40.     while(waitpid(-1, &stat, WNOHANG) > 0);      //löscht Zombies aus table / wartet bis sie weg sind
  41.                                                  //WNOHANG verhindert, dass handler blockiert wenn SIGCHILD aus anderen gründen aufgerufen wird
  42.                                                  //http://www.microhowto.info/howto/reap_zombie_processes_using_a_sigchld_handler.html
  43.     return;
  44. }  
  45.  
  46.  
  47. int main(int argc, char** argv) {
  48.     char* inputorg;
  49.     string s;
  50.     vector<pid_t>programme;
  51.    
  52. do{
  53.         cout << "debian@:myShell$ ";  
  54.        
  55.         //handlerdeklaration für SWI
  56.         signal(SIGINT,handle_SIGINT);
  57.         signal(SIGTSTP,handle_SIGTSTP);
  58.         signal(SIGCHLD,handle_SIGCHLD_zombiekiller);
  59.        
  60.        
  61.        
  62.        
  63.         getline(cin,s);      
  64.         const char* cc=s.c_str();        
  65.         inputorg=const_cast<char*>(cc);
  66.        
  67.        
  68.            
  69.         int run_background=0;
  70.         vector<char*>substrings;
  71.        
  72.         char* input=strtok(inputorg, " ");
  73.        
  74.         while (input)
  75.         {
  76.           if (strncmp(input,"&",1)==0)
  77.             {
  78.               run_background = 1;
  79.               break;
  80.             }
  81.           substrings.push_back(input);
  82.          
  83.           input = strtok(NULL," ");
  84.         }
  85.        
  86.        
  87.         substrings.push_back(NULL); //letzte parameter muss immer NULL sein
  88.        
  89.         if(substrings[0]==NULL){
  90.             substrings[0]="error";
  91.             substrings.push_back(NULL);
  92.         }
  93.      
  94.         char* param[substrings.size()];     //gleiche größe wie vector
  95.        
  96.         for(int i=0;i<substrings.size();i++){   //kopiere vector in param
  97.             param[i]=substrings[i];
  98.         }
  99.        
  100.         // PARSING DONE
  101.        
  102.        
  103.        
  104.        
  105.        
  106.        
  107.         if(strncmp(param[0],"fg",2)==0){            
  108.             kill(pid_stopped,SIGCONT);              //führt gedit/firefox fort
  109.             waitpid(pid_stopped, 0, WUNTRACED);     //wartet auf beendigung von gedit/firefox
  110.         }else if(strncmp(param[0],"bg",2)==0){
  111.             kill(pid_stopped,SIGCONT);              //gleiche wie fg, nur wartet nicht, sondern lässt im hintergrund laufen            
  112.         }else{
  113.        
  114.        
  115.                    
  116.         pid=fork();
  117.         parentid=getppid();
  118.        
  119.         if(pid==0){                         //wenn im child prozess
  120.             int mypid=getpid();  
  121.             programme.push_back(mypid);     //speichert alle PIDs von aufgerufenen funktionen
  122.             setpgid(mypid,mypid);          
  123.             execvp(param[0],param);    
  124.         }
  125.        
  126.        
  127.        
  128.         if(run_background!=1){
  129.                 int status;
  130.                 waitpid(pid,&status,WUNTRACED);     //bei & nicht auf childprozess warten
  131.             }          
  132.         }
  133.         }while(s!="logout");
  134.        
  135.         for(int i=0;i<programme.size();i++){  //sollte theoretisch alle prozesse beenden, beendet aber nur letzten..      
  136.             pid_t temppid=programme[i];
  137.             kill(temppid,SIGINT);             //SIGINT beendet prozess
  138.         }
  139.        
  140.     return 0;
  141. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement