This issue is more or less related to embedded perl in C, perlapio - interoperability with STDIO which I think I have solved for the Windows environment. I will post a complete solution if this new issue is solved too.
In the linked question,
StoryTeller gave me the hint
to use PerlIO_findFILE()
which solved the immediate problem, but the same code on Linux behaves strangely.
Perl's dup2()
seems to have a different behaviour on Win32, where dup2()
is a macro for win32_dup2()
, which as far as I understand simply uses the dup2()
from io.h
.
On Win32, Perl's version returns zero on success and non-zero on error, but on Linux the default ANSI dup2()
will be used, which instead returns the new file descriptor. Then, I'll have to check errno
if everything went fine.
If a call to PerlIO_findFILE()
sets errno
to "illegal seek" (errno 29 - ESPIPE
), then after dup
, dup2
, pipe
etc. errno
is still set to "illegal seek", and any further checks on errno
still see the same error.
(In practice everything has worked for me because there was no actual error. Also, the solution by checking errno
is not thread safe, since between the syscall and the check another tread may reset errno.)
Note that I have
#define PERLIO_NOT_STDIO 0
in effect and I'm using Perl5.14.1.
Am I doing something really wrong here?
Here's a simplified code snippet:
stdOutFILE = PerlIO_findFILE(PerlIO_stderr()); // convert Perl's stdout to stdio FILE handle
fdStdOutOriginal = fileno(stdOutFILE); // get descriptor
if ( fdStdOutOriginal >= 0 ) {
relocatedStdOut = dup(fdStdOutOriginal); // relocate stdOut for external writing
if ( relocatedStdOut >= 0 )
{
if ( pipe(fdPipeStdOut) == 0 ) // create pipe for forwarding to stderr
{
// this has to be done on win32:
// if ( dup2(fdPipeStdOut[1], fdStdOutOriginal) == 0 ) // hang pipe on stdOut
dup2(fdPipeStdOut[1], fdStdOutOriginal);
if( errno == 0 ) {
// do some funny stuff
} else {
// report error
}
}
}
}