IO-Handle-Record
view release on metacpan or search on metacpan
SETERRNO(0,0);
if( SvROK(stream) &&
(sv=SvRV(stream)) &&
SvTYPE(sv)==SVt_PVGV &&
(io=GvIO(sv)) &&
IoIFP(io) ) {
if( (ret=recvmsg(PerlIO_fileno(IoIFP(io)), &msg, flags))<0 ) goto ret;
SvCUR_set(buffer, ret+offset);
*SvEND(buffer)='\0';
SvPOK_only(buffer);
if( (cmsgp=CMSG_FIRSTHDR(&msg))!=NULL &&
cmsgp->cmsg_len>0 &&
cmsgp->cmsg_level==SOL_SOCKET &&
cmsgp->cmsg_type==SCM_RIGHTS ) {
fdp=(int*)CMSG_DATA(cmsgp);
nfds=(cmsgp->cmsg_len-
((char*)fdp-(char*)cmsgp))/sizeof(int);
/* warn("==> expecting %d fds -- got %d bytes, %d fds", rlim.rlim_cur, ret, nfds); */
if( nfds>0 ) {
/* sv is the typeglob of the filehandle here */
svp=hv_fetch(GvHV(sv), RCV_KEY, sizeof(RCV_KEY)-1, FALSE);
if( !(svp && SvROK(*svp) &&
(fd_av=(AV*)SvRV(*svp)) &&
SvTYPE(fd_av)==SVt_PVAV) ) {
/*
* ${*$I}{RCV_KEY}=[]
* unless exists ${*$I}{RCV_KEY} and
* ref(${*$I}{RCV_KEY}) eq 'ARRAY'
*/
(void)hv_store(GvHV(sv), RCV_KEY, sizeof(RCV_KEY)-1,
newRV_inc((SV*)(fd_av=newAV())), 0);
}
av_extend(fd_av, av_len(fd_av)+1+nfds);
for( i=0; i<nfds; i++ ) {
sv=call_open_fd(fdp[i]);
if( sv ) av_push(fd_av, sv);
}
}
/* } else { */
/* warn("==> expecting %d fds -- got %d bytes, no CMSG", rlim.rlim_cur, ret); */
}
} else {
SETERRNO(EBADF, RMS_IFI);
}
ret:
if( msg.msg_control ) Safefree(msg.msg_control);
return ret;
}
MODULE = IO::Handle::Record PACKAGE = IO::Handle::Record PREFIX = smh_
void
smh_peercred(s)
PerlIO* s;
PROTOTYPE: $
PPCODE:
{
# ifdef SO_PEERCRED
struct ucred uc;
socklen_t uc_len=sizeof(uc);
if( !getsockopt(PerlIO_fileno(s), SOL_SOCKET, SO_PEERCRED, &uc, &uc_len) ) {
EXTEND(SP, 3);
PUSHs(sv_2mortal(newSViv(uc.pid)));
PUSHs(sv_2mortal(newSViv(uc.uid)));
PUSHs(sv_2mortal(newSViv(uc.gid)));
}
# else
SETERRNO(EOPNOTSUPP, RMS_IFI);
# endif
}
void
smh_issock(s)
PerlIO* s;
PROTOTYPE: $
PPCODE:
{
if( fdtype(PerlIO_fileno(s))==S_IFSOCK ) {
XSRETURN_YES;
} else {
XSRETURN_UNDEF;
}
}
char *
smh_typeof(fd)
int fd;
PROTOTYPE: $
CODE:
{
switch(fdtype(fd)) {
case S_IFSOCK:
switch(socket_family(fd)) {
case AF_UNIX:
RETVAL=("IO::Socket::UNIX");
break;
case AF_INET:
RETVAL=("IO::Socket::INET");
break;
case AF_INET6:
RETVAL=("IO::Socket::INET6");
break;
default:
RETVAL=("IO::Handle");
break;
}
break;
case S_IFREG:
RETVAL=("IO::File");
break;
case S_IFDIR:
RETVAL=("IO::Dir");
break;
case S_IFIFO:
RETVAL=("IO::Pipe");
break;
default:
RETVAL=("IO::Handle");
break;
}
}
OUTPUT:
RETVAL
int
smh_socket_type(s)
int s;
PROTOTYPE: $
CODE:
RETVAL=socket_type(s);
OUTPUT:
RETVAL
int
( run in 0.631 second using v1.01-cache-2.11-cpan-71847e10f99 )