I have to change working directory from my C program. For this I have used the following command:
execl("/bin/cd","cd","..",(char*)0);
but this command is not changing the directory?
Is anything wrong in this command or is there any other way to change working directory from C program?
To change the current directory you should use chdir:
int chdir(const char *path);
On success it returns 0.
You can't use execl for several reasons:
cd is typically a shell builtin command;
on most systems /bin/cd does not exists; on the very very few systems that have it, it changes the current directory and then spawns a child shell process;
the current directory is a process' property: if you change the current directory using /bin/cd, you'd lose the directory change as soon as the process terminates;
if you use a function from the exec family, the current process image is replaced with a new process image - you could use system, but wouldn't fix the previous 3 problems.
What you are doing won't work because the exec family of calls will actually replace your current program in the current process. In other words, you will have been terminated so that, when cd is finished, your parent process will once again take over.
If you want to change the working directory for the current process, use chdir. If you want to change it on exit, you're out of luck because your program itself is running in a separate process from the parent that started it.
So, unless you have some form of communication with the parent, that's not going to work.
You need to use the chdir system call to change the working directory of the calling process.
Related
i have a trouble with :
system("cd mypath");
when i try this in C programming language terminal doesn't do anything.
i need help.
The system function creates a whole new process, separate from the one calling the function.
Each process have its own current working directory associated with it, and this working directory is specific to that process only. Changing the working directory of one process will not change it for another process.
If you want to change the working directory of your own process use operating-system specific functions to to it. Like chdir on Linux (and other POSIX system like macOS), or SetCurrentDirectory in Windows.
Note that if you change directory in your own process, the directory of the shell or console that invoked your program will not be changed, as it's also a separate process from yours.
look just do
chdir("path");
or
system("chdir PATH"); //linux
I am using chdir() to change directory to the value passed as an argument to this function.
I understand that when I run my C program using gcc myCd.c and ./a.out .. this changes the directory to the parent directory "within" the C program (i.e. a child process is spawned for the a.out process, and the change of directory happens within that child process).
What I want to do is, change the directory at the terminal using this C program. I tried writing a shell script for the same, and then sourcing it, and running, that works, but I wanted to achieve this using C.
What you are attempting to do can't be done. The current working directory is a per-process attribute.
If you run a program which changes its cwd, it does not affect any other processes, except for any children it might create after the chdir().
The correct way to change the terminal's working directory is to use the cd command which the shell executes on your behalf and remains within the same process. That is, cd is one of several commands that the shell does not fork(); this makes the cd command work as expected.
sourceing a shell file makes it run within the shell's process. However, if you were to run the script without source, you'd find there was the exact same problem as with a C program: the shell forks to create a process for the script to run, it runs and then exits, and then the shell continues, but without its cwd changed.
this is the way to change the current working directory in C
this needs the unistd.h header file to be included
if( 0 != chdir( "pathToNewDirectory" ) )
{ // then chdir failed
perror( "chdir failed" );
// handle error
}
This question already has answers here:
Is there any way to change directory using C language?
(6 answers)
Closed 8 years ago.
After a bit of research I realized that the cd system command does not have any implementation files on my system, specifically in /bin/. A class project recently required the implementation of a basic shell program that could make use of the implementation files located in this directory.
Consequentially, my program cannot change directories since cd does not exist and must have been an internal implementation by other shells.
That being said, how would you go about programmatically changing the current working directory of a program?
Each individual process has a notion of its "current directory". When a new process gets created, its current directory is its parent process's current directory.
A shell is just another process, no different from any other process, except that this particular process waits for you to type a command, then it executes the typed command as a new process.
It should now become obvious why there isn't any actual "cd" command. Say there was one. So, you typed the "cd" command, and the shell executes the "cd" command as a new process.
The new process changes its current directory, and exits.
So, what did you accomplish? Absolutely nothing. The shell's current directory has not changed. All that the "cd" process would do, in this hypothetical case, is change its own current directory, and nothing else. Then it terminates, and everything's back to the way it was before.
That's why "cd" is a built-in command. This command is one of several commands that's executed by the shell directly, and this command changes the shell's current directory. So, all future processes started from this shell will now have a new current directory.
The system call that changes the process's current directory is chdir(2). C, Perl, Python, and pretty much every other programming language has some function somewhere called chdir, or something similar, that executes the system call that changes the process's current directory.
I've written an application in C that is supposed to be reading environmental variables and handling those changes appropriately. When the application starts, I've set it up to go ahead and initialize the variable (to prevent any null pointers from returning) via setenv("MYVARIABLE", "TEST", 1).
This application loops often and, during those loops, one of its jobs is to check that global variable via getenv("MYVARIABLE").
The plan then was to have either a shell script or a python script change these environmental variables. The C application is full screen, so I have no way of testing this process without another terminal entry. In my other terminal (c2) I run commands such as:
MYVARIABLE="My New Value"
or
export MYVARIABLE="My New Value"
My application doesn't seem to catch the environmental update, though. Instead it continues to insist that MYVARIABLE is "test," and not "My New Value." I'm not sure why these two environments are separate, but I need them to work together. Does anyone know what I'm doing wrong?
My system is running Archlinux for anyone who is interested
The problem you're facing right now is that you've only set your variable in the local shell session's scope. EX:
(Assuming bash) When you set a variable such as:
MYVARIABLE="My New Value"
it only effects the current shell, when you set it as:
export MYVARIABLE="My New Value"
it effects the current shell and all processes started from the current shell.
If you set it in your .bashrc file it will set it permanently for all future sessions, but you'll need to source that file for it to work in your current session.
The best solution is to fork off a process. For example if your program is called a.out you can execute:
> ./a.out &
This will allow you to continue to work in the shell session while the program is running, then you can set variables in that same session.
The only other option I've ever seen is to force your shell session to "auto" source things as they come in:
1) In your first session enter:
trap 'source ~/.bashrc' DEBUG
2) Then start your program in the same session:
./a.out
3) In a second window edit your .bashrc file to add the new env var
4) in the second window source the new version of the file:
source ~/.bashrc
Now the first window running your program has the new var set to its session. I've used that before and I know it works, but I've never tried it on an applications that was already spawned.. but I suspect it should work for you.
Your process environment is not dynamically changeable!!!
Remember this main() prototype...
int main (int argc, char *argv[], char *envp[])
{
char *path;
/*
Searches in this process envp[] only,
There is no way it can access changes happening in Shell command prompt...
User shell does not communicate with this process, if not piped.
This will always return PATH, that was set at the time of starting.
*/
while (1)
{
path = getenv("PATH");
sleep (5);
printf("PATH = %s\n", path);
free(path);
};
}
Your understanding of getenv() library function is WRONG. To achieve your expectation, You need to use any form of IPC.
setenv() works with calling process own environment. That will be passed on to it own child process through fork(), exec() syscalls. This will will not do anything in the parent process, your shell.
I know that cd is a shell built-in ,and I can run it by using system().
But is that possible to run the cd command by the exec() family, like execvp()?
Edit: And I just noticed that system("cd") is also meaningless。Thanks for the help of everyone.
exec loads an executable file and replaces the current program image with it. As you rightly noted, cd is not an executable file, but rather a shell builtin. So the executable that you want to run is the shell itself. This is of course what system() does for you, but if you want to be explicit about it, you can use exec:
execl("/bin/sh", "-c", "cd", (const char *)0);
Since this replaces your current process image, you should do this after fork()ing off a new process.
However, this entire procedure has absolutely no effect. If you want to change the directory in your current process, use chdir().
You're better off using int chdir(const char *path); found in unistd.h.
No it is not, and it would be of no use. chdir (the function that changes a process's current directory) only affects the process that calls it (and its children). It does not affect its parent in particular.
So execing cd has no point, since the process would exit immediately after having changed directories.
(You could exec something like bash -c cd /tmp if you really want to, but as I said, this is fruitless.)
While, as already stated system("cd xxx") wouldn't change your application current directory, it is not completely useless.
You can still use system exit status to know if changing your current directory to the one stated would succeed or not.
Similarly, if you like complex solutions, you could also do the same with fork/exec, either with exec'ing /bin/sh -c cd xxx or simply /bin/cd xxx with OSes that provide an independent cd executable.
I would however recommend this non overkill faster equivalent access("xxx", X_OK|R_OK)
Note: All POSIX compliant OSes must provide an independent cd executable. This is at least the case with Solaris, AIX, HP-UX and Mac OS/X.
When a fork is done the environment variable CWD(current working directory) is inherited by the child from the parent.If fork and exec is done as usual then the child calls chdir() which simply changes the directory to the new directory and exits but this does not affect the parent.Hence, the new environment is lost..