I would keep the myfunc()
wrapper in Perl, it works and shouldn't be a bottleneck.
Reimplementing open()
is tricky and requires usage of undocumented/internal API. I think this is a pretty close implementation. newGVgen()
and do_openn()
is part of the public API but undocumented and subject to change.
void
myfunc(sv)
SV *sv
PPCODE:
{
GV *gv = newGVgen("Mypackage");
SV *rv = sv_2mortal(newRV_noinc((SV *)gv));
SV *fd = sv_2mortal(newSViv(some_c_function_returning_an_fd()));
if (!do_openn(gv, "+<&=", 4, FALSE, 0, 0, NULL, &fd, 1))
croak("Could not fdopen descriptor: '%s'", Strerror(errno)); /* or XSRETURN_NO; */
sv_setsv(sv, rv);
SvSETMAGIC(sv);
XSRETURN_YES;
}