/* * 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); } /* --- 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); } } } 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[]) { CommandTab ct; char str[BUFFER_SIZE]; int a; //Initialisation structures error_finit("mysh.log"); ini_pid_list(&pidlist); error.exit(); //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(); } int run(CommandTab ct){ pid_t pid; int result; pid_node* pnode; //Fork pour executer la commande 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; } // --- Pere --- else if(pid != 0){ //Ajoute du pid dans la liste des pid actifs pnode = add_pid(&pidlist, pid); //Si on attend le retour de la commande if(!ct.bck){ //Ajout du pid comme étant le pid actif et attente active = pnode; wait(&result); //Le processus n'est plus actif et analyse retour active = NULL; remove_pid(&pidlist, pnode); if(WIFEXITED(result)){ return WEXITSTATUS(result); } else { return SHELL_FAIL; } } //Sinon ok return SHELL_OK; } // --- Fils --- //Reset sortie erreur error.end(); //Execute chaque commande Command* c; int tmpfd; 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); } 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; }