File Coverage

IO.xs
Criterion Covered Total %
statement 124 164 75.6
branch 68 116 58.6
condition n/a
subroutine n/a
pod n/a
total 192 280 68.5


line stmt bran cond sub pod time code
1             /*
2             * Copyright (c) 1997-8 Graham Barr . All rights reserved.
3             * This program is free software; you can redistribute it and/or
4             * modify it under the same terms as Perl itself.
5             */
6              
7             #define PERL_EXT_IO
8              
9             #define PERL_NO_GET_CONTEXT
10             #include "EXTERN.h"
11             #define PERLIO_NOT_STDIO 1
12             #include "perl.h"
13             #include "XSUB.h"
14             #define NEED_newCONSTSUB
15             #define NEED_newSVpvn_flags
16             #include "ppport.h"
17             #include "poll.h"
18             #ifdef I_UNISTD
19             # include
20             #endif
21             #if defined(I_FCNTL) || defined(HAS_FCNTL)
22             # include
23             #endif
24              
25             #ifndef SIOCATMARK
26             # ifdef I_SYS_SOCKIO
27             # include
28             # endif
29             #endif
30              
31             #ifdef PerlIO
32             #if defined(MACOS_TRADITIONAL) && defined(USE_SFIO)
33             #define PERLIO_IS_STDIO 1
34             #undef setbuf
35             #undef setvbuf
36             #define setvbuf _stdsetvbuf
37             #define setbuf(f,b) ( __sf_setbuf(f,b) )
38             #endif
39             typedef int SysRet;
40             typedef PerlIO * InputStream;
41             typedef PerlIO * OutputStream;
42             #else
43             #define PERLIO_IS_STDIO 1
44             typedef int SysRet;
45             typedef FILE * InputStream;
46             typedef FILE * OutputStream;
47             #endif
48              
49             #define MY_start_subparse(fmt,flags) start_subparse(fmt,flags)
50              
51             #ifndef __attribute__noreturn__
52             # define __attribute__noreturn__
53             #endif
54              
55             #ifndef NORETURN_FUNCTION_END
56             # define NORETURN_FUNCTION_END /* NOT REACHED */ return 0
57             #endif
58              
59             #ifndef OpSIBLING
60             # define OpSIBLING(o) (o)->op_sibling
61             #endif
62              
63             static int not_here(const char *s) __attribute__noreturn__;
64             static int
65 0           not_here(const char *s)
66             {
67 0           croak("%s not implemented on this architecture", s);
68             NORETURN_FUNCTION_END;
69             }
70              
71             #ifndef PerlIO
72             #define PerlIO_fileno(f) fileno(f)
73             #endif
74              
75             static int
76 10           io_blocking(pTHX_ InputStream f, int block)
77             {
78 10           int fd = -1;
79             #if defined(HAS_FCNTL)
80             int RETVAL;
81 10 50         if (!f) {
82 0           errno = EBADF;
83 0           return -1;
84             }
85 10           fd = PerlIO_fileno(f);
86 10 50         if (fd < 0) {
87 0           errno = EBADF;
88 0           return -1;
89             }
90 10           RETVAL = fcntl(fd, F_GETFL, 0);
91 10 50         if (RETVAL >= 0) {
92 10           int mode = RETVAL;
93 10           int newmode = mode;
94             #ifdef O_NONBLOCK
95             /* POSIX style */
96              
97             # ifndef O_NDELAY
98             # define O_NDELAY O_NONBLOCK
99             # endif
100             /* Note: UNICOS and UNICOS/mk a F_GETFL returns an O_NDELAY
101             * after a successful F_SETFL of an O_NONBLOCK. */
102 10           RETVAL = RETVAL & (O_NONBLOCK | O_NDELAY) ? 0 : 1;
103              
104 10 100         if (block == 0) {
105 4           newmode &= ~O_NDELAY;
106 4           newmode |= O_NONBLOCK;
107 6 100         } else if (block > 0) {
108 1           newmode &= ~(O_NDELAY|O_NONBLOCK);
109             }
110             #else
111             /* Not POSIX - better have O_NDELAY or we can't cope.
112             * for BSD-ish machines this is an acceptable alternative
113             * for SysV we can't tell "would block" from EOF but that is
114             * the way SysV is...
115             */
116             RETVAL = RETVAL & O_NDELAY ? 0 : 1;
117              
118             if (block == 0) {
119             newmode |= O_NDELAY;
120             } else if (block > 0) {
121             newmode &= ~O_NDELAY;
122             }
123             #endif
124 10 100         if (newmode != mode) {
125 5           const int ret = fcntl(fd, F_SETFL, newmode);
126 5 50         if (ret < 0)
127 0           RETVAL = ret;
128             }
129             }
130 10           return RETVAL;
131             #else
132             # ifdef WIN32
133             if (block >= 0) {
134             unsigned long flags = !block;
135             /* ioctl claims to take char* but really needs a u_long sized buffer */
136             const int ret = ioctl(fd, FIONBIO, (char*)&flags);
137             if (ret != 0)
138             return -1;
139             /* Win32 has no way to get the current blocking status of a socket.
140             * However, we don't want to just return undef, because there's no way
141             * to tell that the ioctl succeeded.
142             */
143             return flags;
144             }
145             /* TODO: Perhaps set $! to ENOTSUP? */
146             return -1;
147             # else
148             return -1;
149             # endif
150             #endif
151             }
152              
153              
154             MODULE = IO PACKAGE = IO::Seekable PREFIX = f
155              
156             void
157             fgetpos(handle)
158             InputStream handle
159             CODE:
160 1 50         if (handle) {
161             #ifdef PerlIO
162             #if PERL_VERSION_LT(5,8,0)
163             Fpos_t pos;
164             ST(0) = sv_newmortal();
165             if (PerlIO_getpos(handle, &pos) != 0) {
166             ST(0) = &PL_sv_undef;
167             }
168             else {
169             sv_setpvn(ST(0), (char *)&pos, sizeof(Fpos_t));
170             }
171             #else
172 1           ST(0) = sv_newmortal();
173 1 50         if (PerlIO_getpos(handle, ST(0)) != 0) {
174 1           ST(0) = &PL_sv_undef;
175             }
176             #endif
177             #else
178             Fpos_t pos;
179             if (fgetpos(handle, &pos)) {
180             ST(0) = &PL_sv_undef;
181             } else {
182             # if PERL_VERSION_GE(5,11,0)
183             ST(0) = newSVpvn_flags((char*)&pos, sizeof(Fpos_t), SVs_TEMP);
184             # else
185             ST(0) = sv_2mortal(newSVpvn((char*)&pos, sizeof(Fpos_t)));
186             # endif
187             }
188             #endif
189             }
190             else {
191 0           errno = EINVAL;
192 0           ST(0) = &PL_sv_undef;
193             }
194              
195             SysRet
196             fsetpos(handle, pos)
197             InputStream handle
198             SV * pos
199             CODE:
200 2 50         if (handle) {
201             #ifdef PerlIO
202             #if PERL_VERSION_LT(5,8,0)
203             char *p;
204             STRLEN len;
205             if (SvOK(pos) && (p = SvPV(pos,len)) && len == sizeof(Fpos_t)) {
206             RETVAL = PerlIO_setpos(handle, (Fpos_t*)p);
207             }
208             else {
209             RETVAL = -1;
210             errno = EINVAL;
211             }
212             #else
213 2           RETVAL = PerlIO_setpos(handle, pos);
214             #endif
215             #else
216             char *p;
217             STRLEN len;
218             if ((p = SvPV(pos,len)) && len == sizeof(Fpos_t)) {
219             RETVAL = fsetpos(handle, (Fpos_t*)p);
220             }
221             else {
222             RETVAL = -1;
223             errno = EINVAL;
224             }
225             #endif
226             }
227             else {
228 0           RETVAL = -1;
229 0           errno = EINVAL;
230             }
231             OUTPUT:
232             RETVAL
233              
234             MODULE = IO PACKAGE = IO::File PREFIX = f
235              
236             void
237             new_tmpfile(packname = "IO::File")
238             const char * packname
239             PREINIT:
240             OutputStream fp;
241             GV *gv;
242             CODE:
243             #ifdef PerlIO
244 1           fp = PerlIO_tmpfile();
245             #else
246             fp = tmpfile();
247             #endif
248 1           gv = (GV*)SvREFCNT_inc(newGVgen(packname));
249 1 50         if (gv)
250 1           (void) hv_delete(GvSTASH(gv), GvNAME(gv), GvNAMELEN(gv), G_DISCARD);
251 1 50         if (gv && do_open(gv, "+>&", 3, FALSE, 0, 0, fp)) {
    50          
252 1           ST(0) = sv_2mortal(newRV_inc((SV*)gv));
253 1           sv_bless(ST(0), gv_stashpv(packname, TRUE));
254 1           SvREFCNT_dec(gv); /* undo increment in newRV() */
255             }
256             else {
257 0           ST(0) = &PL_sv_undef;
258 0           SvREFCNT_dec(gv);
259             }
260              
261             MODULE = IO PACKAGE = IO::Poll
262              
263             void
264             _poll(timeout,...)
265             int timeout;
266             PPCODE:
267             {
268             #ifdef HAS_POLL
269 4           const int nfd = (items - 1) / 2;
270 4           SV *tmpsv = sv_2mortal(NEWSV(999,nfd * sizeof(struct pollfd)));
271             /* We should pass _some_ valid pointer even if nfd is zero, but it
272             * doesn't matter what it is, since we're telling it to not check any fds.
273             */
274 4 100         struct pollfd *fds = nfd ? (struct pollfd *)SvPVX(tmpsv) : (struct pollfd *)tmpsv;
275             int i,j,ret;
276 6 100         for(i=1, j=0 ; j < nfd ; j++) {
277 2 50         fds[j].fd = SvIV(ST(i));
278 2           i++;
279 2 50         fds[j].events = (short)SvIV(ST(i));
280 2           i++;
281 2           fds[j].revents = 0;
282             }
283 4 50         if((ret = poll(fds,nfd,timeout)) >= 0) {
284 6 100         for(i=1, j=0 ; j < nfd ; j++) {
285 2           sv_setiv(ST(i), fds[j].fd); i++;
286 2           sv_setiv(ST(i), fds[j].revents); i++;
287             }
288             }
289 4           XSRETURN_IV(ret);
290             #else
291             not_here("IO::Poll::poll");
292             #endif
293             }
294              
295             MODULE = IO PACKAGE = IO::Handle PREFIX = io_
296              
297             void
298             io_blocking(handle,blk=-1)
299             InputStream handle
300             int blk
301             PROTOTYPE: $;$
302             CODE:
303             {
304 10 100         const int ret = io_blocking(aTHX_ handle, items == 1 ? -1 : blk ? 1 : 0);
305 10 50         if(ret >= 0)
306 10           XSRETURN_IV(ret);
307             else
308 0           XSRETURN_UNDEF;
309             }
310              
311             MODULE = IO PACKAGE = IO::Handle PREFIX = f
312              
313             int
314             ungetc(handle, c)
315             InputStream handle
316             SV * c
317             CODE:
318 8200 50         if (handle) {
319             #ifdef PerlIO
320             UV v;
321              
322 8200 50         if ((SvIOK_notUV(c) && SvIV(c) < 0) || (SvNOK(c) && SvNV(c) < 0.0))
    50          
    50          
    0          
    50          
    0          
    0          
    0          
323 0           croak("Negative character number in ungetc()");
324              
325 8200 50         v = SvUV(c);
326 8200 100         if (UVCHR_IS_INVARIANT(v) || (v <= 0xFF && !PerlIO_isutf8(handle)))
    100          
    50          
327 128           RETVAL = PerlIO_ungetc(handle, (int)v);
328             else {
329             U8 buf[UTF8_MAXBYTES + 1], *end;
330             Size_t len;
331              
332 8072 50         if (!PerlIO_isutf8(handle))
333 0           croak("Wide character number in ungetc()");
334              
335             /* This doesn't warn for non-chars, surrogate, and
336             * above-Unicodes */
337 8072           end = uvchr_to_utf8_flags(buf, v, 0);
338 8072           len = end - buf;
339 8072 50         if ((Size_t)PerlIO_unread(handle, &buf, len) == len)
340 8200           XSRETURN_UV(v);
341             else
342 0           RETVAL = EOF;
343             }
344             #else
345             RETVAL = ungetc((int)SvIV(c), handle);
346             #endif
347             }
348             else {
349 0           RETVAL = -1;
350 0           errno = EINVAL;
351             }
352             OUTPUT:
353             RETVAL
354              
355             int
356             ferror(handle)
357             SV * handle
358             PREINIT:
359 3           IO *io = sv_2io(handle);
360 3           InputStream in = IoIFP(io);
361 3           OutputStream out = IoOFP(io);
362             CODE:
363 3 50         if (in)
364             #ifdef PerlIO
365 3 50         RETVAL = PerlIO_error(in) || (out && in != out && PerlIO_error(out));
    100          
    50          
    100          
366             #else
367             RETVAL = ferror(in) || (out && in != out && ferror(out));
368             #endif
369             else {
370 0           RETVAL = -1;
371 0           errno = EINVAL;
372             }
373             OUTPUT:
374             RETVAL
375              
376             int
377             clearerr(handle)
378             SV * handle
379             PREINIT:
380 1           IO *io = sv_2io(handle);
381 1           InputStream in = IoIFP(io);
382 1           OutputStream out = IoOFP(io);
383             CODE:
384 1 50         if (handle) {
385             #ifdef PerlIO
386 1           PerlIO_clearerr(in);
387 1 50         if (in != out)
388 1           PerlIO_clearerr(out);
389             #else
390             clearerr(in);
391             if (in != out)
392             clearerr(out);
393             #endif
394 1           RETVAL = 0;
395             }
396             else {
397 0           RETVAL = -1;
398 0           errno = EINVAL;
399             }
400             OUTPUT:
401             RETVAL
402              
403             int
404             untaint(handle)
405             SV * handle
406             CODE:
407             #ifdef IOf_UNTAINT
408             IO * io;
409 3           io = sv_2io(handle);
410 1 50         if (io) {
411 1           IoFLAGS(io) |= IOf_UNTAINT;
412 1           RETVAL = 0;
413             }
414             else {
415             #endif
416 0           RETVAL = -1;
417 0           errno = EINVAL;
418             #ifdef IOf_UNTAINT
419             }
420             #endif
421             OUTPUT:
422             RETVAL
423              
424             SysRet
425             fflush(handle)
426             OutputStream handle
427             CODE:
428 2 50         if (handle)
429             #ifdef PerlIO
430 2           RETVAL = PerlIO_flush(handle);
431             #else
432             RETVAL = Fflush(handle);
433             #endif
434             else {
435 0           RETVAL = -1;
436 0           errno = EINVAL;
437             }
438             OUTPUT:
439             RETVAL
440              
441             void
442             setbuf(handle, ...)
443             OutputStream handle
444             CODE:
445 0 0         if (handle)
446             #ifdef PERLIO_IS_STDIO
447             {
448             char *buf = items == 2 && SvPOK(ST(1)) ?
449             sv_grow(ST(1), BUFSIZ) : 0;
450             setbuf(handle, buf);
451             }
452             #else
453 0           not_here("IO::Handle::setbuf");
454             #endif
455              
456             SysRet
457             setvbuf(...)
458             CODE:
459 0 0         if (items != 4)
460 0           Perl_croak(aTHX_ "Usage: IO::Handle::setvbuf(handle, buf, type, size)");
461             #if defined(PERLIO_IS_STDIO) && defined(_IOFBF) && defined(HAS_SETVBUF)
462             {
463             OutputStream handle = 0;
464             char * buf = SvPOK(ST(1)) ? sv_grow(ST(1), SvIV(ST(3))) : 0;
465             int type;
466             int size;
467              
468             if (items == 4) {
469             handle = IoOFP(sv_2io(ST(0)));
470             buf = SvPOK(ST(1)) ? sv_grow(ST(1), SvIV(ST(3))) : 0;
471             type = (int)SvIV(ST(2));
472             size = (int)SvIV(ST(3));
473             }
474             if (!handle) /* Try input stream. */
475             handle = IoIFP(sv_2io(ST(0)));
476             if (items == 4 && handle)
477             RETVAL = setvbuf(handle, buf, type, size);
478             else {
479             RETVAL = -1;
480             errno = EINVAL;
481             }
482             }
483             #else
484 0           RETVAL = (SysRet) not_here("IO::Handle::setvbuf");
485             #endif
486             OUTPUT:
487             RETVAL
488              
489              
490             SysRet
491             fsync(arg)
492             SV * arg
493             PREINIT:
494 2           OutputStream handle = NULL;
495             CODE:
496             #if defined(HAS_FSYNC) || defined(_WIN32)
497 2           handle = IoOFP(sv_2io(arg));
498 2 100         if (!handle)
499 1           handle = IoIFP(sv_2io(arg));
500 2 50         if (handle) {
501 2           int fd = PerlIO_fileno(handle);
502 2 50         if (fd >= 0) {
503             # ifdef _WIN32
504             RETVAL = _commit(fd);
505             # else
506 2           RETVAL = fsync(fd);
507             # endif
508             } else {
509 0           RETVAL = -1;
510 2           errno = EBADF;
511             }
512             } else {
513 0           RETVAL = -1;
514 0           errno = EINVAL;
515             }
516             #else
517             RETVAL = (SysRet) not_here("IO::Handle::sync");
518             #endif
519             OUTPUT:
520             RETVAL
521              
522             # To make these two work correctly with the open pragma, the readline op
523             # needs to pick up the lexical hints at the method's callsite. This doesn't
524             # work in pure Perl, because the hints are read from the most recent nextstate,
525             # and the nextstate of the Perl subroutines show *here* hold the lexical state
526             # for the IO package.
527             #
528             # There's no clean way to implement this - this approach, while complex, seems
529             # to be the most robust, and avoids manipulating external state (ie op checkers)
530             #
531             # sub getline {
532             # @_ == 1 or croak 'usage: $io->getline()';
533             # my $this = shift;
534             # return scalar <$this>;
535             # }
536             #
537             # sub getlines {
538             # @_ == 1 or croak 'usage: $io->getlines()';
539             # wantarray or
540             # croak 'Can\'t call $io->getlines in a scalar context, use $io->getline';
541             # my $this = shift;
542             # return <$this>;
543             # }
544              
545             # If this is deprecated, should it warn, and should it be removed at some point?
546             # *gets = \&getline; # deprecated
547              
548             void
549             getlines(...)
550             ALIAS:
551             IO::Handle::getline = 1
552             IO::Handle::gets = 2
553             INIT:
554             UNOP myop;
555             SV *io;
556 47           OP *was = PL_op;
557             PPCODE:
558 47 100         if (items != 1)
559 2 100         Perl_croak(aTHX_ "usage: $io->%s()", ix ? "getline" : "getlines");
560 45 100         if (!ix && GIMME_V != G_LIST)
    50          
    100          
561 2           Perl_croak(aTHX_ "Can't call $io->getlines in a scalar context, use $io->getline");
562 43           Zero(&myop, 1, UNOP);
563 43 100         myop.op_flags = (ix ? OPf_WANT_SCALAR : OPf_WANT_LIST ) | OPf_STACKED;
564 43           myop.op_ppaddr = PL_ppaddr[OP_READLINE];
565 43           myop.op_type = OP_READLINE;
566             /* I don't know if we need this, but it's correct as far as the control flow
567             goes. However, if we *do* need it, do we need to set anything else up? */
568 43           myop.op_next = PL_op->op_next;
569             /* Sigh, because pp_readline calls pp_rv2gv, and *it* has this wonderful
570             state check for PL_op->op_type == OP_READLINE */
571 43           PL_op = (OP *) &myop;
572 43           io = ST(0);
573             /* Our target (which we need to provide, as we don't have a pad entry.
574             I think that this is only needed for G_SCALAR - maybe we can get away
575             with NULL for list context? */
576 43           PUSHs(sv_newmortal());
577 43 50         XPUSHs(io);
578 43           PUTBACK;
579             /* And effectively we get away with tail calling pp_readline, as it stacks
580             exactly the return value(s) we need to return. */
581 43           PL_ppaddr[OP_READLINE](aTHX);
582 41           PL_op = was;
583             /* And we don't want to reach the line
584             PL_stack_sp = sp;
585             that xsubpp adds after our body becase PL_stack_sp is correct, not sp */
586 41           return;
587              
588             MODULE = IO PACKAGE = IO::Socket
589              
590             SysRet
591             sockatmark (sock)
592             InputStream sock
593             PROTOTYPE: $
594             PREINIT:
595             int fd;
596             CODE:
597 0           fd = PerlIO_fileno(sock);
598 0 0         if (fd < 0) {
599 0           errno = EBADF;
600 0           RETVAL = -1;
601             }
602             #ifdef HAS_SOCKATMARK
603             else {
604 0           RETVAL = sockatmark(fd);
605             }
606             #else
607             else {
608             int flag = 0;
609             # ifdef SIOCATMARK
610             # if defined(NETWARE) || defined(WIN32)
611             if (ioctl(fd, SIOCATMARK, (char*)&flag) != 0)
612             # else
613             if (ioctl(fd, SIOCATMARK, &flag) != 0)
614             # endif
615             XSRETURN_UNDEF;
616             # else
617             not_here("IO::Socket::atmark");
618             # endif
619             RETVAL = flag;
620             }
621             #endif
622             OUTPUT:
623             RETVAL
624              
625             BOOT:
626             {
627             HV *stash;
628             /*
629             * constant subs for IO::Poll
630             */
631 32           stash = gv_stashpvn("IO::Poll", 8, TRUE);
632             #ifdef POLLIN
633 32           newCONSTSUB(stash,"POLLIN",newSViv(POLLIN));
634             #endif
635             #ifdef POLLPRI
636 32           newCONSTSUB(stash,"POLLPRI", newSViv(POLLPRI));
637             #endif
638             #ifdef POLLOUT
639 32           newCONSTSUB(stash,"POLLOUT", newSViv(POLLOUT));
640             #endif
641             #ifdef POLLRDNORM
642 32           newCONSTSUB(stash,"POLLRDNORM", newSViv(POLLRDNORM));
643             #endif
644             #ifdef POLLWRNORM
645 32           newCONSTSUB(stash,"POLLWRNORM", newSViv(POLLWRNORM));
646             #endif
647             #ifdef POLLRDBAND
648 32           newCONSTSUB(stash,"POLLRDBAND", newSViv(POLLRDBAND));
649             #endif
650             #ifdef POLLWRBAND
651 32           newCONSTSUB(stash,"POLLWRBAND", newSViv(POLLWRBAND));
652             #endif
653             #ifdef POLLNORM
654             newCONSTSUB(stash,"POLLNORM", newSViv(POLLNORM));
655             #endif
656             #ifdef POLLERR
657 32           newCONSTSUB(stash,"POLLERR", newSViv(POLLERR));
658             #endif
659             #ifdef POLLHUP
660 32           newCONSTSUB(stash,"POLLHUP", newSViv(POLLHUP));
661             #endif
662             #ifdef POLLNVAL
663 32           newCONSTSUB(stash,"POLLNVAL", newSViv(POLLNVAL));
664             #endif
665             /*
666             * constant subs for IO::Handle
667             */
668 32           stash = gv_stashpvn("IO::Handle", 10, TRUE);
669             #ifdef _IOFBF
670 32           newCONSTSUB(stash,"_IOFBF", newSViv(_IOFBF));
671             #endif
672             #ifdef _IOLBF
673 32           newCONSTSUB(stash,"_IOLBF", newSViv(_IOLBF));
674             #endif
675             #ifdef _IONBF
676 32           newCONSTSUB(stash,"_IONBF", newSViv(_IONBF));
677             #endif
678             #ifdef SEEK_SET
679 32           newCONSTSUB(stash,"SEEK_SET", newSViv(SEEK_SET));
680             #endif
681             #ifdef SEEK_CUR
682 32           newCONSTSUB(stash,"SEEK_CUR", newSViv(SEEK_CUR));
683             #endif
684             #ifdef SEEK_END
685 32           newCONSTSUB(stash,"SEEK_END", newSViv(SEEK_END));
686             #endif
687             }
688