File Coverage

MsgHdr.xs
Criterion Covered Total %
statement 56 58 96.5
branch 40 80 50.0
condition n/a
subroutine n/a
pod n/a
total 96 138 69.5


line stmt bran cond sub pod time code
1             #include "EXTERN.h"
2             #include "perl.h"
3             #include "XSUB.h"
4              
5             #include "ppport.h"
6              
7             #include
8             #include
9              
10             typedef PerlIO* InOutStream;
11             typedef int SysRet;
12              
13             #ifndef PerlIO
14             #define PerlIO_fileno(f) fileno(f)
15             #endif
16              
17             static Size_t aligned_cmsghdr_sz = 0;
18              
19             struct Socket__MsgHdr {
20             struct msghdr m;
21             struct iovec io;
22             };
23              
24             static void
25 17           smhobj_2msghdr(SV *obj, struct Socket__MsgHdr *mh)
26             {
27             HV* hash;
28             SV ** svp;
29             STRLEN dlen;
30              
31 17 50         if (!obj || !sv_isa(obj, "Socket::MsgHdr"))
    50          
32 0           croak("parameter not of type Socket::MsgHdr");
33              
34 17           hash = (HV*) SvRV(obj);
35              
36 17           Zero(mh, 1, struct Socket__MsgHdr);
37              
38 17           mh->m.msg_iov = &mh->io;
39 17           mh->m.msg_iovlen = 1;
40              
41             /* Set any values supplied by the user, but translate
42             * empty strings to explicit NULLs (for FreeBSD's sake).
43             */
44 17 50         if ((svp = hv_fetch(hash, "name", 4, FALSE)) && SvOK(*svp)) {
    50          
    0          
    0          
45 17 50         mh->m.msg_name = SvPV_force(*svp, dlen);
46 17           mh->m.msg_namelen = dlen;
47 17 100         if (0 == dlen) mh->m.msg_name = NULL;
48             }
49              
50 17 50         if ((svp = hv_fetch(hash, "buf", 3, FALSE)) && SvOK(*svp)) {
    50          
    0          
    0          
51 17 100         mh->io.iov_base = SvPV_force(*svp, dlen);
52 17           mh->io.iov_len = dlen;
53 17 50         if (0 == dlen) mh->io.iov_base = NULL;
54             }
55              
56 17 50         if ((svp = hv_fetch(hash, "control", 7, FALSE)) && SvOK(*svp)) {
    50          
    0          
    0          
57 17 100         mh->m.msg_control = SvPV_force(*svp, dlen);
58 17           mh->m.msg_controllen = dlen;
59 17 100         if (0 == dlen) mh->m.msg_control = NULL;
60             }
61              
62 17 50         if ((svp = hv_fetch(hash, "flags", 5, FALSE)) && SvOK(*svp)) {
    50          
    0          
    0          
63 17 50         mh->m.msg_flags = SvIV(*svp);
64             }
65 17           }
66              
67             MODULE = Socket::MsgHdr PACKAGE = Socket::MsgHdr PREFIX = smh_
68              
69             SV *
70             smh_pack_cmsghdr(...)
71             PROTOTYPE: $$$;@
72             PREINIT:
73             STRLEN len;
74             STRLEN space;
75             I32 i;
76             struct cmsghdr *cm;
77             CODE:
78 4           space = 0;
79 9 100         for (i=0; i
80 5           len = sv_len(ST(i+2));
81 5           space += CMSG_SPACE(len);
82             }
83 4           RETVAL = newSV( space );
84 4           SvPOK_on(RETVAL);
85 4           SvCUR_set(RETVAL, space);
86              
87 4           cm = (struct cmsghdr *)SvPVX(RETVAL);
88              
89 9 100         for (i=0; i
90 5           len = sv_len(ST(i+2));
91 5           cm->cmsg_len = CMSG_LEN(len);
92 5 50         cm->cmsg_level = SvIV( ST(i) );
93 5 50         cm->cmsg_type = SvIV( ST(i+1) );
94 5           Copy(SvPVX(ST(i+2)), CMSG_DATA(cm), len, U8);
95 5           cm = (struct cmsghdr *)((U8 *)cm + CMSG_SPACE( len ));
96             }
97             OUTPUT:
98             RETVAL
99              
100             void
101             smh_unpack_cmsghdr(cmsv)
102             SV* cmsv;
103             INIT:
104             struct msghdr dummy;
105             struct cmsghdr *cm;
106             STRLEN len;
107             PPCODE:
108 2 50         dummy.msg_control = (struct cmsghdr *) SvPV(cmsv, len);
109 2           dummy.msg_controllen = len;
110              
111 2 50         if (!len)
112 0           XSRETURN_EMPTY;
113              
114 2 50         cm = CMSG_FIRSTHDR(&dummy);
115 5 100         for (; cm; cm = CMSG_NXTHDR(&dummy, cm)) {
116 3 50         XPUSHs(sv_2mortal(newSViv(cm->cmsg_level)));
117 3 50         XPUSHs(sv_2mortal(newSViv(cm->cmsg_type)));
118 3 50         XPUSHs(sv_2mortal(newSVpvn(CMSG_DATA(cm),
119             (cm->cmsg_len - aligned_cmsghdr_sz))));
120             }
121              
122             SysRet
123             smh_sendmsg(s, msg_hdr, flags = 0)
124             InOutStream s;
125             SV * msg_hdr;
126             int flags;
127              
128             PROTOTYPE: $$;$
129             PREINIT:
130             struct Socket__MsgHdr mh;
131             CODE:
132 9           smhobj_2msghdr(msg_hdr, &mh);
133 9           RETVAL = sendmsg(PerlIO_fileno(s), &mh.m, flags);
134             OUTPUT:
135             RETVAL
136              
137             SysRet
138             smh_recvmsg(s, msg_hdr, flags = 0)
139             InOutStream s;
140             SV * msg_hdr;
141             int flags;
142              
143             PROTOTYPE: $$;$
144             PREINIT:
145             struct Socket__MsgHdr mh;
146              
147             CODE:
148 8           smhobj_2msghdr(msg_hdr, &mh);
149 8 100         if ((RETVAL = recvmsg(PerlIO_fileno(s), &mh.m, flags)) >= 0) {
150             SV** svp;
151             HV* hsh;
152              
153 7           hsh = (HV*) SvRV(msg_hdr);
154              
155 7 50         if ((svp = hv_fetch(hsh, "name", 4, FALSE)))
156 7           SvCUR_set(*svp, mh.m.msg_namelen);
157 7 50         if ((svp = hv_fetch(hsh, "buf", 3, FALSE)))
158 7           SvCUR_set(*svp, RETVAL);
159 7 50         if ((svp = hv_fetch(hsh, "control", 7, FALSE)))
160 7           SvCUR_set(*svp, mh.m.msg_controllen);
161             }
162             OUTPUT:
163             RETVAL
164              
165             BOOT:
166 4           aligned_cmsghdr_sz = CMSG_LEN(0);