/* * File: mysh.c * Author: Arthur Brandao * * Created on 31 octobre 2018, 12:43 */ #define _POSIX_C_SOURCE 2 #include #include #include #include #include #include #include "error.h" #include "str.h" #include "parser.h" #include "command.h" #include "execute.h" #include "mysh.h" /* --- Extern --- */ extern Error error; /* --- Global --- */ pid_list pidlist; pid_node* active = NULL; /* --- Fonctions privées --- */ void test_write() { char* a = "azerty\n"; int tmp = write(1, a, strlen(a)); printf("%d\n", tmp); } void test_tmp_file(){ int a; FILE* f = tmpfile(); printf("F : %d\n", f == NULL); int fd = fileno(f); printf("%d : %ld\n", fd, write(fd, "bonjour", 8)); a = lseek(fd, 0L, SEEK_SET); sleep(2); char buf[10]; memset(buf, 0 , 10); a = read(fd, buf, 10); printf("%d : %s\n", a, buf); close(fd); } void test(){ CommandTab ct; char str[BUFFER_SIZE]; int a; //Initialisation structures error_finit("mysh.log"); ini_pid_list(&pidlist); //Recup ligne //printf("%s\n", fgets(str, 500, stdin));& memset(str, 0, 500); a = read(STDIN, str, 500); printf("%s\n", str); //Separe les commandes a = parse_line(&ct, str); if(a == SHELL_ERR){ addserror("Erreur lors du parse de la ligne"); error.exit_err(); } //Parse les commandes a = parse_all_command(&ct); if(a == SHELL_FAIL){ addserror("Erreur lors du parse des commandes"); error.exit_err(); } //Affiche resultat for (int i = 0; i < ct.length; i++) { Command* c = ct.cmd[i]; printf("Commande %d (%s) : \n", i, c->name); for (int j = 0; j < c->argc; j++) { printf(" Argument %d : %s\n", j, c->argv[j]); } printf("Commande en fond : %d\n\n", ct.bck); //Si c'est une commande interne on l'execute if(is_internal_cmd(ct.cmd[i]->name)){ show_current_dir(NULL, "\n"); printf("Result : %d\n", launch_internal_command(ct.cmd[i])); show_current_dir(NULL, "\n"); } } //Nettoyage structures clean_command(&ct); clean_pid(&pidlist); error.exit(); } /* --- Fonctions utilitaires --- */ void show_current_dir(const char* before, const char* after) { char buffer[BUFFER_SIZE]; if (getcwd(buffer, sizeof (buffer)) == NULL) { addperror("Erreur getcwd()"); } else { if(before == NULL && after == NULL){ printf(":%s", buffer); } else if(before == NULL){ printf(":%s%s", buffer, after); } else if(after == NULL){ printf("%s:%s", before, buffer); } else { printf("%s:%s%s", before, buffer, after); } } fflush(stdout); } int get_line(char* buffer){ memset(buffer, 0, BUFFER_SIZE); if(read(STDIN, buffer, BUFFER_SIZE) == ERR){ addperror("Impossible de lire dans STDIN"); return SHELL_ERR; } return SHELL_OK; } int get_tmp_file(){ FILE* f = tmpfile(); if(f == NULL){ adderror("Impossible de créer un fichier temporaire"); return SHELL_ERR; } return fileno(f); } /* --- Main --- */ int main(int argc, char* argv[]) { //Declaration variables CommandTab ct; int result; char line[BUFFER_SIZE]; //Initialisation structures error_finit("mysh.log"); ini_pid_list(&pidlist); //BOucle infini de lecture while(1){ //Affichage repertoire show_current_dir(getlogin(), "> "); //Lecture ligne if(get_line(line) == SHELL_ERR){ error.print("Impossible de lire les commandes"); clean_pid(&pidlist); error.exit_err(); } //Parse la ligne et commandes result = parse_line(&ct, line); if(result == SHELL_ERR){ error.print("Impossible d'analyser la ligne"); addserror("Erreur lors du parse de la ligne"); continue; } //Parse les commandes result = parse_all_command(&ct); if(result == SHELL_FAIL){ error.print("Impossible d'analyser la commande"); addserror("Erreur lors du parse des commandes"); continue; } //Execute result = run(ct); printf("Result : %d\n", result); } //Nettoyage clean_pid(&pidlist); error.end(); return EXIT_SUCCESS; } int run(CommandTab ct){ pid_t pid; int result; //Si en fond creation d'un fork pour executer les commandes printf("bck : %d\n", ct.bck); if(ct.bck && false/*ToDo - Test plus tard*/){ pid = fork(); if(pid == ERR){ addperror("Erreur lors du fork pour l'execution des commandes"); error.print("Erreur systeme, impossible de continuer\n"); return SHELL_ERR; } //Fils if(pid == 0){ ct.bck = 0; result = run(ct); if(result == SHELL_FAIL){ exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); } //Ajout du fils dans la liste des pid add_pid(&pidlist, pid); //Pour le pere c'est fini return SHELL_OK; } //Sinon execution de chaque commande Command* c; //int tmpfd; //Parcours les commandes for(int i = 0; i < ct.length; i++){ c = ct.cmd[i]; //Si il y a un pipe creation d'un fichier temporaire à la place de la sortie standard /*if(c->next == SHELL_PIPE){ tmpfd = get_tmp_file(); if(tmpfd == SHELL_ERR){ exit(EXIT_FAILURE); } tmpfd = redirect_fd(STDOUT, tmpfd); }*/ //Effectue les redirections IO /*ToDo*/ //Execute la commande if(is_internal_cmd(c->name)){ result = launch_internal_command(c); printf("%d\n", result); } else if(is_executable_file(c->name)){ } else { } //Reset IO /*ToDo*/ //Agit en fonction de la jointure avec la prochaine commande /*ToDo*/ } return SHELL_OK; }