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