I just realized that the PerlIO layer seems to be doing something more than just (more or less) easily transferring the functions of stdio.h. If I try to use the file descriptor allowed with PerlIO_stdout()and PerlIO_fileno()with functions from stdio.h, this will not work.
For instance:
PerlIO* perlStdErr = PerlIO_stderr();
fdStdErrOriginal = PerlIO_fileno(perlStdErr);
relocatedStdErr = dup(fdStdOutOriginal);
_write(relocatedStdErr, "something", 8); //<-- this fails
I tried this with VC10. The perl firmware is executed from a different context - therefore, it is not possible to use PerlIO from the context in which it writes to relocatedStdErr.
For the curious: I need to run a perl script and redirect the output of the stdout / stderr script to the log, while still being able to write to stdout for myself. In addition, this should work regardless of the platform (Linux, Windows console application, Win32 desktop application). Just forward stdout / stderr does not work in Win32 desktop applications, since they are not there;) - you need to use perl stdout / stderr.
Necessary solution: to be able to write to a file descriptor (or descriptor) obtained from perlio without using the PerlIO stack.
EDIT is my solution:
As the Teller narrator pointed to PerlIO_findFILE, this did the trick. So, here is an excerpt from the code - see comments inside for a description:
FILE* stdErrFILE = PerlIO_findFILE(PerlIO_stderr());
fdStdErrOriginal = _fileno(stdErrFILE);
if (fdStdErrOriginal >= 0)
{
relocatedStdErr = _dup(fdStdErrOriginal);
if (relocatedStdErr >= 0)
{
if (pipe(fdPipeStdErr) == 0)
{
if (dup2(fdPipeStdErr[1], fdStdErrOriginal) >= 0)
{
close(fdPipeStdErr[1]);
stdErrForwarder = new StreamForwarder(fdPipeStdErr[0], &processStdErrOutput, PerlIO_stderr());
return relocatedStdErr;
}
}
}
}
...
...
_write(relocatedStdErr, "Hello Stackoverflow!", 20);
, , , perl , #define PERLIO_NOT_STDIO 0 PerlIO_findFILE(). , PerlIO stdio. , , .