Partage
  • Partager sur Facebook
  • Partager sur Twitter

Recréer la console Ubuntu en C

Anonyme
    20 mai 2018 à 23:38:49

    Bonsoir, 

    Je dois recréer la console Ubuntu pour un projet de fac. J'ai fait pratiquement ce que je voulais et ce que je dois faire mais je n'arrive pas à gérer deux cas, le "<" et "|".  

    Je n'ai pas d'erreur lors de l'exécution, le code ne fait simplement rien, peu importe ce que je tente. Merci de votre aide

    Voici mon code :

    Le main :

    int main(int argc, char * argv[]){
    	char str[MAX_CMD_SIZE];
    	int i = 0;
    	while(i == 0) {
    		printf("$ ");
    		fgets(str, MAX_CMD_SIZE, stdin);
    		if (str[strlen(str)-1]=='\n')
    			str[strlen(str)-1]='\0';
    		command_t tab_cmd[MAX_CMD];
    		init_commands(tab_cmd, MAX_CMD);
    		int nb;
    		nb = make_commands(str, tab_cmd, MAX_CMD);
    		exec_commands(tab_cmd, nb);
    	}
    	return 0;
    }

    Les structures :

    typedef struct command_t { 
    	char path[MAX_PATH_SIZE];
    	char * argv [MAX_ARGS];
    	int stdout, stdin, stderr; 
    	int bg; //mis à 1 dans parser.c quand token = "&"
    	pid_t pid;
    	int status;
    	struct command_t * next;
    	struct command_t * next_success;
    	struct command_t * next_failure;
    } command_t;

    Le fichier qui gère les structures :

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/wait.h>
    #include "exec.h"
    
    int search_path(const char * f, char * path) {
    	//printf("line: %d file: %s\n", __LINE__, __FILE__);
    	char * env_path = getenv("PATH");
    	if(env_path == NULL) return 1;
    	
    	char * str = env_path;
    	char * fin;
    	while(str != NULL){
    		fin = strchr(str, ':');
    		if(fin == NULL){ break; }
    		//pointeur sur le premier ':'
    		strncpy(path, str, fin-str);
    		path[fin-str] = '/';
    		path[fin-str+1] = '\0';
    		strcat(path, f);
    		 str = fin+1;
    
    		//tester si path existe :
    		FILE * tmp = fopen(path, "r");
    		if(tmp == NULL) { continue; }
    		else{
    			fclose(tmp);
    			return 0;
    		}
    	}
    	return 1;
    	
    }
    
    int exec_commands(command_t * cmds, int nb) {
    	command_t *cmd = &cmds[0];
    	
    	while (cmd!=NULL) {
    		//printf("1. cmd = %p\n", cmd);
    		if((cmd->pid = fork()) == 0) {
    			dup2(cmd->stdin, STDIN_FILENO);
    			dup2(cmd->stdout, STDOUT_FILENO);
    			dup2(cmd->stderr, STDERR_FILENO);
    			if(cmd->stdin != STDIN_FILENO) {
    				close(cmd->stdin);
    				close(cmd->stdout);
    				close(cmd->stderr);
    			}
    			//printf("exec : %s\n", cmd->path);
    			execv(cmd->path, cmd->argv);
    			exit (-1);
    		}
    		if(cmd->bg != 1) {
    			waitpid(cmd->pid, &cmd->status, 0);
    		}
    		if (WEXITSTATUS(cmd->status)==0) {
    			cmd = cmd->next_success;
    		} else {
    			cmd = cmd->next_failure;
    		}
    		//printf("2. cmd = %p\n", cmd);
    
    	}
    	
    	return 0;
    }
    
    int init_commands(command_t * cmds, int nb) {
    	for(int i = 0; i < nb; i++) {
    		cmds[i].stdin = STDIN_FILENO;
    		cmds[i].stdout = STDOUT_FILENO;
    		cmds[i].stderr = STDERR_FILENO;
    		cmds[i].bg = 0;
    		cmds[i].next_success = NULL;
    		cmds[i].next_failure = NULL;
    	}
    	
    	return 0;
    }



    Mon fichier qui contient les fonctions :

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include "exec.h"
    
    // Enleve les espaces au début et à la fin de la chaine
    int trim(char * str){
    	int i;
    	int nb = strspn(str, " \t");
    	memmove(str, str+nb, strlen(str)-nb+1);
    	for(i = strlen(str)-1; i>=0; --i) {
    		if(str[i] != ' ' && str[i] != '\t'){
    			break;
    		}
    	}
    	str[i+1] = '\0';
    	
    	return 0;
    }
    
    // Enleve les doublons d'espace
    int clean(char * str){
    	char * doublon;
    	while((doublon == strstr(str, "  ")) > 0) {
    		memmove(doublon, doublon+1, strlen(doublon));
    	}
    	return 0;
    }
    
    
    
    // Sépare les arguments un à un 
    int tokenize(char * str, char * argv[], int max_arg){
    	int ind_arg=0;
    	int i = 0;
    	
    	while(ind_arg < max_arg-1)
    	{
    		argv[ind_arg++] = &str[i]; //str+i
    		// Avancer dans la chaine jusqu'au prochain "espace" ou "\0"
    		while(str[i] != ' ' && str[i] != '\0') ++i;
    		if(str[i] == ' ') { str[i]='\0'; ++i; }
    		if(str[i] == '\0') break;
    	}
    	argv[ind_arg] = NULL;
    	return 0;
    }
    
    // Effectue la ligne de commande
    int make_commands(char * str, command_t * tab_cmd, int max) {
    	char * argv[MAX_ARGS];
    	char path [MAX_PATH_SIZE];
    	trim(str);
    	clean(str);
    	tokenize(str, argv, MAX_ARGS);
    	int cmd_idx = 0;
    	int argv_idx = 0;
    	for(int i = 0 ; argv[i] != NULL && cmd_idx < max ; i++) {
    		
    		if(strcmp(argv[i], ";") == 0) { //OK
    			tab_cmd[cmd_idx].argv[argv_idx] = NULL;
    			if (search_path(tab_cmd[cmd_idx].argv[0], tab_cmd[cmd_idx].path)!=0) {
    				return -1;
    			}
    			tab_cmd[cmd_idx].next_success = &tab_cmd[cmd_idx + 1];
    			tab_cmd[cmd_idx].next_failure = &tab_cmd[cmd_idx + 1];
    			++cmd_idx;
    			argv_idx = 0;
    			continue;	
    		}
    		
    		else if(strcmp(argv[i], "&") == 0) { //OK
    			tab_cmd[cmd_idx].bg = 1;
    			tab_cmd[cmd_idx].argv[argv_idx] = NULL;
    			if (search_path(tab_cmd[cmd_idx].argv[0], tab_cmd[cmd_idx].path)!=0) {
    				return -1;
    			}
    			tab_cmd[cmd_idx].next_success = &tab_cmd[cmd_idx + 1];
    			tab_cmd[cmd_idx].next_failure = &tab_cmd[cmd_idx + 1];
    			++cmd_idx;
    			argv_idx = 0;
    			continue;	
    		}
    		
    		else if(strcmp(argv[i], "&&") == 0) { //OK
    			tab_cmd[cmd_idx].next_success = &tab_cmd[cmd_idx+1];
    			tab_cmd[cmd_idx].argv[argv_idx] = NULL;
    			if (search_path(tab_cmd[cmd_idx].argv[0], tab_cmd[cmd_idx].path)!=0) {
    				return -1;
    			}
    			tab_cmd[cmd_idx].next_success = &tab_cmd[cmd_idx + 1];
    			tab_cmd[cmd_idx].next_failure = NULL;
    			++cmd_idx;
    			argv_idx = 0;
    			continue;	
    		}
    		
    		else if(strcmp(argv[i], "|") == 0) { //PAS OK
    			/*int pipefd[2];
    			pipe(pipefd);
    			
    			tab_cmd[cmd_idx].stdout = dup(pipefd[1]);
    			tab_cmd[cmd_idx].bg = 1;
    			
    			int i = cmd_idx+1;
    			command_t *cmd = &tab_cmd[i];
    			tab_cmd[cmd_idx].next = cmd;
    			++cmd_idx;
    			init_commands(cmd, MAX_CMD);
    			
    			
    			cmd->stdin = dup(pipefd[0]);
    			
    			close(pipefd[0]);
    			close(pipefd[1]);*/
    			
    			continue;	
    		}
    		
    		else if(strcmp(argv[i], "||") == 0) { 
    			tab_cmd[cmd_idx].next_success = &tab_cmd[cmd_idx+1];
    			tab_cmd[cmd_idx].argv[argv_idx] = NULL;
    			if (search_path(tab_cmd[cmd_idx].argv[0], tab_cmd[cmd_idx].path)!=0) {
    				return -1;
    			}
    			tab_cmd[cmd_idx].next_success = NULL;
    			tab_cmd[cmd_idx].next_failure = &tab_cmd[cmd_idx + 1];
    			++cmd_idx;
    			argv_idx = 0;
    			continue;	
    		}
    		
    		else if(strcmp(argv[i], "<") == 0) { 
    			char * stdout_path = argv[i+1];
    			int fd = open(stdout_path, O_RDONLY, S_IREAD);
    			if(fd == -1) { fprintf(stderr, "Impossible de lire le fichier"); }
    			tab_cmd[cmd_idx].stdin = fd;
    			tab_cmd[cmd_idx].argv[argv_idx] = NULL;
    			continue;	
    		}
    	}
    
    	if (argv_idx != 0) {
    		tab_cmd[cmd_idx].argv[argv_idx] = NULL;
    		if (search_path(tab_cmd[cmd_idx].argv[0], tab_cmd[cmd_idx].path)!=0) {
    			return -1;
    		}
    		return cmd_idx+1;
    	}
    	return cmd_idx;
    }




    -
    Edité par Anonyme 20 mai 2018 à 23:39:53

    • Partager sur Facebook
    • Partager sur Twitter
      21 mai 2018 à 10:47:03

      Bonjour,

      Ce que tu dois créer est un shell, pas une console. Le shell s'affiche dans une console. Ce détail pourrait t'aider dans tes recherches.

      • Partager sur Facebook
      • Partager sur Twitter
        21 mai 2018 à 13:31:41

        Bonjour 

        D'accord je ne savais pas. Je m'étais servi du cœur openclassroom sur le site redirections pour l'instant

        • Partager sur Facebook
        • Partager sur Twitter

        Recréer la console Ubuntu en C

        × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
        × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
        • Editeur
        • Markdown