1

I have a program that calls chdir() to change the cwd. However, after the program finishes the cwd changes back to the directory that called the program instead of staying the in one specified by the call to chdir(). I made a program to test if chdir() is actually changing to the specified directory and found that chdir() is doing what I presumed: changing to the specified directory for the duration of the program then returning to the directory that executed the program.

Here is the code for the test:

#include <stdio.h>
#include <unistd.h>

#define NAME_MAX 100

int main(int argc, char **argv)
{
    char buf[NAME_MAX];
    char *path = argv[1];

    if (chdir(path) == -1) { /* change cwd to path */   
        fprintf(stderr, "error: could not change to dir %s\n", path);
        return 1;
    }
    getcwd(buf, NAME_MAX);
    printf("CWD is: %s\n", buf); /* print cwd as obtained from getcwd() */

    return 0;
}

and here is the output from my terminal:

john@ubuntu:~/C/cli$ pwd
/home/john/C/cli
john@ubuntu:~/C/cli$ mkdir foobar
john@ubuntu:~/C/cli$ ./test.c foobar
CWD is: /home/john/C/cli/foobar
john@ubuntu:~/C/cli$ pwd
/home/john/C/cli

So my question is, how can I stay in the directory that I specify in the call to chdir() after the the program finishes? Also, I am on Ubuntu 12.04 and compiling with gcc.

sardoj
  • 33
  • 1
  • 4

2 Answers2

4

Certain information, including values of environment variables and the current working directory, is propagated from parent processes to child processes but not back to parent processes. If a child process (your program) invokes chdir or sets or modifies an environment variable, that affects that process and any of its children, but cannot affect the parent.

That's why chdir is a built-in command in the shell; it can't be implemented as a separate program.

If you want to have a program change your shell's current directory for you, you'll need to do it indirectly. For example, your program can print a cd command, and you can eval that output in your shell. (You can wrap that in a function.)

For example, if you change:

chdir(path);

to

printf("cd %s\n", path);

you can have a shell function:

my_func() {
    eval `your_program`
}

and my_func will change your shell's current directory.

Or you can put a cd command directly in the function, or in a script that you execute via . script-name or source script-name rather than executing it.

All these solutions require your current shell to execute the cd command itself (which internally invokes the chdir system call).

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
2

The environment of one process cannot be changed by another process. That includes the current working directory. So no, you can't stay in the directory.

Joni
  • 108,737
  • 14
  • 143
  • 193
  • Technically the "environment" is only the vector of KEY=value strings provided as the third argument to `main`, and does not include the current working directory (on Unix; IIRC the per-drive CWD *is* represented as special environment variables on Windows). However, it is true that neither the environment nor the working directory of one process can be changed by another process. – zwol Aug 16 '13 at 16:59
  • I use the term loosely. Do you know the correct term for process state in general, that includes the cwd, env variables, mount points etc? – Joni Aug 16 '13 at 17:02
  • I don't think there is an official term, but if you said "inherited process state" I think that would be clear enough. – zwol Aug 16 '13 at 21:23