Are you using ActiveState or Strawberry Perl? and which version?
It seems that there is a missmatch between what Perl sees as its file descriptor 2 and the C lib file descriptor 2.
use File::Temp qw(tempfile);
use Inline 'C';
open my $olderr, '>&STDERR'; # save STDERR
my ($fh, $fn) = tempfile();
open STDERR, '>&', $fh;
printf "fileno STDERR: %d\n", fileno(STDERR);
print STDERR "foo!";
test_err();
open STDERR, '>&', $olderr; # reset STDERR
close $fh;
open my $e, '<', $fn;
my $err = <$e>;
print "|$err|\n";
__END__
__C__
void test_err() {
FILE *err = fdopen(2, "a+");
(void)fprintf (err, "ERROR");
}
# here it says:
# fileno STDERR: 2
# |foo!|
# ERROR
Besides that, don't trust what you get from Inline::C, the perlio.h header is included before your C code and most stdio functions are replaced by macros calling into perl own implementations (that not-too-unsurprisingly, do not work as expected either):
update: the funny thing is that when a subprocess is launched, perl file descriptors are the ones inherited:
|