Subject: | segfault in Net::CUPS::IPP->DESTROY |
upon success, cupsDoFileRequest() calls ippDelete() on the ipp_t object.
thus, the ipp_t structure no longer exists when Net::CUPS::IPP->DESTROY
attempts to call ippDelete().
i played around with a number of different solutions. my first attempt
was to give the SV some sort of magic that would identify whether or not
cupsDoFileRequest() was successful. then, Net::CUPS::IPP->DESTROY would
only call ippDelete() if the SV did not have that magic. however, it
appears my XS/perlguts fu is not strong enough to make this work.
instead, i dynamically created a new ipp_t object via ippNew() when
Net::CUPS->requestData is called and used sv_setiv() to replace the SV's
pointer.
i don't like either solution because of the way it destroys the original
IPP request data. it is my opinion that a better solution would be to
have Net::CUPS::IPP be a proxy object that holds the IPP data for the
entire lifetime of the object. the ipp_t structure would then only be
created when requestData is called.
attached is my patch to CUPS.xs.
Subject: | requestData-ippDelete.patch |
diff -uNr Net-CUPS-0.61-pristine/CUPS.xs Net-CUPS-0.61/CUPS.xs
--- Net-CUPS-0.61-pristine/CUPS.xs 2009-07-30 08:42:59.000000000 -0500
+++ Net-CUPS-0.61/CUPS.xs 2010-01-15 18:56:43.854662213 -0600
@@ -151,11 +151,12 @@
RETVAL
void
-NETCUPS_requestData( request, resource, filename )
- ipp_t* request;
+NETCUPS_requestData( self, resource, filename )
+ SV* self;
const char* resource;
const char* filename;
PPCODE:
+ ipp_t* request = SvIV(SvRV(self));
http_t* http = NULL;
ipp_t* response = NULL;
const char* server = NULL;
@@ -168,6 +169,8 @@
if( strlen( filename ) == 0 )
filename = NULL;
response = cupsDoFileRequest( http, request, resource, filename );
+ request = ippNew();
+ sv_setiv( SvRV(self), request );
rv = sv_newmortal();
sv_setref_pv( rv, "Net::CUPS::IPP", response );
XPUSHs( rv );
@@ -943,6 +946,7 @@
ipp_t * ipp = NULL;
SV* rv = NULL;
ipp = ippNewRequest( op );
+ printf("IPP: %p\n", ipp);
rv = sv_newmortal();
sv_setref_pv( rv, "Net::CUPS::IPP", ipp );
XPUSHs( rv );