Advertisement
Guest User

Untitled

a guest
Feb 7th, 2016
189
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.47 KB | None | 0 0
  1. #include <sys/types.h>
  2. #include <sys/wait.h>
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <stdlib.h>
  6. #include <unistd.h>
  7. #include <errno.h>
  8.  
  9. #define MAX_LENGTH 1024
  10. #define MAX 256
  11. #define CMD_MAX 10
  12.  
  13. //A method which returns the number of tokens
  14. int make_tokenlist(char *buf, char* tokens[]) {
  15. char input_line[MAX]; //string to hold input
  16. char *line = buf; //pointer pointing to input buf
  17. int i=0; //counter
  18.  
  19. //tokenizing input string
  20. tokens[i] = strtok(line, " ");
  21. do {
  22. i++; //incrementing i
  23. line = NULL; //setting line to null
  24. tokens[i] = strtok(line, " "); //getting the next token, placing it in next position in array
  25. } while (tokens[i] != NULL); //do while there are more tokens
  26.  
  27. return i; //return number of strings
  28. }
  29.  
  30.  
  31.  
  32. //A method which returns the two commands of a one pipe command
  33. void onePipeSplit(char *tokens[], char *command1[], char *command2[], int numTokens) {
  34. int i=0, j=0;
  35.  
  36. //while the current token is not a pipe, do
  37. while (strcmp(tokens[j], "|")!=0) {
  38. command1[i] = malloc(sizeof(tokens[j])+1); //allocate memory
  39. strcpy(command1[i], tokens[j]); //copy current token to command1
  40. i++; j++; //increment i and j
  41. }
  42.  
  43. j++; //Increment j
  44. i=0; //reset i
  45.  
  46. //while j < the number of tokens, do
  47. while (j < numTokens) {
  48. command2[i] = malloc(sizeof(tokens[j])+1); //allocate memory
  49. strcpy(command2[i], tokens[j]); //copy current token to command2
  50. i++; j++; //increment i and j
  51. }
  52.  
  53. }
  54.  
  55.  
  56.  
  57. //A method which counts the number of pipes in the user's input
  58. int countPipes(int size, char *tokens[]) {
  59.  
  60. int numPipes = 0; //Value which holds number of pipes
  61.  
  62. for (int i=0; i<size; i++) { //for i to number of tokens, do
  63.  
  64. if (strcmp(tokens[i], "|")==0) { //if tokens[i] equals '|', then
  65. numPipes++; //increment numPipes
  66. }
  67. }
  68. return numPipes; //return numPipes
  69. }
  70.  
  71.  
  72.  
  73. //A method which adds the current command to history
  74. void updateHistory(char *history[], char command[], int histIndex) {
  75.  
  76. history[histIndex] = realloc(history[histIndex], MAX_LENGTH); //Allocating space
  77. strcpy(history[histIndex], command); //Put the current command in history
  78. }
  79.  
  80. //A method which increments the histIndex
  81. int incrementIndex(int index) {
  82. if (index != 9)
  83. return index+1;
  84. else
  85. return 0;
  86. }
  87.  
  88.  
  89. //A method which prints out our history
  90. void getHistory(char *history[], int histIndex) {
  91.  
  92. //Loop through the current index to 10 and print out commands
  93. for (int i=histIndex; i < 10; i++) {
  94.  
  95. if (history[i]!=NULL) //If it isn't null, then print
  96. printf("%s\n", history[i]);
  97. }
  98.  
  99. //Loop through 0 to the current index and print out commands
  100. for (int i=0; i<histIndex; i++) {
  101.  
  102. if (history[i]!=NULL) //If it isn't null, then print
  103. printf("%s\n", history[i]);
  104. }
  105. }
  106.  
  107.  
  108.  
  109. ////////////////////// MAIN ////////////////////////
  110. ///////////////////////////////////////////////////////////////////////
  111.  
  112. int main(int argc, char *argv[]) {
  113. char *path = "/bin/"; //Path to commands
  114. char input[MAX], *tokens[CMD_MAX]; //strings to input and token
  115. int i, j, numTokens, numPipes; //initializing ints
  116. char *piped_input; //string holding input when the user uses a pipe
  117. char *history[10]; //An array holding the last 10 commands
  118. int histIndex = 0; //An int which keeps track of the current position in history
  119.  
  120. for (int i=0; i<10; i++) { //Initialize the values in history
  121. history[i] = malloc(MAX_LENGTH);
  122. if (history[i]==NULL) { //If history at position i is null, then it failed
  123. printf("Unable to allocate memory.\n"); //allocating memory, so exit
  124. exit(EXIT_FAILURE);
  125. }
  126. }
  127.  
  128. //while true, do
  129. while (1) {
  130.  
  131. printf("%s> ", getenv("USER")); //print out the user's name + >
  132. fgets(input, MAX, stdin); //Get the users input
  133. strtok(input, "\n"); //Take the entire line and set it to input
  134.  
  135. updateHistory(history, input, histIndex);
  136. histIndex = incrementIndex(histIndex);
  137.  
  138. if (strcmp(input, "exit")==0) { //If the input is exit, then exit
  139. for (int i=0; i<10; i++) { //Freeing the space allocated to history
  140. free(history[i]);
  141. }
  142. exit(0);
  143. }
  144.  
  145. //Else if the current command is history, then print the last 10 commands
  146. else if (strcmp(input, "history")==0) {
  147. getHistory(history, histIndex);
  148.  
  149. }
  150.  
  151. //Otherwise, do
  152. else {
  153. numTokens = make_tokenlist(input, tokens); //Counting the number of tokens
  154. tokens[numTokens] = NULL; //Initializing an array of each token
  155. char cmd[MAX_LENGTH]; //string which holds the user's command
  156. strcpy(cmd, tokens[0]); //copying the command to the cmd string
  157. pid_t pid = fork(); //Creating child 1
  158.  
  159.  
  160. if (pid < 0) { //if pid is < 0 then we have an error
  161. perror("Problem forking.");
  162. exit(EXIT_FAILURE);
  163. }
  164.  
  165. else if (pid > 0) { //else if pid > 0 then this is the parent, so wait
  166. wait(NULL);
  167. }
  168.  
  169. else { //Otherwise make the child execute cmd
  170.  
  171. //Count the number of pipes in the input
  172. numPipes = countPipes(numTokens, tokens);
  173.  
  174. if (numPipes == 0) { //if the number of pipes is 0, then
  175.  
  176. execvp(cmd, tokens); //execute the command
  177. perror("Error"); //if the command doesn't execute, then we have an error
  178. exit(EXIT_FAILURE); //exit
  179. }
  180.  
  181. //Otherwise if we have a single pipe, then do
  182. else if (numPipes == 1) {
  183.  
  184. char *command1[CMD_MAX]; //string holding the first command
  185. char *command2[CMD_MAX]; //string holding the second command
  186. int fds[2]; //create file descriptors for the parent and child
  187. pid_t new_pid; //create new pid_t obj
  188.  
  189. onePipeSplit(tokens, command1, command2, numTokens); //Getting each command for pipe
  190.  
  191. if (pipe(fds) < 0) { //use the pipe command. If < 0
  192. perror("Pipe failure."); //we have an error, so exit
  193. exit(EXIT_FAILURE);
  194. }
  195.  
  196. //Creating child 2
  197. new_pid = fork();
  198.  
  199. //if pid < 0 then we have an error. Exit.
  200. if (new_pid < 0) {
  201. perror("Fork failure.");
  202. exit(EXIT_FAILURE);
  203. }
  204.  
  205. //Else we have the child (2) process
  206. else if (new_pid == 0) {
  207.  
  208. close(fds[0]); //Close read
  209.  
  210. //sending stdin to the shared file descriptor
  211. if (dup2(fds[1], STDOUT_FILENO)<0) {
  212. perror("Can't dup");
  213. exit(EXIT_FAILURE);
  214. }
  215.  
  216. execvp(command1[0], command1); //Execute the next command
  217. perror("Exec failure");
  218. exit(EXIT_FAILURE);
  219. }
  220.  
  221. //Else if we have the parent process
  222. else {
  223.  
  224. pid_t child = fork(); //Creating child 3
  225. if (new_pid < 0) { //if pid < 0, error, exit
  226. perror("Fork failure.");
  227. exit(EXIT_FAILURE);
  228. }
  229.  
  230. //else if pid > 0 we have the parent wait until children execute
  231. else if (new_pid > 0) {
  232. wait(NULL);
  233. }
  234.  
  235. //else we have the child (3)
  236. else {
  237.  
  238. close(fds[1]); //Close write
  239.  
  240. //Sending stdout to the shared file descriptor
  241. if (dup2(fds[0], STDIN_FILENO) < 0) {
  242. perror("Can't dup");
  243. exit(EXIT_FAILURE);
  244. }
  245.  
  246. execvp(command2[0], command2); //Execute the command
  247. perror("Exec failure");
  248. exit(EXIT_FAILURE);
  249. }
  250. }
  251. }
  252.  
  253.  
  254. //////////////////////////////////////////TODO: COMPLETE 2 PIPES/////////////////////////////////////////////
  255. else if (numPipes == 2) {
  256.  
  257.  
  258.  
  259. }
  260.  
  261. else {
  262. printf("\nCan't use more than 2 pipes.\n");
  263. }
  264.  
  265. }
  266. }
  267. }
  268. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement