Advertisement
daniv1

Untitled

Nov 28th, 2018
167
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.31 KB | None | 0 0
  1. /******************************************************************************
  2.  
  3.                             Online C Compiler.
  4.                 Code, Compile, Run and Debug C program online.
  5. Write your code in this editor and press "Run" button to compile and execute it.
  6.  
  7. *******************************************************************************/
  8.  
  9. #include <stdio.h>
  10. #include <sys/wait.h>
  11. #include <unistd.h>
  12. #include <stdlib.h>
  13. #include <stdio.h>
  14. #include <string.h>
  15. #define LSH_RL_BUFSIZE 1024
  16. #define LSH_TOK_BUFSIZE 64
  17. #define LSH_TOK_DELIM " \t\r\n\a"
  18. /*
  19.   Function Declarations for builtin shell commands:
  20.  */
  21. int lsh_cd(char **args);
  22. int lsh_help(char **args);
  23. int lsh_exit(char **args);
  24.  
  25.  
  26. /*
  27.   List of builtin commands, followed by their corresponding functions.
  28.  */
  29. char *builtin_str[] = {
  30.   "cd",
  31.   "help",
  32.   "exit"
  33. };
  34.  
  35. int (*builtin_func[]) (char **) = {
  36.   &lsh_cd,
  37.   &lsh_help,
  38.   &lsh_exit
  39. };
  40.  
  41. int lsh_num_builtins() {
  42.   return sizeof(builtin_str) / sizeof(char *);
  43. }
  44.  
  45. /*
  46.   Builtin function implementations.
  47. */
  48. int lsh_cd(char **args)
  49. {
  50.   if (args[1] == NULL) {
  51.     fprintf(stderr, "lsh: expected argument to \"cd\"\n");
  52.   } else {
  53.     if (chdir(args[1]) != 0) {
  54.       perror("lsh");
  55.     }
  56.   }
  57.   return 1;
  58. }
  59.  
  60. int lsh_help(char **args)
  61. {
  62.   int i;
  63.   printf("Type program names and arguments, and hit enter.\n");
  64.   printf("The following are built in:\n");
  65.  
  66.   for (i = 0; i < lsh_num_builtins(); i++) {
  67.     printf("  %s\n", builtin_str[i]);
  68.   }
  69.  
  70.   printf("Use the man command for information on other programs.\n");
  71.   return 1;
  72. }
  73.  
  74. int lsh_exit(char **args)
  75. {
  76.   return 0;
  77. }
  78. char **lsh_split_line(char *line)
  79. {
  80.   int bufsize = LSH_TOK_BUFSIZE, position = 0;
  81.   char **tokens = malloc(bufsize * sizeof(char*));
  82.   char *token;
  83.  
  84.   if (!tokens) {
  85.     fprintf(stderr, "lsh: allocation error\n");
  86.     exit(EXIT_FAILURE);
  87.   }
  88.  
  89.   token = strtok(line, LSH_TOK_DELIM);
  90.   while (token != NULL) {
  91.     tokens[position] = token;
  92.     position++;
  93.  
  94.     if (position >= bufsize) {
  95.       bufsize += LSH_TOK_BUFSIZE;
  96.       tokens = realloc(tokens, bufsize * sizeof(char*));
  97.       if (!tokens) {
  98.         fprintf(stderr, "lsh: allocation error\n");
  99.         exit(EXIT_FAILURE);
  100.       }
  101.     }
  102.  
  103.     token = strtok(NULL, LSH_TOK_DELIM);
  104.   }
  105.   tokens[position] = NULL;
  106.   return tokens;
  107. }
  108.  
  109. char *lsh_read_line(void)
  110. {
  111.   int bufsize = LSH_RL_BUFSIZE;
  112.   int position = 0;
  113.   char *buffer = malloc(sizeof(char) * bufsize);
  114.   int c;
  115.  
  116.   if (!buffer) {
  117.     fprintf(stderr, "lsh: allocation error\n");
  118.     exit(EXIT_FAILURE);
  119.   }
  120.  
  121.   while (1) {
  122.     // Read a character
  123.     c = getchar();
  124.  
  125.     // If we hit EOF, replace it with a null character and return.
  126.     if (c == EOF || c == '\n') {
  127.       buffer[position] = '\0';
  128.       return buffer;
  129.     } else {
  130.       buffer[position] = c;
  131.     }
  132.     position++;
  133.  
  134.     // If we have exceeded the buffer, reallocate.
  135.     if (position >= bufsize) {
  136.       bufsize += LSH_RL_BUFSIZE;
  137.       buffer = realloc(buffer, bufsize);
  138.       if (!buffer) {
  139.         fprintf(stderr, "lsh: allocation error\n");
  140.         exit(EXIT_FAILURE);
  141.       }
  142.     }
  143.   }
  144. }
  145. int lsh_execute(char **args)
  146. {
  147.   int i;
  148.  
  149.   if (args[0] == NULL) {
  150.     // An empty command was entered.
  151.     return 1;
  152.   }
  153.  
  154.   for (i = 0; i < lsh_num_builtins(); i++) {
  155.     if (strcmp(args[0], builtin_str[i]) == 0) {
  156.       return (*builtin_func[i])(args);
  157.     }
  158.   }
  159.  
  160.   return lsh_launch(args);
  161. }
  162.  
  163. int lsh_launch(char **args)
  164. {
  165.   pid_t pid, wpid;
  166.   int status;
  167.  
  168.   pid = fork();
  169.   if (pid == 0) {
  170.     // Child process
  171.     if (execvp(args[0], args) == -1) {
  172.       perror("lsh");
  173.     }
  174.     exit(EXIT_FAILURE);
  175.   } else if (pid < 0) {
  176.     // Error forking
  177.     perror("lsh");
  178.   } else {
  179.     // Parent process
  180.     do {
  181.       wpid = waitpid(pid, &status, WUNTRACED);
  182.     } while (!WIFEXITED(status) && !WIFSIGNALED(status));
  183.   }
  184.  
  185.   return 1;
  186. }
  187. void lsh_loop(void)
  188. {
  189.   char *line;
  190.   char **args;
  191.   int status;
  192.  
  193.   do {
  194.     printf("> ");
  195.     line = lsh_read_line();
  196.     args = lsh_split_line(line);
  197.     status = lsh_execute(args);
  198.  
  199.     free(line);
  200.     free(args);
  201.   } while (status);
  202. }
  203. int main(int argc, char **argv)
  204. {
  205.   // Load config files, if any.
  206.  
  207.   // Run command loop.
  208.   lsh_loop();
  209.  
  210.   // Perform any shutdown/cleanup.
  211.  
  212.   return EXIT_SUCCESS;
  213. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement