Advertisement
Guest User

Untitled

a guest
Oct 21st, 2016
61
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.41 KB | None | 0 0
  1. /**************************************************************************
  2.  * Student name and No.: Ho Hilary 3035229306
  3.  * Development platform: Ubuntu 14.04 VM
  4.  * Last modified date:
  5.  * Compilation: gcc myshell.c -o myshell
  6.  */
  7.  
  8. #include <errno.h>
  9. #include <unistd.h>
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <sys/types.h>
  14. #include <sys/wait.h>
  15.  
  16. //signal handler declaration
  17. void sigint_handler(int signum) {
  18.     if(signum ==SIGUSR1){
  19.         printf("Received SIGUSR1!\n");
  20.     }else {
  21.     printf(" Program terminated\n");
  22.     }
  23. }
  24.  
  25. int main() {
  26.   //variable declaration
  27.  
  28.     //for timeX print out statisticc
  29.     char str[50];
  30.     FILE * file;
  31.     int z;
  32.     //unsigned long long i, x;
  33.     unsigned long h, ut, st;
  34.  
  35.     char input[1024];   //store user input
  36.     char *split[1024];  //split the input into
  37.     int a=0;
  38.  
  39.       int childtype=0; //to indicate if it is background(1) or foreground(2) child process
  40.     int result;     //store result of waitid() from parent process
  41.     siginfo_t info; //signal type
  42.  
  43.    
  44.  
  45.   //start of program
  46.  
  47.     //prompt ##myshell $ and get the input from user and store in "input"
  48.     printf("##myshell $");
  49.     fgets(input, 1024,stdin);
  50.  
  51.     //loop until "exit" command appears
  52.     while(strcmp(input,"exit\n")!=0){
  53.  
  54.         //remove the newline character at the end of the input
  55.         if (input[strlen(input) - 1] == '\n') {
  56.                 input[strlen(input) - 1] = '\0';
  57.         }
  58.  
  59.         //check if the input has the character '&'
  60.         if(strstr(input,"&")!=NULL){
  61.             if(input[strlen(input)-1]!='&'){  //the input has '&' but not at the end position
  62.                  printf("'&' should not appear in the middle of the command line\n");
  63.             }else{  //the input has '&' at the end
  64.                 childtype =1;  //define it as background child process
  65.             }
  66.  
  67.         //get process statistics
  68.       }else if(strcmp(input,"timeX")==0){   //the input is exactly "timeX"
  69.  
  70.                 printf("myshell: \"timeX\" cannot be a standalone command\n");
  71.  
  72.  
  73.                 sprintf(str, "/proc/%d/stat", (int)getpid());
  74.                 file = fopen(str, "r");
  75.                 if (file == NULL) {
  76.                     printf("Error in open my proc file\n");
  77.                     exit(0);
  78.                 }
  79.                 fscanf(file, "%d %s %c %d %d %d %d %d %u %lu %lu %lu %lu %lu %lu", &z, str, &str[0], &z, &z, &z, &z, &z,
  80.                        (unsigned *)&z, &h, &h, &h, &h, &ut, &st);
  81.                 fclose(file);
  82.                 printf("PID \t CMD \t UTIME \t STIME\n");
  83.                     //remove the newline character of the input
  84.                     if (input[strlen(input) - 1] == '\n') {
  85.                         input[strlen(input) - 1] = '\0';
  86.                     }
  87.                 printf("%d\t %s\t %.2lfs\t %.2lfs\n",(int)getpid(),input, ut*2.0f/sysconf(_SC_CLK_TCK),st*1.0f/sysconf(_SC_CLK_TCK));
  88.  
  89.  
  90.           }else if ((strstr(input,"timeX")!=NULL) & (input[strlen(input)-1]=='&')){    //"timeX" command ends with '&'
  91.                 printf("myshell: \"timeX\" cannot be run in background mode\n");
  92.             }
  93.         else {
  94.  
  95.         //create child process to execute command
  96.            int pid = fork();
  97.                if (pid < 0) {
  98.                 printf("Cannot create child process successfully!");
  99.             } else if (pid == 0) {  //run child process
  100.               childtype =2;  ////define it as foreground child process
  101.  
  102.                 // printf("It is a foreground process with type %d\n", childtype);
  103.                 //printf("I am a child process, with pid: %d\n", (int) getpid());
  104.  
  105.           //split the input into small pieces with delimiter of a space " "
  106.           split[a] = strtok(input," ");
  107.             while(split[a]!=NULL)
  108.             {
  109.                split[++a] = strtok(NULL," ");
  110.             }
  111.  
  112.             if ((strcmp(split[0],"exit")==0)&& split[1]!=NULL){    //there are other input after "exit" command
  113.                 printf("myshell: \"exit\" with other arguments!!!\n");
  114.             }
  115.             else{
  116.             //locate and execute program with aboslute
  117.                 execvp(split[0],split);
  118.             char *path[] = {"HOME=/home","LOGNAME=home",(char *)0};
  119.                 execve(split[0],split,path);
  120.  
  121.             //input path cannot be found
  122.             if (execvp (split[0], split) == -1) {
  123.                 printf("myshell: \'%s \': No such file or directory\n", input);
  124.                 exit(-1);
  125.             }
  126.             printf("These lines should never be printed\n");
  127.             exit(0);
  128.           }
  129.  
  130.           } else {
  131.             //run parent process
  132.             pid_t child_pid;
  133.             child_pid = waitpid(pid,NULL,0);
  134.               if(child_pid>0){}
  135.             //printf("I am a parent process, with pid: %d and my child's pid is %d\n",(int) getpid(), (int) pid);
  136.                 //printf("Parent: OK\n");
  137.  
  138.               if(childtype==1) { // if it is a background child process.
  139.                         signal(SIGCHLD,sigint_handler);// handle SIGCHLD signal
  140.                     }
  141.  
  142.                     if(childtype ==2){ //if it is a foreground child process
  143.                         result = waitid(P_ALL,0,&info,WCONTINUED);
  144.                         if(result ==-1){ //error
  145.                         //printf("Program terminated.%d\n",status.si_signo);
  146.                     }
  147.  
  148.                                 }
  149.                 }
  150.           }
  151.           //prompt the user and get input from user
  152.              printf("##myshell $");
  153.            fgets(input, 1024,stdin);
  154.     }//end of while loop
  155.  
  156.   //"exit" command is typed
  157.     printf("myshell: Terminated\n");
  158.   return 0;
  159. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement