/*--------------------------------------------------------------------------------------*/
/* XS Interface for perl code */
-XS(XS_perlio_import)
-{
- dXSARGS;
- GV *gv = CvGV(cv);
- char *s = GvNAME(gv);
- STRLEN l = GvNAMELEN(gv);
- PerlIO_debug("%.*s\n",(int) l,s);
- XSRETURN_EMPTY;
-}
-
-XS(XS_perlio_unimport)
-{
- dXSARGS;
- GV *gv = CvGV(cv);
- char *s = GvNAME(gv);
- STRLEN l = GvNAMELEN(gv);
- PerlIO_debug("%.*s\n",(int) l,s);
- XSRETURN_EMPTY;
-}
-
SV *
-PerlIO_find_layer(pTHX_ const char *name, STRLEN len)
+PerlIO_find_layer(pTHX_ const char *name, STRLEN len, int load)
{
SV **svp;
SV *sv;
if ((SSize_t) len <= 0)
len = strlen(name);
svp = hv_fetch(PerlIO_layer_hv,name,len,0);
- if (!svp && PL_subname && PerlIO_layer_av && av_len(PerlIO_layer_av)+1 >= 2)
+ if (!svp && load && PL_subname && PerlIO_layer_av && av_len(PerlIO_layer_av)+1 >= 2)
{
SV *pkgsv = newSVpvn("PerlIO",6);
SV *layer = newSVpvn(name,len);
if (SvROK(sv))
return *svp;
}
- return NULL;
+ return Nullsv;
}
{
STRLEN len;
const char *name = SvPV(ST(i),len);
- SV *layer = PerlIO_find_layer(aTHX_ name,len);
+ SV *layer = PerlIO_find_layer(aTHX_ name,len,1);
if (layer)
{
av_push(av,SvREFCNT_inc(layer));
SV *
PerlIO_tab_sv(pTHX_ PerlIO_funcs *tab)
{
- HV *stash = gv_stashpv("perlio::Layer", TRUE);
+ HV *stash = gv_stashpv("PerlIO::Layer", TRUE);
SV *sv = sv_bless(newRV_noinc(newSViv(PTR2IV(tab))),stash);
return sv;
}
}
if (e > s)
{
- SV *layer = PerlIO_find_layer(aTHX_ s,llen);
+ SV *layer = PerlIO_find_layer(aTHX_ s,llen,1);
if (layer)
{
av_push(av,SvREFCNT_inc(layer));
}
}
PerlIO_debug("Pushing %s\n",tab->name);
- av_push(av,SvREFCNT_inc(PerlIO_find_layer(aTHX_ tab->name,0)));
+ av_push(av,SvREFCNT_inc(PerlIO_find_layer(aTHX_ tab->name,0,0)));
av_push(av,&PL_sv_undef);
}
{
const char *s = (PL_tainting) ? Nullch : PerlEnv_getenv("PERLIO");
PerlIO_layer_av = get_av("open::layers",GV_ADD|GV_ADDMULTI);
- newXS("perlio::import",XS_perlio_import,__FILE__);
- newXS("perlio::unimport",XS_perlio_unimport,__FILE__);
#if 0
newXS("io::MODIFY_SCALAR_ATTRIBUTES",XS_io_MODIFY_SCALAR_ATTRIBUTES,__FILE__);
#endif
#endif
PerlIO_define_layer(aTHX_ &PerlIO_utf8);
PerlIO_define_layer(aTHX_ &PerlIO_byte);
- av_push(PerlIO_layer_av,SvREFCNT_inc(PerlIO_find_layer(aTHX_ PerlIO_unix.name,0)));
+ av_push(PerlIO_layer_av,SvREFCNT_inc(PerlIO_find_layer(aTHX_ PerlIO_unix.name,0,0)));
av_push(PerlIO_layer_av,&PL_sv_undef);
if (s)
{
return type;
}
+static SV *
+PerlIO_layer_from_ref(pTHX_ SV *sv)
+{
+ /* For any scalar type load the handler which is bundled with perl */
+ if (SvTYPE(sv) < SVt_PVAV)
+ return PerlIO_find_layer(aTHX_ "Scalar",6, 1);
+
+ /* For other types allow if layer is known but don't try and load it */
+ switch (SvTYPE(sv))
+ {
+ case SVt_PVAV:
+ return PerlIO_find_layer(aTHX_ "Array",5, 0);
+ case SVt_PVHV:
+ return PerlIO_find_layer(aTHX_ "Hash",4, 0);
+ case SVt_PVCV:
+ return PerlIO_find_layer(aTHX_ "Code",4, 0);
+ case SVt_PVGV:
+ return PerlIO_find_layer(aTHX_ "Glob",4, 0);
+ }
+ return Nullsv;
+}
+
AV *
PerlIO_resolve_layers(pTHX_ const char *layers,const char *mode,int narg, SV **args)
{
PerlIO_stdstreams(aTHX);
if (narg)
{
- if (SvROK(*args) && !sv_isobject(*args))
+ SV *arg = *args;
+ /* If it is a reference but not an object see if we have a handler for it */
+ if (SvROK(arg) && !sv_isobject(arg))
{
- if (SvTYPE(SvRV(*args)) < SVt_PVAV)
+ SV *handler = PerlIO_layer_from_ref(aTHX_ SvRV(arg));
+ if (handler)
{
- SV *handler = PerlIO_find_layer(aTHX_ "Scalar",6);
- if (handler)
- {
- def = newAV();
- av_push(def,SvREFCNT_inc(handler));
- av_push(def,&PL_sv_undef);
- incdef = 0;
- }
- }
- else
- {
- Perl_croak(aTHX_ "Unsupported reference arg to open()");
+ def = newAV();
+ av_push(def,SvREFCNT_inc(handler));
+ av_push(def,&PL_sv_undef);
+ incdef = 0;
}
+ /* Don't fail if handler cannot be found
+ * :Via(...) etc. may do something sensible
+ * else we will just stringfy and open resulting string.
+ */
}
}
if (!layers)
l->flags |= PERLIO_F_FASTGETS;
if (mode)
{
+ if (*mode == '#' || *mode == 'I')
+ mode++;
switch (*mode++)
{
case 'r':
{
dTHX;
#ifdef HAS_SOCKS5_INIT
- int optval, optlen = sizeof(int);
+ int optval;
+ Sock_size_t optlen = sizeof(int);
#endif
FILE *stdio = PerlIOSelf(f,PerlIOStdio)->stdio;
return(
#ifdef HAS_SOCKS5_INIT
- (getsockopt(PerlIO_fileno(f), SOL_SOCKET, SO_TYPE, (char *)&optval, &optlen) < 0) ?
+ (getsockopt(PerlIO_fileno(f), SOL_SOCKET, SO_TYPE, (void *)&optval, &optlen) < 0) ?
PerlSIO_fclose(stdio) :
close(PerlIO_fileno(f))
#else