system() call not inheriting shell environment?
Hi,
We have a piece of 'C' code that we've been using on our Oracle Linux servers for sometime without issue however, we're now trying to use it on our new Redhat Server and it's not working.
The code simply makes a system call to move a file between two directories.
Following is our original code that works on Oracle Linux:
command = "mv /home/useraccount/temp/filename.txt /home/useraccount/archive/newfilename.txt"
if (system(command) == 0)
log_output("File %s has been moved", filepntr->d_name);
However to get this to work on Redhat Linux we have to include the full path to the mv command thus:
command = "/usr/bin/mv /home/useraccount/temp/filename.txt /home/useraccount/archive/newfilename.txt"
if (system(command) == 0)
log_output("File %s has been moved", filepntr->d_name);
Can anyone please advise as to why on Redhat the PATH environment variable isn't inherited when we make the system() call as it is under Oracle Linux?
Thanks,
MikeT.
Responses
Hi Mike,
What is the PATH variable set to when running your C program on RHEL server? Test with something like this:
printf("PATH : %s\n", getenv("PATH"));
Or
const char* s = getenv("PATH");
printf("PATH :%s\n",(s!=NULL)? s : "getenv returned NULL");
By the way, system() can be quite dangerous and care should be taken. Nice writeup about it:
https://wiki.sei.cmu.edu/confluence/pages/viewpage.action?pageId=87152177
Regards,
Dusan Baljevic (amateur radio VK2COT)
There likely is something else in play; the claim on PATH (or environment overall) not being inherited through system(..) did not sound credible, and is easy enough to test, so I tested.
Code:
#include <stdlib.h>
int main(char **argv, char **envp) {
system("env");
return 0;
}
So, running "env" command through system(..) in order to see what is set in the environment. Testing this by running the above (compiled as ./t) with explicitly set and very minimal environment (in order not to be drowned by all regular environment contents):
$ env -i PATH=/usr/bin:/whatever1 ./t
PATH=/usr/bin:/whatever1
PWD=/tmp
SHLVL=1
_=/usr/bin/env
$ env -i PATH=/usr/bin:/whatever2 ./t
PATH=/usr/bin:/whatever2
PWD=/tmp
SHLVL=1
_=/usr/bin/env
So, the PATH is very much inherited through system(..) here, on a RHEL7 server. This is such piece of functionality that I would be very surprised on having it to behave differently on any even near-POSIX system.
Please really do check (by printing to a log file or stderr or somewhere) the value of PATH right before your call to system(..), as already suggested above.
HTH, Juha
Hi, Mike,
yes, that was run from a shell. But that does not change the fact that it is not the "system(..)" call that loses the environment. The issue was that whereever you did run that code of yours did not have the environment to provide to the /bin/sh invocation. So it appears that in your old system, the surrounding system (Oracle DB?) behaved differently with respect to passing the environment to this code of yours.
But the suggestion to use "rename(..)" is a very good proposal here, with the possible exception of cases where the source and target locations are on separate file systems; there rename(..) will fail even though "mv" will work.
Br, Juha
Welcome! Check out the Getting Started with Red Hat page for quick tours and guides for common tasks.
