Advertisement
Guest User

Untitled

a guest
Dec 13th, 2018
60
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.76 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <sys/wait.h>
  4. #include <unistd.h>
  5. #include <string.h>
  6.  
  7.  
  8.  
  9. #define SHELL_RL_BUFSIZE 1024
  10. #define SHELL_TOK_BUFSIZE 64
  11. #define SHELL_TOK_DELIM " \t\r\n\a"
  12. #define MAX_HISTORY_SIZE 100
  13.  
  14. #define clear() printf("\033[H\033[J")
  15.  
  16. /*
  17. Function Declarations for builtin shell commands:
  18. */
  19. int s_cd(char **args);
  20. int s_help(char **args);
  21. int s_exit(char **args);
  22. int s_history(char **args);
  23. int s_show_history();
  24.  
  25. char *history[MAX_HISTORY_SIZE][10];
  26. int history_position=0;
  27.  
  28. /*
  29. List of builtin commands, followed by their corresponding functions.
  30. */
  31. char *builtin_str[] = {
  32. "cd",
  33. "help",
  34. "exit",
  35. "history",
  36. };
  37.  
  38. int (*builtin_func[]) (char **) = {
  39. &s_cd,
  40. &s_help,
  41. &s_exit,
  42. &s_show_history
  43. };
  44.  
  45. int s_show_history(char **args){
  46. for(int i=1;i<history_position;i++)
  47. printf("%d. %s\n",i, history[i-1]);
  48. return 1;
  49. }
  50.  
  51. int s_num_builtins() {
  52. return sizeof(builtin_str) / sizeof(char *);
  53. }
  54.  
  55. /*
  56. Builtin function implementations.
  57. */
  58. int s_cd(char **args)
  59. {
  60. if (args[1] == NULL) {
  61. fprintf(stderr, "shell: expected argument to \"cd\"\n");
  62. } else {
  63. if (chdir(args[1]) != 0) {
  64. perror("shell");
  65. }
  66. }
  67. return 1;
  68. }
  69.  
  70. int s_help(char **args)
  71. {
  72. int i;
  73. printf("This are the implemented functions : \n");
  74.  
  75. for (i = 0; i < s_num_builtins(); i++) {
  76. printf(" %s\n", builtin_str[i]);
  77. }
  78.  
  79. return 1;
  80. }
  81.  
  82. int s_exit(char **args)
  83. {
  84. printf("Successful exit\n");
  85. return 0;
  86. }
  87.  
  88. int s_history(char **args)
  89. {
  90. int i;
  91.  
  92. strcpy(history[history_position],args[0]);
  93. history_position++;
  94. return 1;
  95. }
  96.  
  97. int s_execute(char **args)
  98. {
  99. int i;
  100.  
  101. if (args[0] == NULL) {
  102. // An empty command was entered.
  103. return 1;
  104. }
  105.  
  106. s_history(args);
  107.  
  108. for (i = 0; i < s_num_builtins(); i++) {
  109. if (strcmp(args[0], builtin_str[i]) == 0) {
  110. return (*builtin_func[i])(args);
  111. }
  112. }
  113.  
  114. return s_launch(args);
  115. }
  116.  
  117. int s_launch(char **args)
  118. {
  119. pid_t pid, wpid;
  120. int status;
  121.  
  122. pid = fork();
  123. if (pid == 0) {
  124. // Child process
  125. if (execvp(args[0], args) == -1) {
  126. perror("shell");
  127. }
  128. exit(EXIT_FAILURE);
  129. } else if (pid < 0) {
  130. // Error forking
  131. perror("shell");
  132. } else {
  133. // Parent process
  134. do {
  135. wpid = waitpid(pid, &status, WUNTRACED);
  136. } while (!WIFEXITED(status) && !WIFSIGNALED(status));
  137. }
  138.  
  139. return 1;
  140. }
  141.  
  142. int s_history_arrow_up(){
  143. printf("THIS IS A\n");
  144. int i;
  145. char his_val[1];
  146.  
  147. for(i=1;i<=history_position;i++){
  148. printf("%d. %s\n",i, history[i-1]);
  149. }
  150.  
  151. return 1;
  152. }
  153.  
  154. char **s_split_line(char *line)
  155. {
  156. int bufsize = SHELL_TOK_BUFSIZE, position = 0;
  157. char **tokens = malloc(bufsize * sizeof(char*));
  158. char *token;
  159.  
  160. if (!tokens) {
  161. fprintf(stderr, "shell: allocation error\n");
  162. exit(EXIT_FAILURE);
  163. }
  164.  
  165. token = strtok(line, SHELL_TOK_DELIM);
  166. while (token != NULL) {
  167. tokens[position] = token;
  168. position++;
  169.  
  170. if (position >= bufsize) {
  171. bufsize += SHELL_TOK_BUFSIZE;
  172. tokens = realloc(tokens, bufsize * sizeof(char*));
  173. if (!tokens) {
  174. fprintf(stderr, "shell: allocation error\n");
  175. exit(EXIT_FAILURE);
  176. }
  177. }
  178.  
  179. token = strtok(NULL, SHELL_TOK_DELIM);
  180. }
  181. tokens[position] = NULL;
  182. return tokens;
  183. }
  184.  
  185. char *s_read_line(void)
  186. {
  187. int bufsize = SHELL_RL_BUFSIZE;
  188. int position = 0;
  189. char *buffer = malloc(sizeof(char) * bufsize);
  190. int c;
  191.  
  192. if (!buffer) {
  193. fprintf(stderr, "shell: allocation error\n");
  194. exit(EXIT_FAILURE);
  195. }
  196.  
  197. while (1) {
  198. // Read a character
  199. c = getchar();
  200. if (c == '\033') { // if the first value is esc
  201. getchar(); // skip the [
  202. switch(getchar()) { // the real value
  203. case 'A':
  204. s_history_arrow_up();
  205. break;
  206. case 'B':
  207. printf("THIS IS B\n");
  208. break;
  209. }
  210. }else if (c == EOF || c == '\n') { // If we hit EOF, replace it with a null character and return.
  211. buffer[position] = '\0';
  212. return buffer;
  213. } else {
  214. buffer[position] = c;
  215. }
  216. position++;
  217.  
  218. // If we have exceeded the buffer, reallocate.
  219. if (position >= bufsize) {
  220. bufsize += SHELL_RL_BUFSIZE;
  221. buffer = realloc(buffer, bufsize);
  222. if (!buffer) {
  223. fprintf(stderr, "shell: allocation error\n");
  224. exit(EXIT_FAILURE);
  225. }
  226. }
  227. }
  228. }
  229.  
  230. void s_loop(void)
  231. {
  232. char *line;
  233. char **args;
  234. int status;
  235.  
  236. clear();
  237. printf("Use help command for more information\n");
  238. do {
  239. printf("> ");
  240.  
  241. line = s_read_line();
  242. args = s_split_line(line);
  243. status = s_execute(args);
  244.  
  245. free(line);
  246. free(args);
  247. } while (status);
  248. }
  249.  
  250. int main(int argc, char **argv)
  251. {
  252.  
  253. // Run command loop.
  254. s_loop();
  255.  
  256. return EXIT_SUCCESS;
  257. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement