develooper Front page | perl.perl5.porters | Postings from December 2017

Re: [perl #115814] open ${\$x} leaks

Thread Previous | Thread Next
From:
Father Chrysostomos
Date:
December 11, 2017 04:27
Subject:
Re: [perl #115814] open ${\$x} leaks
Message ID:
8B3A2E5F-0850-4C16-9CBA-43F0DE81414D@cpan.org

On Dec 10, 2017, at 7:55 PM, "Zefram via RT" <perlbug-followup@perl.org> wrote:

> Father Chrysostomos wrote:
>> Done in 6da090e6cb and 732d3893ab.
> 
> You've broken something:
> 
> APItest.c: In function 'XS_XS__APItest_PerlIO_exportFILE':
> APItest.c:7295:9: warning: assignment from incompatible pointer type
>  RETVAL = PerlIO_exportFILE(f, mode);
>         ^

I added this to APItest.xs:

FILE *
PerlIO_exportFILE(PerlIO *f, const char *mode)

The code generated in APItest.c is as follows:

XS_EUPXS(XS_XS__APItest_PerlIO_exportFILE)
{
    dVAR; dXSARGS;
    if (items != 2)
       croak_xs_usage(cv,  "f, mode");
    {
	FILE *	RETVAL;
	PerlIO *	f = IoIFP(sv_2io(ST(0)))
;
	const char *	mode = (const char *)SvPV_nolen(ST(1))
;

	RETVAL = PerlIO_exportFILE(f, mode);
	{
	    SV * RETVALSV;
	    RETVALSV = sv_newmortal();
	    {
		GV *gv = (GV *)sv_newmortal();
		gv_init_pvn(gv, gv_stashpvs("XS::APItest",1),"__ANONIO__",10,0);
		PerlIO *fp = PerlIO_importFILE(RETVAL,0);
		if ( fp && do_open(gv, "+<&", 3, FALSE, 0, 0, fp) ) {
		    SV *rv = newRV_inc((SV*)gv);
		    rv = sv_bless(rv, GvSTASH(gv));
		    RETVALSV = sv_2mortal(rv);
		}
	    }
	    ST(0) = RETVALSV;
	}
    }
    XSRETURN(1);
}

Notice that RETVAL is declared as a FILE *.

perlio.c declared the function thus:

FILE *
PerlIO_exportFILE(PerlIO * f, const char *mode)

So how can that be an incompatible pointer type?

Maybe this has something to do with it:

$ ./perl -Ilib Porting/expand-macro.pl FILE
cc -c -DPERL_CORE -fno-common -DPERL_DARWIN -mmacosx-version-min=10.8 -DDEBUGGING -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -I/opt/local/include -DPERL_USE_SAFE_PUTENV -std=c89 -O3 -O0 -g -Wall -Werror=declaration-after-statement -Werror=pointer-arith -Wextra -Wc++-compat -Wwrite-strings -Wno-unused-value -E try.c > try.i
# 4 "FILE expands to"
PerlIO

But where is that coming from?

‘ack -n 'define FILE'’ includes in its output:

fakesdio.h
16:#define FILE			PerlIO

which means we have API functions (documented in perlapio) that are not callable without compiler warnings (or explicit casts).

> APItest.c:7302:34: warning: passing argument 1 of 'PerlIO_importFILE' from incompatible pointer type
>   PerlIO *fp = PerlIO_importFILE(RETVAL,0);
>                                  ^
> In file included from ../../iperlsys.h:51:0,
>                 from ../../perl.h:3540,
>                 from APItest.xs:10:
> ../../perlio.h:217:23: note: expected 'struct FILE *' but argument is of type 'struct PerlIOl **'
> PERL_CALLCONV PerlIO *PerlIO_importFILE(FILE *, const char *);
>                       ^
> ../../perlio.h:63:16: error: ISO C90 forbids mixed declarations and code [-Werror=declaration-after-statement]
> #define PerlIO PerlIO
>                ^
> APItest.c:7302:3: note: in expansion of macro 'PerlIO'
>   PerlIO *fp = PerlIO_importFILE(RETVAL,0);
>   ^

Well this one is my fault.  It’s a good thing I added a test!  Fixed in d269f58.

What are we supposed to do about ‘API’ functions like this?  Or perhaps a more relevant question: How do we test a FILE* typemap?

> cc1: some warnings being treated as errors
> Makefile:344: recipe for target 'APItest.o' failed
> 
> -zefram

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About