command.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. /*
  2. * File: command.c
  3. * Author: Arthur Brandao
  4. *
  5. * Created on 9 novembre 2018
  6. */
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <unistd.h>
  10. #include "error.h"
  11. #include "str.h"
  12. #include "parser.h"
  13. #include "mysh.h"
  14. #include "execute.h"
  15. #include "command.h"
  16. /* --- Extern --- */
  17. extern Error error;
  18. extern pid_t last;
  19. extern int status_cmd;
  20. extern int result_cmd;
  21. char* cmdlist[] = {
  22. "cd",
  23. "exit",
  24. "status",
  25. NULL
  26. };
  27. boolean exitsh = false;
  28. /* --- Fonctions publiques --- */
  29. void ini_pid_list(pid_list* pl) {
  30. pl->first = NULL;
  31. pl->last = NULL;
  32. }
  33. pid_node* add_pid(pid_list* pl, pid_t pid, int job) {
  34. pid_node* pn = malloc(sizeof (pid_node));
  35. pn->pid = pid;
  36. pn->job = job;
  37. pn->next = NULL;
  38. if (pl->first == NULL) {
  39. pn->prev = NULL;
  40. pl->first = pn;
  41. pl->last = pn;
  42. } else {
  43. pn->prev = pl->last;
  44. pl->last->next = pn;
  45. pl->last = pn;
  46. }
  47. return pn;
  48. }
  49. pid_node* search_pid(pid_list* pl, pid_t pid) {
  50. pid_node* pn = pl->first;
  51. while (pn != NULL) {
  52. if (pn->pid == pid) {
  53. return pn;
  54. }
  55. pn = pn->next;
  56. }
  57. return NULL;
  58. }
  59. void remove_pid(pid_list* pl, pid_node* pn) {
  60. //Si 1er et seul
  61. if (pn->prev == NULL && pn->next == NULL) {
  62. pl->first = NULL;
  63. pl->last = NULL;
  64. }
  65. //Si 1er et non seul
  66. else if (pn->prev == NULL && pn->next != NULL) {
  67. pn->next->prev = NULL;
  68. pl->first = pn->next;
  69. }
  70. //Si dernier
  71. else if (pn->next == NULL) {
  72. pn->prev->next = NULL;
  73. pl->last = pn->prev;
  74. }
  75. //Sinon si il est au milieu
  76. else {
  77. pn->prev->next = pn->next;
  78. pn->next->prev = pn->prev;
  79. }
  80. //Free
  81. free(pn);
  82. }
  83. void clean_pid(pid_list* pl) {
  84. pid_node* tmp, * pn = pl->first;
  85. while (pn != NULL) {
  86. tmp = pn->next;
  87. free(pn);
  88. pn = tmp;
  89. }
  90. pl->first = NULL;
  91. pl->last = NULL;
  92. }
  93. boolean is_internal_cmd(const char* cmd) {
  94. //Parcours tableau pour trouver correspondance
  95. for (int i = 0; cmdlist[i] != NULL; i++) {
  96. if (strncmp(cmd, cmdlist[i], strlen(cmd)) == 0) {
  97. return true;
  98. }
  99. }
  100. return false;
  101. }
  102. int launch_internal_command(Command* cmd) {
  103. int result, length = strlen(cmd->name) + 1;
  104. //cd
  105. if (strncmp(cmd->name, cmdlist[0], length) == 0) {
  106. result = cd(cmd->argc, cmd->argv);
  107. return result;
  108. }
  109. //exit
  110. else if (strncmp(cmd->name, cmdlist[1], length) == 0) {
  111. result = exit_sh(cmd->argc, cmd->argv);
  112. return result;
  113. }
  114. //status
  115. else if (strncmp(cmd->name, cmdlist[2], length) == 0) {
  116. result = status(cmd->argc, cmd->argv);
  117. return result;
  118. }
  119. //Aucune commande
  120. else {
  121. return SHELL_FAIL;
  122. }
  123. }
  124. /* --- Commandes --- */
  125. int cd(int argc, char** argv) {
  126. //Si trop d'arguments
  127. if (argc > 2) {
  128. error.print("too many arguments : 1 required, %d given\n", argc - 1);
  129. return EXIT_FAILURE;
  130. } else {
  131. //Si aucun argument on va à la racine
  132. if (argc == 1) {
  133. if (chdir("/") == ERR) {
  134. addperror("Erreur chdir()");
  135. return EXIT_FAILURE;
  136. }
  137. }
  138. //Sinon on va dans le dossier indiqué par l'utilisateur
  139. else {
  140. if (chdir(argv[1]) == ERR) {
  141. error.print("path does not exist\n");
  142. return EXIT_FAILURE;
  143. }
  144. }
  145. }
  146. return EXIT_SUCCESS;
  147. //show_current_dir("current working directory is: ", "\n");
  148. }
  149. int exit_sh(int argc, char** argv){
  150. exitsh = true;
  151. return EXIT_SUCCESS;
  152. }
  153. int status(int argc, char** argv){
  154. if(!(last != -1 && status_cmd != -1)){
  155. error.print("Aucune commande executée\n");
  156. return EXIT_FAILURE;
  157. }
  158. //En fonction du status
  159. if(result_cmd == SHELL_FAIL){
  160. printf("%d terminé anormalement\n", last);
  161. } else {
  162. printf("%d terminé avec comme code de retour %d\n", last, status_cmd);
  163. }
  164. return EXIT_SUCCESS;
  165. }