This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
When parsing LC_ALL or LANG to get the locale's encoding, ignore
[perl5.git] / ext / IO / IO.xs
CommitLineData
cf7fe8a2
GS
1/*
2 * Copyright (c) 1997-8 Graham Barr <gbarr@pobox.com>. 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
6e22d046
JH
7#define PERL_EXT_IO
8
c5be433b 9#define PERL_NO_GET_CONTEXT
8add82fc 10#include "EXTERN.h"
760ac839 11#define PERLIO_NOT_STDIO 1
8add82fc 12#include "perl.h"
13#include "XSUB.h"
cf7fe8a2 14#include "poll.h"
8add82fc 15#ifdef I_UNISTD
16# include <unistd.h>
17#endif
cf7fe8a2 18#if defined(I_FCNTL) || defined(HAS_FCNTL)
760ac839
LW
19# include <fcntl.h>
20#endif
8add82fc 21
63a347c7
JH
22#ifndef SIOCATMARK
23# ifdef I_SYS_SOCKIO
24# include <sys/sockio.h>
25# endif
26#endif
27
2a0cf753 28#ifdef PerlIO
eb44fba6 29#if defined(MACOS_TRADITIONAL) && defined(USE_SFIO)
824215e2
JH
30#define PERLIO_IS_STDIO 1
31#undef setbuf
32#undef setvbuf
33#define setvbuf _stdsetvbuf
34#define setbuf(f,b) ( __sf_setbuf(f,b) )
35#endif
8add82fc 36typedef int SysRet;
760ac839
LW
37typedef PerlIO * InputStream;
38typedef PerlIO * OutputStream;
2a0cf753 39#else
40#define PERLIO_IS_STDIO 1
41typedef int SysRet;
42typedef FILE * InputStream;
43typedef FILE * OutputStream;
44#endif
8add82fc 45
cceca5ed 46#define MY_start_subparse(fmt,flags) start_subparse(fmt,flags)
cf7fe8a2
GS
47
48#ifndef gv_stashpvn
49#define gv_stashpvn(str,len,flags) gv_stashpv(str,flags)
50#endif
51
35a60386
RGS
52#ifndef __attribute__noreturn__
53# define __attribute__noreturn__
54#endif
55
56#ifndef NORETURN_FUNCTION_END
57# define NORETURN_FUNCTION_END /* NOT REACHED */ return 0
58#endif
59
7698c435 60static int not_here(const char *s) __attribute__noreturn__;
8add82fc 61static int
7698c435 62not_here(const char *s)
8add82fc 63{
64 croak("%s not implemented on this architecture", s);
c38693a5 65 NORETURN_FUNCTION_END;
8add82fc 66}
67
cf7fe8a2
GS
68
69#ifndef PerlIO
70#define PerlIO_fileno(f) fileno(f)
8add82fc 71#endif
cf7fe8a2
GS
72
73static int
e87a358a 74io_blocking(pTHX_ InputStream f, int block)
cf7fe8a2 75{
91f3b821 76#if defined(HAS_FCNTL)
cf7fe8a2
GS
77 int RETVAL;
78 if(!f) {
79 errno = EBADF;
80 return -1;
81 }
cf7fe8a2
GS
82 RETVAL = fcntl(PerlIO_fileno(f), F_GETFL, 0);
83 if (RETVAL >= 0) {
84 int mode = RETVAL;
3b2f3eeb 85 int newmode = mode;
cf7fe8a2 86#ifdef O_NONBLOCK
766a733e 87 /* POSIX style */
cf7fe8a2 88
3b2f3eeb
BD
89# ifndef O_NDELAY
90# define O_NDELAY O_NONBLOCK
91# endif
92 /* Note: UNICOS and UNICOS/mk a F_GETFL returns an O_NDELAY
6fd254a4
JH
93 * after a successful F_SETFL of an O_NONBLOCK. */
94 RETVAL = RETVAL & (O_NONBLOCK | O_NDELAY) ? 0 : 1;
95
3b2f3eeb
BD
96 if (block == 0) {
97 newmode &= ~O_NDELAY;
98 newmode |= O_NONBLOCK;
99 } else if (block > 0) {
100 newmode &= ~(O_NDELAY|O_NONBLOCK);
cf7fe8a2 101 }
8add82fc 102#else
cf7fe8a2
GS
103 /* Not POSIX - better have O_NDELAY or we can't cope.
104 * for BSD-ish machines this is an acceptable alternative
766a733e 105 * for SysV we can't tell "would block" from EOF but that is
cf7fe8a2
GS
106 * the way SysV is...
107 */
108 RETVAL = RETVAL & O_NDELAY ? 0 : 1;
109
3b2f3eeb
BD
110 if (block == 0) {
111 newmode |= O_NDELAY;
112 } else if (block > 0) {
113 newmode &= ~O_NDELAY;
114 }
115#endif
116 if (newmode != mode) {
7698c435 117 const int ret = fcntl(PerlIO_fileno(f),F_SETFL,newmode);
3b2f3eeb 118 if (ret < 0)
cf7fe8a2 119 RETVAL = ret;
3b2f3eeb 120 }
cf7fe8a2
GS
121 }
122 return RETVAL;
8add82fc 123#else
91f3b821 124 return -1;
8add82fc 125#endif
8add82fc 126}
127
8add82fc 128MODULE = IO PACKAGE = IO::Seekable PREFIX = f
129
8063af02 130void
8add82fc 131fgetpos(handle)
132 InputStream handle
133 CODE:
8add82fc 134 if (handle) {
2a0cf753 135#ifdef PerlIO
35a60386 136#if PERL_VERSION < 8
86413ec0
SH
137 Fpos_t pos;
138 ST(0) = sv_newmortal();
35a60386
RGS
139 if (PerlIO_getpos(handle, &pos) != 0) {
140 ST(0) = &PL_sv_undef;
141 }
142 else {
143 sv_setpvn(ST(0), (char *)&pos, sizeof(Fpos_t));
144 }
145#else
86413ec0 146 ST(0) = sv_newmortal();
766a733e
NIS
147 if (PerlIO_getpos(handle, ST(0)) != 0) {
148 ST(0) = &PL_sv_undef;
149 }
35a60386 150#endif
2a0cf753 151#else
35a60386 152 Fpos_t pos;
766a733e 153 if (fgetpos(handle, &pos)) {
a6a714bd
NC
154 ST(0) = &PL_sv_undef;
155 } else {
35a60386 156 ST(0) = sv_2mortal(newSVpvn((char*)&pos, sizeof(Fpos_t)));
a6a714bd 157 }
766a733e 158#endif
8add82fc 159 }
160 else {
8add82fc 161 errno = EINVAL;
35a60386 162 ST(0) = &PL_sv_undef;
8add82fc 163 }
8add82fc 164
165SysRet
166fsetpos(handle, pos)
167 InputStream handle
168 SV * pos
169 CODE:
766a733e 170 if (handle) {
2a0cf753 171#ifdef PerlIO
35a60386
RGS
172#if PERL_VERSION < 8
173 char *p;
174 STRLEN len;
175 if (SvOK(pos) && (p = SvPV(pos,len)) && len == sizeof(Fpos_t)) {
176 RETVAL = PerlIO_setpos(handle, (Fpos_t*)p);
177 }
178 else {
179 RETVAL = -1;
180 errno = EINVAL;
181 }
182#else
766a733e 183 RETVAL = PerlIO_setpos(handle, pos);
35a60386 184#endif
2a0cf753 185#else
766a733e
NIS
186 char *p;
187 STRLEN len;
188 if ((p = SvPV(pos,len)) && len == sizeof(Fpos_t)) {
189 RETVAL = fsetpos(handle, (Fpos_t*)p);
190 }
191 else {
192 RETVAL = -1;
193 errno = EINVAL;
194 }
2a0cf753 195#endif
766a733e 196 }
8add82fc 197 else {
198 RETVAL = -1;
199 errno = EINVAL;
200 }
8add82fc 201 OUTPUT:
202 RETVAL
203
204MODULE = IO PACKAGE = IO::File PREFIX = f
205
8063af02 206void
8add82fc 207new_tmpfile(packname = "IO::File")
35a60386 208 char * packname
a375a877
GB
209 PREINIT:
210 OutputStream fp;
211 GV *gv;
8add82fc 212 CODE:
2a0cf753 213#ifdef PerlIO
a375a877 214 fp = PerlIO_tmpfile();
2a0cf753 215#else
a375a877 216 fp = tmpfile();
2a0cf753 217#endif
a375a877 218 gv = (GV*)SvREFCNT_inc(newGVgen(packname));
71cd1c3f
NC
219 if (gv)
220 hv_delete(GvSTASH(gv), GvNAME(gv), GvNAMELEN(gv), G_DISCARD);
221 if (gv && do_open(gv, "+>&", 3, FALSE, 0, 0, fp)) {
6d5cdeed 222 ST(0) = sv_2mortal(newRV((SV*)gv));
a375a877 223 sv_bless(ST(0), gv_stashpv(packname, TRUE));
cf7fe8a2 224 SvREFCNT_dec(gv); /* undo increment in newRV() */
a375a877
GB
225 }
226 else {
a1ea39dc 227 ST(0) = &PL_sv_undef;
a375a877
GB
228 SvREFCNT_dec(gv);
229 }
8add82fc 230
cf7fe8a2
GS
231MODULE = IO PACKAGE = IO::Poll
232
766a733e 233void
cf7fe8a2
GS
234_poll(timeout,...)
235 int timeout;
236PPCODE:
237{
238#ifdef HAS_POLL
7698c435 239 const int nfd = (items - 1) / 2;
cf7fe8a2
GS
240 SV *tmpsv = NEWSV(999,nfd * sizeof(struct pollfd));
241 struct pollfd *fds = (struct pollfd *)SvPVX(tmpsv);
242 int i,j,ret;
243 for(i=1, j=0 ; j < nfd ; j++) {
244 fds[j].fd = SvIV(ST(i));
245 i++;
7c436af3 246 fds[j].events = (short)SvIV(ST(i));
cf7fe8a2
GS
247 i++;
248 fds[j].revents = 0;
249 }
250 if((ret = poll(fds,nfd,timeout)) >= 0) {
251 for(i=1, j=0 ; j < nfd ; j++) {
252 sv_setiv(ST(i), fds[j].fd); i++;
253 sv_setiv(ST(i), fds[j].revents); i++;
254 }
255 }
256 SvREFCNT_dec(tmpsv);
257 XSRETURN_IV(ret);
258#else
259 not_here("IO::Poll::poll");
260#endif
261}
262
263MODULE = IO PACKAGE = IO::Handle PREFIX = io_
264
265void
266io_blocking(handle,blk=-1)
267 InputStream handle
268 int blk
269PROTOTYPE: $;$
270CODE:
271{
7698c435 272 const int ret = io_blocking(aTHX_ handle, items == 1 ? -1 : blk ? 1 : 0);
cf7fe8a2
GS
273 if(ret >= 0)
274 XSRETURN_IV(ret);
275 else
276 XSRETURN_UNDEF;
277}
278
8add82fc 279MODULE = IO PACKAGE = IO::Handle PREFIX = f
280
8add82fc 281int
282ungetc(handle, c)
283 InputStream handle
284 int c
285 CODE:
286 if (handle)
2a0cf753 287#ifdef PerlIO
760ac839 288 RETVAL = PerlIO_ungetc(handle, c);
2a0cf753 289#else
290 RETVAL = ungetc(c, handle);
291#endif
8add82fc 292 else {
293 RETVAL = -1;
294 errno = EINVAL;
295 }
296 OUTPUT:
297 RETVAL
298
299int
300ferror(handle)
301 InputStream handle
302 CODE:
303 if (handle)
2a0cf753 304#ifdef PerlIO
760ac839 305 RETVAL = PerlIO_error(handle);
2a0cf753 306#else
307 RETVAL = ferror(handle);
308#endif
309 else {
310 RETVAL = -1;
311 errno = EINVAL;
312 }
313 OUTPUT:
314 RETVAL
315
316int
317clearerr(handle)
318 InputStream handle
319 CODE:
320 if (handle) {
321#ifdef PerlIO
322 PerlIO_clearerr(handle);
323#else
324 clearerr(handle);
325#endif
326 RETVAL = 0;
327 }
8add82fc 328 else {
329 RETVAL = -1;
59629a13
RR
330 errno = EINVAL;
331 }
332 OUTPUT:
333 RETVAL
334
335int
336untaint(handle)
337 SV * handle
338 CODE:
7a4c00b4 339#ifdef IOf_UNTAINT
59629a13
RR
340 IO * io;
341 io = sv_2io(handle);
342 if (io) {
343 IoFLAGS(io) |= IOf_UNTAINT;
344 RETVAL = 0;
345 }
346 else {
7a4c00b4 347#endif
59629a13 348 RETVAL = -1;
8add82fc 349 errno = EINVAL;
7a4c00b4 350#ifdef IOf_UNTAINT
8add82fc 351 }
7a4c00b4 352#endif
8add82fc 353 OUTPUT:
354 RETVAL
355
356SysRet
357fflush(handle)
358 OutputStream handle
359 CODE:
360 if (handle)
2a0cf753 361#ifdef PerlIO
760ac839 362 RETVAL = PerlIO_flush(handle);
2a0cf753 363#else
364 RETVAL = Fflush(handle);
365#endif
8add82fc 366 else {
367 RETVAL = -1;
368 errno = EINVAL;
369 }
370 OUTPUT:
371 RETVAL
372
373void
c46a0ec2 374setbuf(handle, ...)
8add82fc 375 OutputStream handle
8add82fc 376 CODE:
377 if (handle)
760ac839 378#ifdef PERLIO_IS_STDIO
c46a0ec2
JH
379 {
380 char *buf = items == 2 && SvPOK(ST(1)) ?
381 sv_grow(ST(1), BUFSIZ) : 0;
8add82fc 382 setbuf(handle, buf);
c46a0ec2 383 }
760ac839
LW
384#else
385 not_here("IO::Handle::setbuf");
386#endif
8add82fc 387
388SysRet
c46a0ec2 389setvbuf(...)
8add82fc 390 CODE:
c46a0ec2
JH
391 if (items != 4)
392 Perl_croak(aTHX_ "Usage: IO::Handle::setvbuf(handle, buf, type, size)");
1eeb0f31 393#if defined(PERLIO_IS_STDIO) && defined(_IOFBF) && defined(HAS_SETVBUF)
c46a0ec2
JH
394 {
395 OutputStream handle = 0;
396 char * buf = SvPOK(ST(1)) ? sv_grow(ST(1), SvIV(ST(3))) : 0;
397 int type;
398 int size;
399
400 if (items == 4) {
401 handle = IoOFP(sv_2io(ST(0)));
402 buf = SvPOK(ST(1)) ? sv_grow(ST(1), SvIV(ST(3))) : 0;
403 type = (int)SvIV(ST(2));
404 size = (int)SvIV(ST(3));
405 }
d924de76
IZ
406 if (!handle) /* Try input stream. */
407 handle = IoIFP(sv_2io(ST(0)));
c46a0ec2 408 if (items == 4 && handle)
8add82fc 409 RETVAL = setvbuf(handle, buf, type, size);
410 else {
411 RETVAL = -1;
412 errno = EINVAL;
413 }
c46a0ec2 414 }
8add82fc 415#else
61839fa9 416 RETVAL = (SysRet) not_here("IO::Handle::setvbuf");
760ac839 417#endif
8add82fc 418 OUTPUT:
419 RETVAL
420
421
cf7fe8a2
GS
422SysRet
423fsync(handle)
424 OutputStream handle
425 CODE:
426#ifdef HAS_FSYNC
427 if(handle)
428 RETVAL = fsync(PerlIO_fileno(handle));
429 else {
430 RETVAL = -1;
431 errno = EINVAL;
432 }
433#else
434 RETVAL = (SysRet) not_here("IO::Handle::sync");
435#endif
436 OUTPUT:
437 RETVAL
438
439
63a347c7
JH
440MODULE = IO PACKAGE = IO::Socket
441
442SysRet
443sockatmark (sock)
444 InputStream sock
445 PROTOTYPE: $
446 PREINIT:
06c912bc 447 int fd;
63a347c7
JH
448 CODE:
449 {
450 fd = PerlIO_fileno(sock);
451#ifdef HAS_SOCKATMARK
06c912bc 452 RETVAL = sockatmark(fd);
63a347c7 453#else
06c912bc
JH
454 {
455 int flag = 0;
6d087280 456# ifdef SIOCATMARK
6e22d046 457# if defined(NETWARE) || defined(WIN32)
2986a63f 458 if (ioctl(fd, SIOCATMARK, (void*)&flag) != 0)
f754b6e0
GS
459# else
460 if (ioctl(fd, SIOCATMARK, &flag) != 0)
461# endif
06c912bc 462 XSRETURN_UNDEF;
63a347c7 463# else
06c912bc
JH
464 not_here("IO::Socket::atmark");
465# endif
466 RETVAL = flag;
467 }
63a347c7
JH
468#endif
469 }
470 OUTPUT:
471 RETVAL
472
cf7fe8a2
GS
473BOOT:
474{
475 HV *stash;
476 /*
477 * constant subs for IO::Poll
478 */
479 stash = gv_stashpvn("IO::Poll", 8, TRUE);
480#ifdef POLLIN
481 newCONSTSUB(stash,"POLLIN",newSViv(POLLIN));
482#endif
483#ifdef POLLPRI
484 newCONSTSUB(stash,"POLLPRI", newSViv(POLLPRI));
485#endif
486#ifdef POLLOUT
487 newCONSTSUB(stash,"POLLOUT", newSViv(POLLOUT));
488#endif
489#ifdef POLLRDNORM
490 newCONSTSUB(stash,"POLLRDNORM", newSViv(POLLRDNORM));
491#endif
492#ifdef POLLWRNORM
493 newCONSTSUB(stash,"POLLWRNORM", newSViv(POLLWRNORM));
494#endif
495#ifdef POLLRDBAND
496 newCONSTSUB(stash,"POLLRDBAND", newSViv(POLLRDBAND));
497#endif
498#ifdef POLLWRBAND
499 newCONSTSUB(stash,"POLLWRBAND", newSViv(POLLWRBAND));
500#endif
501#ifdef POLLNORM
502 newCONSTSUB(stash,"POLLNORM", newSViv(POLLNORM));
503#endif
504#ifdef POLLERR
505 newCONSTSUB(stash,"POLLERR", newSViv(POLLERR));
506#endif
507#ifdef POLLHUP
508 newCONSTSUB(stash,"POLLHUP", newSViv(POLLHUP));
509#endif
510#ifdef POLLNVAL
511 newCONSTSUB(stash,"POLLNVAL", newSViv(POLLNVAL));
512#endif
513 /*
514 * constant subs for IO::Handle
515 */
516 stash = gv_stashpvn("IO::Handle", 10, TRUE);
517#ifdef _IOFBF
518 newCONSTSUB(stash,"_IOFBF", newSViv(_IOFBF));
519#endif
520#ifdef _IOLBF
521 newCONSTSUB(stash,"_IOLBF", newSViv(_IOLBF));
522#endif
523#ifdef _IONBF
524 newCONSTSUB(stash,"_IONBF", newSViv(_IONBF));
525#endif
526#ifdef SEEK_SET
527 newCONSTSUB(stash,"SEEK_SET", newSViv(SEEK_SET));
528#endif
529#ifdef SEEK_CUR
530 newCONSTSUB(stash,"SEEK_CUR", newSViv(SEEK_CUR));
531#endif
532#ifdef SEEK_END
533 newCONSTSUB(stash,"SEEK_END", newSViv(SEEK_END));
534#endif
cf7fe8a2 535}
63a347c7 536