C++ getenv doesnt update

1.8k views Asked by At

I'm trying to make a program that a bash script runs. I want the bash script to be able to change the state of the c++ program, and the only thing I could find was to use environment variables. Thing is, its seems getenv only gets the value at the time when the program was run.

Bash

export BLINK=1
./blink &
sleep 5s
unset BLINK

C++

int main(int args, char **argv) {

    char *blink = getenv("BLINK");

    while(blink && blink[0] == '1')
    {
        std::cout << getenv("BLINK") << std::endl;
        usleep(500000);
    }

    return 1;
}

So what this does is run the blink program, wait 5 seconds then unset the environment. The C++ program however always sees the enviorment value as 1 and never stops. How do I get an updated environment variable while the program is running? Or is there a better way to have a bash script control the state of a c++ program.

EDIT I should note, I do not want to just kill the process either because it has to turn off hardware when it ends.

2

There are 2 answers

0
Daniel Frużyński On BEST ANSWER

It is not possible to modify program environment after it is started. You have to use another method of interprocess communication. The simplest one is to register handler for some signal to your app (e.g. SIGUSR1), and then send it using kill -SIGUSR1 <pid> command.

There are also other solutions available, e.g. create named pipe (using pipe shell command), and check periodically if someone wrote something to it. If yes, exit loop.

You can also use sockets if you want, but this could be more complicated.

0
Scott 'scm6079' On

The C++ programs environment is not changing when you change it in bash - since when you start your program it gets a copy of the parent's environment and has no access to the parent process's environment.

You can use a file to easily share data, however.

Bash

echo "1" > blink.txt
./blink &
sleep 5s
echo "0" > blink.txt

C++

#include <iostream>
#include <string>
#include <fstream>
#include <cstdlib>
#include <unistd.h>
using namespace std;

string getfile(const string& filename) {
    ifstream in(filename.c_str(), ios_base::binary);
    in.exceptions(ios_base::badbit | ios_base::failbit | ios_base::eofbit);
    return string(istreambuf_iterator<char>(in), istreambuf_iterator<char>());
}

int main(int argc, char* argv[]) {
    string blink = getfile("blink.txt");
    while(blink[0] == '1')
    {
        std::cout << getfile("blink.txt") << std::endl;
        usleep(500000);
    }

    return 1;
}