Search code examples
cshellforkcd

How can I implement cd command in my own shell in C?


this is my code, i'm a Spanish student and I can't explain correctly, but, i need implement cd command in my own shell in C. Is for a workclass, if someone can help for realize it. When I put the if condition on process, cd doesn't work, But when I put the code outside I get the cd to work, however, when putting back cd does not return to the previous directory as the cd command would normally do.

If any can correct the fail. Thanks you so much.

#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h> 
#include <unistd.h> 
#include <libgen.h> 
#include <sys/shm.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>

#define TAM 1000 

void  parseo(char *line, char **argv);

int main(void) {

    char  cad[TAM];             
    char  *argv[TAM]; 
    char  *gdir;
    char  *dir;
    char  *to;
    char buf[TAM];
    pid_t pid;
    int status;

    while (1) {                   

        printf("user@PC: ");    
        fgets(cad, 1000, stdin);

        // Si encontramos un salto de linea (se pulsa enter)
        if (cad[strlen(cad) - 1] == '\n')                                                           
            cad[strlen(cad) - 1] = '\0';    // lo marcamos como final de sentencia            

        parseo(cad, argv);


        // Exit para salir del shell
        if (!strcmp(argv[0], "exit")) exit(0);  

        if (!strcmp(argv[0], "cd")){

            gdir = getcwd(buf, sizeof(buf));
            dir = strcat(gdir, "/");
            to = strcat(dir, argv[1]);

            chdir(to);
            //printf("Acceso a la carpeta realizado\n");

        }            

        pid = fork();

        if (pid == 0) {   

            if (execvp(*argv, argv) < 0) {
                printf("%s: no se encontró la orden \n", argv[0]);
                exit(1);
            }
        }else {  

            waitpid(pid,&status,0);
        }   

    }
    return 0;
}

void  parseo(char *line, char **argv){

    while (*line != '\0') {       
        while (*line == ' ' || *line == '\t' || *line == '\n')

            *line++ = '\0';     
            *argv++ = line; 

        while (*line != '\0' && *line != ' ' && *line != '\t' && *line != '\n') 
            line++;             
    } 
    *argv = '\0';             // marca de final
}

Solution

  • It's working fine, actually! The only problem is that, after calling chdir(), your code continues to parse the command as an external executable, which fails. You didn't have this problem for exit because that exits the shell before it can do anything else. :)

    Moving the code which follows into an else block, or adding continue after chdir(), should fix it.

    (As an aside: The getcwd() / strcat() steps preceding chdir() are actually unnecessary. chdir() works with relative path: for example, if the current working directory is /usr, you can call chdir("bin") to enter /usr/bin.)