Search code examples
cstringpointerscdchdir

chdir(..) returns 0 for success and changes directory, but outputs "No such file or directory"


I'm implementing cd functionality using system calls in a C program that acts as a simple shell, and am having a bit of an issue with directory names. I have a feeling it's trivially string related, but I haven't had any luck so far.

I have a function like the following:

static void parse_args(int argc, char **argv) {

    // Special conditions:
    if (strcmp(argv[1], "return") == 0) {
        exit(0);
    }
    else if (strcmp(argv[1], "cd") == 0) {

        if (strcmp(argv[2], "mydir") == 0) {
            printf("Directory name is 'mydir'!\n");
        } else {
            printf("Directory name is NOT 'mydir'!\n");
        }

        int ret = chdir(argv[2]);
        if (ret == 0) { // success
            printf("Able to change directory.\n");
        } else {
            printf("UNABLE to change directory.\n");
        }
    }

    // Handling piping for shell ....
}

I know up front that argv[2] is a string containing my new desired directory.

I wish to cd into an existing directory called mydir, and call changeDirectory with argv[2] equal to "mydir". However, as you can see, inside changeDirectory, I verify that argv[2] is in fact exactly equal to "mydir".

The results of my simple shell call is:

$> pwd
/foo/bar
$> cd mydir
Directory name is 'mydir'!
UNABLE to change directory.
/usr/bin/cd: line 4: cd: mydir: No such file or directory
$> pwd
/foo/bar/mydir

So it appears the command succeeds, however I don't know why I'm receiving the error message. Interestingly, this error message doesn't occur if I call int ret = chdir("mydir"); Can I cast/sanitize this parameter somehow? Any pointers would be greatly appreciated. Can I san


Solution

  • Turns out I had forgotten to exit the function after changing the directory. Later in the function, I was passing cd as a parameter to execvp to execute it as if it were a program. Simply encapsulating the later "Handle Piping" code in an else resolved this.