user3560634
user3560634

Reputation: 93

How to set path inside of c++ program using system() function

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

Answers (1)

Mike Kinghan
Mike Kinghan

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

  1. Get the value of PATH from the environment that your program inherits.
  2. Using that value, create the new value of PATH that you want to pass to your child process.
  3. Put that new value of PATH into the environment your child process will inherit.
  4. Run your child process.

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;
}

See it live

Upvotes: 5

Related Questions