Cacadril has asked for the wisdom of the Perl Monks concerning the following question:

Following the perlxstut, in example 5 I get the following error:

Mytest.c:251:2: error: too few arguments to function 'statfs'

The example creates a module function statfs that is tested like this in t/Mytest.t:

my @a; @a = &Mytest::my_statfs("/blech"); # Test non-existent file/directory ok( scalar(@a) == 1 && $a[0] == 2 ); @a = &Mytest::my_statfs("/"); # Test existing file/directory is ( scalar(@a), 7 );

In other words, the function returns a list.

In Mytest.xs:

#include <sys/vfs.h> ... void statfs(path) char * path INIT: int i; struct statfs buf; PCODE: i = statfs(path, &buf); if (i == 0) { XPUSHs(sv_2mortal(newSVnv(buf.f_bavail))); XPUSHs(sv_2mortal(newSVnv(buf.f_bfree))); XPUSHs(sv_2mortal(newSVnv(buf.f_blocks))); XPUSHs(sv_2mortal(newSVnv(buf.f_bsize))); XPUSHs(sv_2mortal(newSVnv(buf.f_ffree))); XPUSHs(sv_2mortal(newSVnv(buf.f_files))); XPUSHs(sv_2mortal(newSVnv(buf.f_type))); } else { XPUSHs(sv_2mortal(newSVnv(errno))); }

The Makefile.PL generates the following C code:

XS_EUPXS(XS_Mytest_statfs) { dVAR; dXSARGS; if (items != 1) croak_xs_usage(cv, "path"); { char * path = (char *)SvPV_nolen(ST(0)) ; #line 43 "Mytest.xs" int i; struct statfs buf; PCODE: i = statfs(path, &buf); if (i == 0) { XPUSHs(sv_2mortal(newSVnv(buf.f_bavail))); XPUSHs(sv_2mortal(newSVnv(buf.f_bfree))); XPUSHs(sv_2mortal(newSVnv(buf.f_blocks))); XPUSHs(sv_2mortal(newSVnv(buf.f_bsize))); XPUSHs(sv_2mortal(newSVnv(buf.f_ffree))); XPUSHs(sv_2mortal(newSVnv(buf.f_files))); XPUSHs(sv_2mortal(newSVnv(buf.f_type))); } else { XPUSHs(sv_2mortal(newSVnv(errno))); } #line 250 "Mytest.c" statfs(path); } XSRETURN_EMPTY; }

Look near the end of this function. Why is this call to statfs being generated? I have tried to call the module function "my_statfs" instead of "statfs", Then the call near the end of the function becomes my_statfs(buf), while the call to the actual library function statfs remains statfs(path, buf), and the compiler message becomes "undefined reference to `my_statfs'".

Why is this call being generated? What am I doing wrong?

And, is XSRETURN_EMPTY the appropriate macro for a function that returns a non-empty list?

Replies are listed 'Best First'.
Re: XS generation error, function returning list
by Corion (Patriarch) on Jul 21, 2016 at 19:49 UTC

    The section name should be PPCODE:, with two P's instead of PCODE: as you wrote. I think that Perl/xsubpp leaves PCODE: alone and the C compiler interprets this as a label instead of a special XS section.

      Confirmed, thanks. I should have written PPCODE with two P's. Now it compiles. The generated C code is now PUTBACK; return; at the position of the PPCODE.

      I can only speculate that the generated call "statfs(buf)" at the end of the function has some cause related to the fact that with the PCODE being interpreted as a label, all the code was in the INIT secion.