Advertisement
Guest User

Untitled

a guest
Oct 16th, 2019
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.49 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include<string.h>
  4. #include<unistd.h>
  5. #include<sys/types.h>
  6. #include<sys/wait.h>
  7. #include<signal.h>
  8. #include <time.h>
  9.  
  10. #define clear() printf("\033[H\033[J")
  11. #define LINEMAX 500 // MAX LIMIT FOR USER CHARACTER INPUT
  12. #define TOKENSMAX 20 // MAX LIMIT FOR COMMAND TOKEN
  13. #define pwd 1
  14. #define cd 2
  15. #define ls 3
  16.  
  17.  
  18. void signalHandler(int sig_num); //FUNCTION TO RECORD THE SIGCHILD SIGNAL IN LOG FILE
  19. void changeDir(char * args[]); //UTILITY FUNCTION TO CHANGE DIRECTORY
  20. void printDir(); // UTILITY FUNCTION TO PRINT CURRENT DIRECTORY
  21. void commandHandler(char * args[], int args_count); //FUNCTION TO HANDLE ENTERED COMMANDS
  22. int parseInput(char line[], char * tokens[]); // PARSE INPUT BY SEPARATING WITH SPACE
  23. char* getCurrentTime();
  24.  
  25. int main()
  26. {
  27. char input[LINEMAX]; // USER INPUT
  28. char * commands[TOKENSMAX]; // COMMAND TOKENS
  29. int commands_count=0,exit_flag=1;
  30. struct sigaction sig; // DEFINING SIGACTION STRUCT TO HANDLE SIGNALS
  31.  
  32. sig.sa_handler = signalHandler; // LINKING SA_HANDLER WITH IMPLEMENTATION OF SIGNAL HANDLER
  33. sigemptyset(&sig.sa_mask); // SET ZEROES
  34. sigaction(SIGCHLD,&sig,NULL); // CALL SIGNAL HANDLER ON CHILD TERMINATION
  35. printf("\t\t\t\tWelcome @%s\n\n",getenv("USER")); // WELCOME MESSAGE
  36. printf("The aim of this project is to create a simple Unix Shell program\ncapable of launching child processes. The project was created as a partial\nsimulation of the actual Unix terminal\n");
  37.  
  38. while(exit_flag==1)
  39. {
  40.  
  41. printDir(); //PRINT CURRENT DIRECTORY AFTER EACH LOOP
  42. fgets(input, LINEMAX, stdin); // READ USER INPUT
  43. commands_count=parseInput(input,commands); // PARSE USER'S INPUT AND STORE TOKEN COUNT
  44. if(commands_count==0)
  45. {
  46. continue;
  47. }
  48. if(strcmp(commands[0],"exit()") == 0) // IF COMMAND IS EXT(), TERMINATE
  49. {
  50. exit_flag=0;
  51. exit(0);
  52. }
  53. commandHandler(commands,commands_count); // HANDLE THE PARSED COMMANDS
  54. }
  55.  
  56. return 0;
  57. }
  58.  
  59. //FUNCTION TO RECORD THE SIGCHILD SIGNAL IN LOG FILE
  60. void signalHandler(int sig_num)
  61. {
  62. FILE *fp;
  63. char time[40];
  64. strcpy(time,getCurrentTime());
  65. fp=fopen("MYSIMPLESHELL.log","a+");
  66. if(fp == NULL)
  67. printf("\nERROR: OPENING FILE FAILED");
  68. else fprintf(fp,"%sCHILD PROCESS TERMINATED SUCCESSFULLY SIGNUM %d\n",time,sig_num);
  69. fclose(fp);
  70. }
  71.  
  72. char* getCurrentTime()
  73. {
  74. time_t rawtime;
  75. struct tm * timeinfo;
  76. time ( &rawtime );
  77. timeinfo = localtime (&rawtime);
  78. return asctime (timeinfo);
  79. }
  80.  
  81. // UTILITY FUNCTION TO PRINT CURRENT DIRECTORY
  82. void printDir()
  83. {
  84. char currentDir[1024];
  85. getcwd(currentDir, sizeof(currentDir));
  86. printf("\nDir: %s :~$ ", currentDir);
  87. }
  88.  
  89. //UTILITY FUNCTION TO CHANGE DIRECTORY
  90. void changeDir(char * args[])
  91. {
  92. if (args[1] == NULL)
  93. chdir(getenv("HOME")); // ONLY CD written
  94. else
  95. {
  96. if (chdir(args[1]) == -1)
  97. printf(" %s: ERROR: DIRECTORY NOT AVAILABLE\n", args[1]);
  98. }
  99. }
  100.  
  101. //FUNCTION TO HANDLE COMMANDS ENTERED
  102. void commandHandler(char * args[], int args_count)
  103. {
  104. int count = args_count;
  105. int back_flag = 0; //SET BACKGROUND FLAG TO NO
  106.  
  107. if(!(strcmp(args[count-1],"&"))) //CHECK FOR BACKGROUND PROCESS INDICATOR '&'
  108. {
  109. back_flag=1; //SET BACKGROUND FLAG TO YES
  110. args[count-1]='\0'; //REMOVING *&
  111. count--;
  112. }
  113. // EXECUTE THE ENTERED COMMAND
  114. pid_t pid=fork(); //PROCESS ID
  115. if (pid >= 0) // FORKING SUCCESSFUL
  116. {
  117. if(pid == 0) //CHILD EXECUTING
  118. { if(execvp(args[0],args)<0)
  119. {
  120. printf("ERROR: COMMAND COULDN'T BE EXECUTED!");
  121. }
  122. }
  123. else
  124. {
  125. if(back_flag==1)
  126. return;
  127. else
  128. {
  129. wait(NULL);
  130. // SUSPEND PARENT TILL CHILD CHANGES STATE
  131. }
  132. }
  133. }
  134. else
  135. printf("\nFORKING FAILED!");
  136. }
  137.  
  138. // PARSE INPUT BY SEPARATING BY WHITESPACES
  139. int parseInput(char line[], char * command_tokens[])
  140. {
  141. int i=0;
  142. if((command_tokens[i] = strtok(line," \n\t")) == NULL)
  143. return 0; // CASE OF NO INPUT, RETURN 0
  144. i=1;
  145. while((command_tokens[i] = strtok(NULL, " \n\t")) != NULL) // SEPARATE USER INPUT BY SPACES
  146. i++; // COUNTING TOKENS
  147. tokens[i]= NULL; // MAKING SURE LAST ELEMENT IS NULL
  148. return i;
  149. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement