Reputation: 93
I need to write c++ program which sets path using system() function:
system("set PATH=%PATH%;C:\\Program Files (x86)\\Microsoft Visual Studio 12.0\\VC\\bin\\amd64");
system("nvcc -x cu -o cudapair cudapair.c");
But it doesnt work. It throws error, because path wasn't set. What's the problem?
Upvotes: 1
Views: 13254
Reputation: 61550
I need to write c++ program which sets path using system() function
I'm assuming what you actually need to do is write a C++ program that
sets the PATH
for the environment in which it will then execute
nvcc -x cu -o cudapair cudapair.c
You think you need to make that environment setting with
the system
function, but in fact you don't.
You should understand that a process cannot change its own environment. A process inherits its environment from its parent process, and it can change the environment that is inherited by its child processes.
That's why your posted attempt does not work.
system("set PATH=%PATH%;C:\\Program Files (x86)\\Microsoft Visual Studio 12.0\\VC\\bin\\amd64");
executes a child process of your program. That child process gets the same environment settings as your program, and can't change them. What does that child process do? It invokes the Windows shell to run the commandline:
set PATH=%PATH%;C:\\Program Files (x86)\\Microsoft Visual Studio 12.0\\VC\\bin\\amd64");
This would change the environment settings of any more child processes that were started
by this commandline. But there aren't any. The commandline makes an environment setting
that no process uses. Your system
call returns. That environment setting no longer
exists anywhere. Nothing has changed.
You then call:
system("nvcc -x cu -o cudapair cudapair.c");
which starts a second child process, again with the same environment settings that your program started with.
What you should do
PATH
from the environment that your program inherits.PATH
that you want to pass to your child process.PATH
into the environment your child process will inherit.You use system
only to do 4.
To do 1, use the Microsoft C library function getenv_s
(It is a secure variant of the Standard C++ std::getenv
)
To do 3, use the Microsoft C library function _putenv_s
(Note the leading underscore.)
Here is an illustrative program for Visual C++:
#include <iostream>
#include <string>
#include <cstdlib>
const std::size_t ENV_BUF_SIZE = 1024; // Enough for your PATH?
int main()
{
char buf[ENV_BUF_SIZE];
std::size_t bufsize = ENV_BUF_SIZE;
int e = getenv_s(&bufsize,buf,bufsize,"PATH");
if (e) {
std::cerr << "`getenv_s` failed, returned " << e << '\n';
exit(EXIT_FAILURE);
}
std::string env_path = buf;
std::cout << "In main process, `PATH`=" << env_path << std::endl;
env_path += ";C:\\Program Files (x86)\\Microsoft Visual Studio 12.0\\VC\\bin\\amd64";
e = _putenv_s("PATH",env_path.c_str());
if (e) {
std::cerr << "`_putenv_s` failed, returned " << e << std::endl;
exit(EXIT_FAILURE);
}
std::cout << std::endl;
e = std::system("echo \"In child process `PATH`=%PATH%\"");
if (e) {
std::cerr << "`std::system` failed, returned " << e << std::endl;
exit(EXIT_FAILURE);
}
return 0;
}
Upvotes: 5