Monitoring a file that gets created by a sub-program executed in my in c++ program

51 views Asked by At

I'm executing a script from my c++ code. During its execution this script (say my_script) writes some information to a file (say a.txt) and I want to print that information in my main program's transcript. How can I achieve this?

Initially I wasn't interested in "a.txt", and was just executing my_script via system("my_script").

I tried using tail -F a.txt. Not sure if I'm doing it properly and maybe there is a better solution. Is running tail -F with a detached thread a good idea at all?

// assume this does some job and also
// generates a.txt with below content (there can be any number of lines containing myText)
//
// header 1
// header 2
// myText someOtherText1
// myText some other text 2
void
runMyScript()
{
    system("my_script");
}

void
monitorFile(const std::string& fName, pid_t pid)
{
    std::stringstream cmdSS;
    cmdSS << "tail -q -F --pid=" << pid << " " << fName
          << " |grep myText"; // I need to print only lines containing myText
    std::string cmd(cmdSS.str());
    system(cmd.c_str());
}

// solution 1
int main() {
    pid_t parentPID = getpid();
    // just create a new empty file
    // this helps to suspend messages from tail, like below
    // tail: cannot open 'a.txt' for reading: No such file or directory
    // tail: 'a.txt' has appeared;  following new file
    std::fstream myFstream;
    myFstream.open("a.txt", std::fstream::out);
    myFstream.close();
    
    // actually would be better to stop tail when my_prog is done
    // so, I tried solution 2 as well
    std::thread t(monitorFile, "a.txt", parentPID);
    t.detach();

    runMyScript();
    
    return 0;
}

// solution 2
/*
int main() {
    std::fstream myFstream;
    myFstream.open("a.txt", std::fstream::out);
    myFstream.close();
    
    pid_t cPID = fork();
    if (cPID== 0) { // child
        execl("/bin/csh", "csh", "my_script", (char *) nullptr);
        perror("execl failed");
    } else if (cPID > 0) { // parent
        thread t(monitorFile, "a.txt", cPID);
        t.detach();

        // wait for my_script to finish
        int status;
        waitpid(cPID, &status, 0);
    } else {
        std::cout << "ERROR" << std::endl;
    }
    
    return 0;
}
*/
1

There are 1 answers

0
Muhammad Ayyaz On

Consider utilizing notify for real-time file change notifications. However, ponder the benefits of consolidating the entire codebase into a single language, such as C++. Isn't the idea of a unified language, like C++, more advantageous for seamless integration and streamlined development?