mysh.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. /*
  2. * File: mysh.c
  3. * Author: Arthur Brandao
  4. *
  5. * Created on 31 octobre 2018, 12:43
  6. */
  7. #define _POSIX_C_SOURCE 2
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <unistd.h>
  11. #include <fcntl.h>
  12. #include <sys/stat.h>
  13. #include <wait.h>
  14. #include "error.h"
  15. #include "str.h"
  16. #include "parser.h"
  17. #include "command.h"
  18. #include "execute.h"
  19. #include "mysh.h"
  20. /* --- Extern --- */
  21. extern Error error;
  22. /* --- Global --- */
  23. pid_list pidlist;
  24. pid_node* active = NULL;
  25. /* --- Fonctions privées --- */
  26. void test_write() {
  27. char* a = "azerty\n";
  28. int tmp = write(1, a, strlen(a));
  29. printf("%d\n", tmp);
  30. }
  31. void test_tmp_file(){
  32. int a;
  33. FILE* f = tmpfile();
  34. printf("F : %d\n", f == NULL);
  35. int fd = fileno(f);
  36. printf("%d : %ld\n", fd, write(fd, "bonjour", 8));
  37. a = lseek(fd, 0L, SEEK_SET);
  38. sleep(2);
  39. char buf[10];
  40. memset(buf, 0 , 10);
  41. a = read(fd, buf, 10);
  42. printf("%d : %s\n", a, buf);
  43. close(fd);
  44. }
  45. void test(){
  46. CommandTab ct;
  47. char str[BUFFER_SIZE];
  48. int a;
  49. //Initialisation structures
  50. error_finit("mysh.log");
  51. ini_pid_list(&pidlist);
  52. //Recup ligne
  53. //printf("%s\n", fgets(str, 500, stdin));&
  54. memset(str, 0, 500);
  55. a = read(STDIN, str, 500);
  56. printf("%s\n", str);
  57. //Separe les commandes
  58. a = parse_line(&ct, str);
  59. if(a == SHELL_ERR){
  60. addserror("Erreur lors du parse de la ligne");
  61. error.exit_err();
  62. }
  63. //Parse les commandes
  64. a = parse_all_command(&ct);
  65. if(a == SHELL_FAIL){
  66. addserror("Erreur lors du parse des commandes");
  67. error.exit_err();
  68. }
  69. //Affiche resultat
  70. for (int i = 0; i < ct.length; i++) {
  71. Command* c = ct.cmd[i];
  72. printf("Commande %d (%s) : \n", i, c->name);
  73. for (int j = 0; j < c->argc; j++) {
  74. printf(" Argument %d : %s\n", j, c->argv[j]);
  75. }
  76. printf("Commande en fond : %d\n\n", ct.bck);
  77. //Si c'est une commande interne on l'execute
  78. if(is_internal_cmd(ct.cmd[i]->name)){
  79. show_current_dir(NULL, "\n");
  80. printf("Result : %d\n", launch_internal_command(ct.cmd[i]));
  81. show_current_dir(NULL, "\n");
  82. }
  83. }
  84. //Nettoyage structures
  85. clean_command(&ct);
  86. clean_pid(&pidlist);
  87. error.exit();
  88. }
  89. /* --- Fonctions utilitaires --- */
  90. void show_current_dir(const char* before, const char* after) {
  91. char buffer[BUFFER_SIZE];
  92. if (getcwd(buffer, sizeof (buffer)) == NULL) {
  93. addperror("Erreur getcwd()");
  94. } else {
  95. if(before == NULL && after == NULL){
  96. printf(":%s", buffer);
  97. } else if(before == NULL){
  98. printf(":%s%s", buffer, after);
  99. } else if(after == NULL){
  100. printf("%s:%s", before, buffer);
  101. } else {
  102. printf("%s:%s%s", before, buffer, after);
  103. }
  104. }
  105. fflush(stdout);
  106. }
  107. int get_line(char* buffer){
  108. memset(buffer, 0, BUFFER_SIZE);
  109. if(read(STDIN, buffer, BUFFER_SIZE) == ERR){
  110. addperror("Impossible de lire dans STDIN");
  111. return SHELL_ERR;
  112. }
  113. return SHELL_OK;
  114. }
  115. int get_tmp_file(){
  116. FILE* f = tmpfile();
  117. if(f == NULL){
  118. adderror("Impossible de créer un fichier temporaire");
  119. return SHELL_ERR;
  120. }
  121. return fileno(f);
  122. }
  123. /* --- Main --- */
  124. int main(int argc, char* argv[]) {
  125. //Declaration variables
  126. CommandTab ct;
  127. int result;
  128. char line[BUFFER_SIZE];
  129. //Initialisation structures
  130. error_finit("mysh.log");
  131. ini_pid_list(&pidlist);
  132. //BOucle infini de lecture
  133. while(1){
  134. //Affichage repertoire
  135. show_current_dir(getlogin(), "> ");
  136. //Lecture ligne
  137. if(get_line(line) == SHELL_ERR){
  138. error.print("Impossible de lire les commandes");
  139. clean_pid(&pidlist);
  140. error.exit_err();
  141. }
  142. //Parse la ligne et commandes
  143. result = parse_line(&ct, line);
  144. if(result == SHELL_ERR){
  145. error.print("Impossible d'analyser la ligne");
  146. addserror("Erreur lors du parse de la ligne");
  147. continue;
  148. }
  149. //Parse les commandes
  150. result = parse_all_command(&ct);
  151. if(result == SHELL_FAIL){
  152. error.print("Impossible d'analyser la commande");
  153. addserror("Erreur lors du parse des commandes");
  154. continue;
  155. }
  156. //Execute
  157. result = run(ct);
  158. printf("Result : %d\n", result);
  159. }
  160. //Nettoyage
  161. clean_pid(&pidlist);
  162. error.end();
  163. return EXIT_SUCCESS;
  164. }
  165. int run(CommandTab ct){
  166. pid_t pid;
  167. int result;
  168. //Si en fond creation d'un fork pour executer les commandes
  169. printf("bck : %d\n", ct.bck);
  170. if(ct.bck && false/*ToDo - Test plus tard*/){
  171. pid = fork();
  172. if(pid == ERR){
  173. addperror("Erreur lors du fork pour l'execution des commandes");
  174. error.print("Erreur systeme, impossible de continuer\n");
  175. return SHELL_ERR;
  176. }
  177. //Fils
  178. if(pid == 0){
  179. ct.bck = 0;
  180. result = run(ct);
  181. if(result == SHELL_FAIL){
  182. exit(EXIT_FAILURE);
  183. }
  184. exit(EXIT_SUCCESS);
  185. }
  186. //Ajout du fils dans la liste des pid
  187. add_pid(&pidlist, pid);
  188. //Pour le pere c'est fini
  189. return SHELL_OK;
  190. }
  191. //Sinon execution de chaque commande
  192. Command* c;
  193. //int tmpfd;
  194. //Parcours les commandes
  195. for(int i = 0; i < ct.length; i++){
  196. c = ct.cmd[i];
  197. //Si il y a un pipe creation d'un fichier temporaire à la place de la sortie standard
  198. /*if(c->next == SHELL_PIPE){
  199. tmpfd = get_tmp_file();
  200. if(tmpfd == SHELL_ERR){
  201. exit(EXIT_FAILURE);
  202. }
  203. tmpfd = redirect_fd(STDOUT, tmpfd);
  204. }*/
  205. //Effectue les redirections IO
  206. /*ToDo*/
  207. //Execute la commande
  208. if(is_internal_cmd(c->name)){
  209. result = launch_internal_command(c);
  210. printf("%d\n", result);
  211. } else if(is_executable_file(c->name)){
  212. } else {
  213. }
  214. //Reset IO
  215. /*ToDo*/
  216. //Agit en fonction de la jointure avec la prochaine commande
  217. /*ToDo*/
  218. }
  219. return SHELL_OK;
  220. }