File Coverage

IO.xs
Criterion Covered Total %
statement 123 165 74.5
branch 67 106 63.2
condition n/a
subroutine n/a
pod n/a
total 190 271 70.1


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