Stdout and stderror


#1

Hiya,

Just out of interest, where do the stdout and stderr files point to when an application is run from within a sandboxed Legato application?

Can they be redirected to a log file?

ciao, Dave


#2

For the moment, no.
But we have internal discussions about the use cases around this:
[ul]
[li] live access to std streams through a console in DS[/li]
[li] eventually, settings in the adef file to configure the redirection[/li][/ul]

For our information, for which particular use case you would need to access to the std streams in your context?


#3

Hiya,

ok, no problem.

[quote=“daav”]But we have internal discussions about the use cases around this:
[ul]
[li] live access to std streams through a console in DS[/li]
[li] eventually, settings in the adef file to configure the redirection[/li][/ul]

For our information, for which particular use case you would need to access to the std streams in your context?[/quote]

I’ve been looking at the facility to run external scripts from within the adef file on App startup, and was wondering about capturing the output of these scripts - especially if there is an error…

Ciao, Dave


#4

Here are a couple of workarounds until there’s a nice, convenient way to do it in the .adef or something.

If you’re using system("/bin/some_script") to launch your script, you could add a redirection to a file:

int result = system("/bin/some_script > /tmp/scriptOutput.txt");
// check result here.

Of course, if you’re running sandboxed, using “system()” requires that the shell be mapped into your sandbox.

If you are using fork() and execl() (or some other exec variant) to launch your script, then you can use “freopen()” to close stdout and stderr and re-open them to files.

const char logFilePath[] = "/tmp/scriptOutput.txt";

pid_t pid = fork();
if (pid == 0)
{
    // I'm the child (DON'T USE IPC, MUTEXES, SEMAPHORES, ETC.).
    // Just redirect my stdout and stderr to a file and exec a script.

    // Re-open stdout to the log file
    // (create it if it isn't there, truncate it if it already exists).
    FILE* filePtr;
    do
    {
        filePtr = freopen(logFilePath, "w", stdout);
    }
    while ( (filePtr == NULL) && (errno == EINTR) );
    if (filePtr == NULL)
    {
        LE_FATAL("Failed to re-open stdout to log file (%m)");
    }

    // Re-open stderr to the log file
    // (append to the end of the file, since it was already created/truncated).
    do
    {
        filePtr = freopen(logFilePath, "a", stderr);
    }
    while ( (filePtr == NULL) && (errno == EINTR) );
    if (filePtr == NULL)
    {
        LE_FATAL("Failed to re-open stderr to log file (%m)");
    }

    // Run the script.
    execl("/bin/some_script", "some_script", (char *)NULL);

    LE_FATAL("Failed to exec (%m)");
}
else
{
    // I'm the parent...
}

(Note: I haven’t tried compiling this. No warranty, expressed or implied. etc. etc. :wink: )


#5

Actually, in the first workaround (using system), you’ll need to redirect stderr too. So it should look like this:

int result = system("/bin/some_script > /tmp/scriptOutput.txt 2>&1");
// check result here.

#6

Hiya,

Ta. I’ll give it a go if I get time today.

Oops. That’s why system() was failing in a big way and returning some nasty error numbers!

Thanks, Dave