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
}
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 have an occasion where a C program invokes a shell script, which in-turn does some copying stuff from the CD mount location to an installation directory.
Now my question is that, is there a straightforward approach to get the absolute path of this C program inside this shell script ?.
I tried a couple of approaches that includes using "$(ps -o comm= $PPID)" from within the script, but nothing did work out till now. I know that I can create a temporary file from the C program which contains its own name (argv[0]) and then make the shell script to read that file, but I don't want to follow that approach here.
Of course, it can be passed as an argument to the script, but I was thinking why the bash built-in macros or something cannot be used here
On linux there is a /proc/self/exe path that points the absolute path of the current executed file. So you can push an environment variable that contains the path before spawning the shell. Something like:
readlink("/proc/self/exe",...,buf);
putenv("MYEXE",buf);
system("thescript");
and accessing the variable in the script:
echo $MYEXE
Before running a foo command you could use which like
fooprog=$(which foo)
to get the full path of the program (scanning your $PATH). For example which ls could give /bin/ls ....
On Linux specifically you could use proc(5).
In your shell process (running bash or some POSIX compliant shell) started by your C program, $PPID give the parent process id, hopefully the pid of the process running your C program.
Then the executable is /proc/$PPID/exe which is a symbolic link. Try for example the ls -l /proc/$PPID/exe command in some terminal.
(notice that you don't run C source files or stricto sensu C programs, you often run some ELF executable which was built by compiling C code)
You might have weird cases (you'll often ignore them, but you might decide to handle them). Someone might move or replace or remove your executable while it is running. Or the parent process (your executable) died prematurely, so the shell process becomes orphan. Or the executable removed itself.
So I'm trying to create a child using fork and have that child run a program using execlp, only problem is that it isnt running... kind of. Heres my simple program
else if (pid == 0)
{
fprintf(stderr,"Child process is accessing memory %d.\n", rand_num);
execlp("helloworld", "helloworld", (char*)0);
printf("hi\n");
exit(0);
}
I've done some research and read that if the execution is successful, the printf("hi\n) wont run, and thats what happened, it wont print out hi so that means it is accessing the program right? But my program test is a simple Hello World output
#include <stdio.h>
int main()
{
printf("Hello World\n");
return 0;
}
and it isn't running, any ideas why?
I think that your program is actually working perfectly. And also, "test" is a terrible name for a command.
When you are calling execlp("test",...), the kernel looks for a program named test along your PATH environment variable (that's the the p means in execlp). It will find one in /bin:
$ ls -l /bin/test
-rwxr-xr-x. 1 root root 37368 Oct 15 04:31 /bin/test
It is highly likely that /bin is in your $PATH before your current directory. In fact, it's likely that your current directory isn't even in your $PATH.
The /bin/test program is (well, mostly was) used to implement conditional statements in the shell. E.g., when you right:
if [ -f /my/file ]; then ...
The [ is actually just another name for /bin/test.
execlp("test", "test", (char*)0);
Is this on a unix or linux system? execlp() will search the command path (your PATH environment variable) for the program, if the program specified as the first argument doesn't contain any "/" characters. That's the case here, so it's going to search the command path for a program named "test".
It happens that unix systems normally have a program in /bin or /usr/bin named "test", and if you run that program without any arguments, it doesn't print anything. You may be executing that program instead of what you intended to execute.
If this "test" program that you want to execute is in your current directory, try calling execl() instead of execlp(). execl() doesn't search your PATH, so trying to invoke "test" would only look for that program in your current directory.
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 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.