t/op/sort.t using test.pl
[p5sagit/p5-mst-13.2.git] / ext / IO / IO.xs
CommitLineData
cf7fe8a2 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 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 19# include <fcntl.h>
20#endif
8add82fc 21
63a347c7 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 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 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 47
48#ifndef gv_stashpvn
49#define gv_stashpvn(str,len,flags) gv_stashpv(str,flags)
50#endif
51
35a60386 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 68
69#ifndef PerlIO
70#define PerlIO_fileno(f) fileno(f)
8add82fc 71#endif
cf7fe8a2 72
73static int
e87a358a 74io_blocking(pTHX_ InputStream f, int block)
cf7fe8a2 75{
91f3b821 76#if defined(HAS_FCNTL)
cf7fe8a2 77 int RETVAL;
78 if(!f) {
79 errno = EBADF;
80 return -1;
81 }
cf7fe8a2 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 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 93 * after a successful F_SETFL of an O_NONBLOCK. */
94 RETVAL = RETVAL & (O_NONBLOCK | O_NDELAY) ? 0 : 1;
95
3b2f3eeb 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 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 106 * the way SysV is...
107 */
108 RETVAL = RETVAL & O_NDELAY ? 0 : 1;
109
3b2f3eeb 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 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 ST(0) = sv_newmortal();
137#if PERL_VERSION < 8
138 Fpos_t pos;
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
766a733e 146 if (PerlIO_getpos(handle, ST(0)) != 0) {
147 ST(0) = &PL_sv_undef;
148 }
35a60386 149#endif
2a0cf753 150#else
35a60386 151 Fpos_t pos;
766a733e 152 if (fgetpos(handle, &pos)) {
a6a714bd 153 ST(0) = &PL_sv_undef;
154 } else {
35a60386 155 ST(0) = sv_2mortal(newSVpvn((char*)&pos, sizeof(Fpos_t)));
a6a714bd 156 }
766a733e 157#endif
8add82fc 158 }
159 else {
8add82fc 160 errno = EINVAL;
35a60386 161 ST(0) = &PL_sv_undef;
8add82fc 162 }
8add82fc 163
164SysRet
165fsetpos(handle, pos)
166 InputStream handle
167 SV * pos
168 CODE:
766a733e 169 if (handle) {
2a0cf753 170#ifdef PerlIO
35a60386 171#if PERL_VERSION < 8
172 char *p;
173 STRLEN len;
174 if (SvOK(pos) && (p = SvPV(pos,len)) && len == sizeof(Fpos_t)) {
175 RETVAL = PerlIO_setpos(handle, (Fpos_t*)p);
176 }
177 else {
178 RETVAL = -1;
179 errno = EINVAL;
180 }
181#else
766a733e 182 RETVAL = PerlIO_setpos(handle, pos);
35a60386 183#endif
2a0cf753 184#else
766a733e 185 char *p;
186 STRLEN len;
187 if ((p = SvPV(pos,len)) && len == sizeof(Fpos_t)) {
188 RETVAL = fsetpos(handle, (Fpos_t*)p);
189 }
190 else {
191 RETVAL = -1;
192 errno = EINVAL;
193 }
2a0cf753 194#endif
766a733e 195 }
8add82fc 196 else {
197 RETVAL = -1;
198 errno = EINVAL;
199 }
8add82fc 200 OUTPUT:
201 RETVAL
202
203MODULE = IO PACKAGE = IO::File PREFIX = f
204
8063af02 205void
8add82fc 206new_tmpfile(packname = "IO::File")
35a60386 207 char * packname
a375a877 208 PREINIT:
209 OutputStream fp;
210 GV *gv;
8add82fc 211 CODE:
2a0cf753 212#ifdef PerlIO
a375a877 213 fp = PerlIO_tmpfile();
2a0cf753 214#else
a375a877 215 fp = tmpfile();
2a0cf753 216#endif
a375a877 217 gv = (GV*)SvREFCNT_inc(newGVgen(packname));
71cd1c3f 218 if (gv)
219 hv_delete(GvSTASH(gv), GvNAME(gv), GvNAMELEN(gv), G_DISCARD);
220 if (gv && do_open(gv, "+>&", 3, FALSE, 0, 0, fp)) {
6d5cdeed 221 ST(0) = sv_2mortal(newRV((SV*)gv));
a375a877 222 sv_bless(ST(0), gv_stashpv(packname, TRUE));
cf7fe8a2 223 SvREFCNT_dec(gv); /* undo increment in newRV() */
a375a877 224 }
225 else {
a1ea39dc 226 ST(0) = &PL_sv_undef;
a375a877 227 SvREFCNT_dec(gv);
228 }
8add82fc 229
cf7fe8a2 230MODULE = IO PACKAGE = IO::Poll
231
766a733e 232void
cf7fe8a2 233_poll(timeout,...)
234 int timeout;
235PPCODE:
236{
237#ifdef HAS_POLL
7698c435 238 const int nfd = (items - 1) / 2;
cf7fe8a2 239 SV *tmpsv = NEWSV(999,nfd * sizeof(struct pollfd));
240 struct pollfd *fds = (struct pollfd *)SvPVX(tmpsv);
241 int i,j,ret;
242 for(i=1, j=0 ; j < nfd ; j++) {
243 fds[j].fd = SvIV(ST(i));
244 i++;
7c436af3 245 fds[j].events = (short)SvIV(ST(i));
cf7fe8a2 246 i++;
247 fds[j].revents = 0;
248 }
249 if((ret = poll(fds,nfd,timeout)) >= 0) {
250 for(i=1, j=0 ; j < nfd ; j++) {
251 sv_setiv(ST(i), fds[j].fd); i++;
252 sv_setiv(ST(i), fds[j].revents); i++;
253 }
254 }
255 SvREFCNT_dec(tmpsv);
256 XSRETURN_IV(ret);
257#else
258 not_here("IO::Poll::poll");
259#endif
260}
261
262MODULE = IO PACKAGE = IO::Handle PREFIX = io_
263
264void
265io_blocking(handle,blk=-1)
266 InputStream handle
267 int blk
268PROTOTYPE: $;$
269CODE:
270{
7698c435 271 const int ret = io_blocking(aTHX_ handle, items == 1 ? -1 : blk ? 1 : 0);
cf7fe8a2 272 if(ret >= 0)
273 XSRETURN_IV(ret);
274 else
275 XSRETURN_UNDEF;
276}
277
8add82fc 278MODULE = IO PACKAGE = IO::Handle PREFIX = f
279
8add82fc 280int
281ungetc(handle, c)
282 InputStream handle
283 int c
284 CODE:
285 if (handle)
2a0cf753 286#ifdef PerlIO
760ac839 287 RETVAL = PerlIO_ungetc(handle, c);
2a0cf753 288#else
289 RETVAL = ungetc(c, handle);
290#endif
8add82fc 291 else {
292 RETVAL = -1;
293 errno = EINVAL;
294 }
295 OUTPUT:
296 RETVAL
297
298int
299ferror(handle)
300 InputStream handle
301 CODE:
302 if (handle)
2a0cf753 303#ifdef PerlIO
760ac839 304 RETVAL = PerlIO_error(handle);
2a0cf753 305#else
306 RETVAL = ferror(handle);
307#endif
308 else {
309 RETVAL = -1;
310 errno = EINVAL;
311 }
312 OUTPUT:
313 RETVAL
314
315int
316clearerr(handle)
317 InputStream handle
318 CODE:
319 if (handle) {
320#ifdef PerlIO
321 PerlIO_clearerr(handle);
322#else
323 clearerr(handle);
324#endif
325 RETVAL = 0;
326 }
8add82fc 327 else {
328 RETVAL = -1;
59629a13 329 errno = EINVAL;
330 }
331 OUTPUT:
332 RETVAL
333
334int
335untaint(handle)
336 SV * handle
337 CODE:
7a4c00b4 338#ifdef IOf_UNTAINT
59629a13 339 IO * io;
340 io = sv_2io(handle);
341 if (io) {
342 IoFLAGS(io) |= IOf_UNTAINT;
343 RETVAL = 0;
344 }
345 else {
7a4c00b4 346#endif
59629a13 347 RETVAL = -1;
8add82fc 348 errno = EINVAL;
7a4c00b4 349#ifdef IOf_UNTAINT
8add82fc 350 }
7a4c00b4 351#endif
8add82fc 352 OUTPUT:
353 RETVAL
354
355SysRet
356fflush(handle)
357 OutputStream handle
358 CODE:
359 if (handle)
2a0cf753 360#ifdef PerlIO
760ac839 361 RETVAL = PerlIO_flush(handle);
2a0cf753 362#else
363 RETVAL = Fflush(handle);
364#endif
8add82fc 365 else {
366 RETVAL = -1;
367 errno = EINVAL;
368 }
369 OUTPUT:
370 RETVAL
371
372void
c46a0ec2 373setbuf(handle, ...)
8add82fc 374 OutputStream handle
8add82fc 375 CODE:
376 if (handle)
760ac839 377#ifdef PERLIO_IS_STDIO
c46a0ec2 378 {
379 char *buf = items == 2 && SvPOK(ST(1)) ?
380 sv_grow(ST(1), BUFSIZ) : 0;
8add82fc 381 setbuf(handle, buf);
c46a0ec2 382 }
760ac839 383#else
384 not_here("IO::Handle::setbuf");
385#endif
8add82fc 386
387SysRet
c46a0ec2 388setvbuf(...)
8add82fc 389 CODE:
c46a0ec2 390 if (items != 4)
391 Perl_croak(aTHX_ "Usage: IO::Handle::setvbuf(handle, buf, type, size)");
1eeb0f31 392#if defined(PERLIO_IS_STDIO) && defined(_IOFBF) && defined(HAS_SETVBUF)
c46a0ec2 393 {
394 OutputStream handle = 0;
395 char * buf = SvPOK(ST(1)) ? sv_grow(ST(1), SvIV(ST(3))) : 0;
396 int type;
397 int size;
398
399 if (items == 4) {
400 handle = IoOFP(sv_2io(ST(0)));
401 buf = SvPOK(ST(1)) ? sv_grow(ST(1), SvIV(ST(3))) : 0;
402 type = (int)SvIV(ST(2));
403 size = (int)SvIV(ST(3));
404 }
d924de76 405 if (!handle) /* Try input stream. */
406 handle = IoIFP(sv_2io(ST(0)));
c46a0ec2 407 if (items == 4 && handle)
8add82fc 408 RETVAL = setvbuf(handle, buf, type, size);
409 else {
410 RETVAL = -1;
411 errno = EINVAL;
412 }
c46a0ec2 413 }
8add82fc 414#else
61839fa9 415 RETVAL = (SysRet) not_here("IO::Handle::setvbuf");
760ac839 416#endif
8add82fc 417 OUTPUT:
418 RETVAL
419
420
cf7fe8a2 421SysRet
422fsync(handle)
423 OutputStream handle
424 CODE:
425#ifdef HAS_FSYNC
426 if(handle)
427 RETVAL = fsync(PerlIO_fileno(handle));
428 else {
429 RETVAL = -1;
430 errno = EINVAL;
431 }
432#else
433 RETVAL = (SysRet) not_here("IO::Handle::sync");
434#endif
435 OUTPUT:
436 RETVAL
437
438
63a347c7 439MODULE = IO PACKAGE = IO::Socket
440
441SysRet
442sockatmark (sock)
443 InputStream sock
444 PROTOTYPE: $
445 PREINIT:
06c912bc 446 int fd;
63a347c7 447 CODE:
448 {
449 fd = PerlIO_fileno(sock);
450#ifdef HAS_SOCKATMARK
06c912bc 451 RETVAL = sockatmark(fd);
63a347c7 452#else
06c912bc 453 {
454 int flag = 0;
6d087280 455# ifdef SIOCATMARK
6e22d046 456# if defined(NETWARE) || defined(WIN32)
2986a63f 457 if (ioctl(fd, SIOCATMARK, (void*)&flag) != 0)
f754b6e0 458# else
459 if (ioctl(fd, SIOCATMARK, &flag) != 0)
460# endif
06c912bc 461 XSRETURN_UNDEF;
63a347c7 462# else
06c912bc 463 not_here("IO::Socket::atmark");
464# endif
465 RETVAL = flag;
466 }
63a347c7 467#endif
468 }
469 OUTPUT:
470 RETVAL
471
cf7fe8a2 472BOOT:
473{
474 HV *stash;
475 /*
476 * constant subs for IO::Poll
477 */
478 stash = gv_stashpvn("IO::Poll", 8, TRUE);
479#ifdef POLLIN
480 newCONSTSUB(stash,"POLLIN",newSViv(POLLIN));
481#endif
482#ifdef POLLPRI
483 newCONSTSUB(stash,"POLLPRI", newSViv(POLLPRI));
484#endif
485#ifdef POLLOUT
486 newCONSTSUB(stash,"POLLOUT", newSViv(POLLOUT));
487#endif
488#ifdef POLLRDNORM
489 newCONSTSUB(stash,"POLLRDNORM", newSViv(POLLRDNORM));
490#endif
491#ifdef POLLWRNORM
492 newCONSTSUB(stash,"POLLWRNORM", newSViv(POLLWRNORM));
493#endif
494#ifdef POLLRDBAND
495 newCONSTSUB(stash,"POLLRDBAND", newSViv(POLLRDBAND));
496#endif
497#ifdef POLLWRBAND
498 newCONSTSUB(stash,"POLLWRBAND", newSViv(POLLWRBAND));
499#endif
500#ifdef POLLNORM
501 newCONSTSUB(stash,"POLLNORM", newSViv(POLLNORM));
502#endif
503#ifdef POLLERR
504 newCONSTSUB(stash,"POLLERR", newSViv(POLLERR));
505#endif
506#ifdef POLLHUP
507 newCONSTSUB(stash,"POLLHUP", newSViv(POLLHUP));
508#endif
509#ifdef POLLNVAL
510 newCONSTSUB(stash,"POLLNVAL", newSViv(POLLNVAL));
511#endif
512 /*
513 * constant subs for IO::Handle
514 */
515 stash = gv_stashpvn("IO::Handle", 10, TRUE);
516#ifdef _IOFBF
517 newCONSTSUB(stash,"_IOFBF", newSViv(_IOFBF));
518#endif
519#ifdef _IOLBF
520 newCONSTSUB(stash,"_IOLBF", newSViv(_IOLBF));
521#endif
522#ifdef _IONBF
523 newCONSTSUB(stash,"_IONBF", newSViv(_IONBF));
524#endif
525#ifdef SEEK_SET
526 newCONSTSUB(stash,"SEEK_SET", newSViv(SEEK_SET));
527#endif
528#ifdef SEEK_CUR
529 newCONSTSUB(stash,"SEEK_CUR", newSViv(SEEK_CUR));
530#endif
531#ifdef SEEK_END
532 newCONSTSUB(stash,"SEEK_END", newSViv(SEEK_END));
533#endif
cf7fe8a2 534}
63a347c7 535