Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Confusing return value from embedded application

I'm trying to invoke one app from another in C++. The embedded app is subject to segmentation faults due to syntax errors from an input file, so the outer program would be responsible for re-running the inner, and logging failures.

My immediate idea was to rely on the return value of the inner program. So I started to experiment with that. I wrote a dummy program in Inner.cpp:

#include <iostream>

int main()
{
    std::cout << "Inner" << std::endl;
    return 22;
}

Then, I wrote this in Outer.cpp:

#include <cstdlib>
#include <iostream>

int main()
{
    int retval = system("~/Inner");
    std::cout << "Returned: " << retval << std::endl;   
    return 0;
}

Got this confusing output:

Inner
Returned: 5632

So I started reading. I soon found out, that only the 8 LS bits go through, which are treated unsigned. But wouldn't that only mean not to use values above 255? Why am I getting this strange value?

So I started looking at the bits.

What I expected: 22 -> 0000 0000 0000 0000 0000 0000 0001 0110
What I got:    5632 -> 0000 0000 0000 0000 0001 0110 0000 0000

Woah, that's the same pattern, just shifted. And indeed, when I modified my line to:

std::cout << "Returned: " << (retval >> 8) << std::endl;

I always got the exact number I wanted. However, I can't find anything on why is this happening, and now I'm concerned, that there are many more surprises when I get to the part where I'll need to detect a SIGSEGV in the inner program, and continue execution in the outer.

My question ultimately, is: What's the best way to safely embed one (command line) application in another, considering they need to communicate some minimal data, and the one being invoked might end up segfaulting? (Also, what is this bitshift thing with the return value?)

Ubuntu 12.04.4 LTS
gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
like image 999
Innkeeper Avatar asked Oct 21 '22 08:10

Innkeeper


1 Answers

You want to use fork, exec and wait, something like:

int status;
if ((pid = fork()) == 0) // child proc
     exec("~/Inner");
else // parent
    waitpid(-1, &status, 0)
like image 127
Paul Evans Avatar answered Oct 27 '22 09:10

Paul Evans