Prototype (stdio-like) PerlIO passing basic tests. Checked in
[p5sagit/p5-mst-13.2.git] / perlio.c
CommitLineData
760ac839 1/* perlio.c
2 *
1761cee5 3 * Copyright (c) 1996-2000, Nick Ing-Simmons
760ac839 4 *
5 * You may distribute under the terms of either the GNU General Public
6 * License or the Artistic License, as specified in the README file.
7 *
8 */
9
c5be433b 10
760ac839 11#define VOIDUSED 1
12ae5dfc 12#ifdef PERL_MICRO
13# include "uconfig.h"
14#else
15# include "config.h"
16#endif
760ac839 17
6f9d8c32 18#define PERLIO_NOT_STDIO 0
760ac839 19#if !defined(PERLIO_IS_STDIO) && !defined(USE_SFIO)
6f9d8c32 20/* #define PerlIO FILE */
760ac839 21#endif
22/*
6f9d8c32 23 * This file provides those parts of PerlIO abstraction
0f4eea8f 24 * which are not #defined in iperlsys.h.
6f9d8c32 25 * Which these are depends on various Configure #ifdef's
760ac839 26 */
27
28#include "EXTERN.h"
864dbfa3 29#define PERL_IN_PERLIO_C
760ac839 30#include "perl.h"
31
32e30700 32#if !defined(PERL_IMPLICIT_SYS)
33
6f9d8c32 34#ifdef PERLIO_IS_STDIO
760ac839 35
36void
8ac85365 37PerlIO_init(void)
760ac839 38{
6f9d8c32 39 /* Does nothing (yet) except force this file to be included
760ac839 40 in perl binary. That allows this file to force inclusion
6f9d8c32 41 of other functions that may be required by loadable
42 extensions e.g. for FileHandle::tmpfile
760ac839 43 */
44}
45
33dcbb9a 46#undef PerlIO_tmpfile
47PerlIO *
8ac85365 48PerlIO_tmpfile(void)
33dcbb9a 49{
50 return tmpfile();
51}
52
760ac839 53#else /* PERLIO_IS_STDIO */
54
55#ifdef USE_SFIO
56
57#undef HAS_FSETPOS
58#undef HAS_FGETPOS
59
6f9d8c32 60/* This section is just to make sure these functions
760ac839 61 get pulled in from libsfio.a
62*/
63
64#undef PerlIO_tmpfile
65PerlIO *
c78749f2 66PerlIO_tmpfile(void)
760ac839 67{
68 return sftmp(0);
69}
70
71void
c78749f2 72PerlIO_init(void)
760ac839 73{
6f9d8c32 74 /* Force this file to be included in perl binary. Which allows
75 * this file to force inclusion of other functions that may be
76 * required by loadable extensions e.g. for FileHandle::tmpfile
760ac839 77 */
78
79 /* Hack
80 * sfio does its own 'autoflush' on stdout in common cases.
6f9d8c32 81 * Flush results in a lot of lseek()s to regular files and
760ac839 82 * lot of small writes to pipes.
83 */
84 sfset(sfstdout,SF_SHARE,0);
85}
86
17c3b450 87#else /* USE_SFIO */
760ac839 88
6f9d8c32 89/*======================================================================================*/
90
91/* Implement all the PerlIO interface ourselves.
760ac839 92*/
93
6f9d8c32 94#undef printf
95void PerlIO_debug(char *fmt,...) __attribute__((format(printf,1,2)));
96
97
98void
99PerlIO_debug(char *fmt,...)
100{
101 static int dbg = 0;
102 if (!dbg)
103 {
104 char *s = getenv("PERLIO_DEBUG");
105 if (s && *s)
106 dbg = open(s,O_WRONLY|O_CREAT|O_APPEND,0666);
107 else
108 dbg = -1;
109 }
110 if (dbg > 0)
111 {
112 dTHX;
113 va_list ap;
114 SV *sv = newSVpvn("",0);
115 char *s;
116 STRLEN len;
117 va_start(ap,fmt);
118 sv_vcatpvf(sv, fmt, &ap);
119 s = SvPV(sv,len);
120 write(dbg,s,len);
121 va_end(ap);
122 SvREFCNT_dec(sv);
123 }
124}
125
126#define PERLIO_F_EOF 0x010000
127#define PERLIO_F_ERROR 0x020000
128#define PERLIO_F_LINEBUF 0x040000
129#define PERLIO_F_TEMP 0x080000
130#define PERLIO_F_RDBUF 0x100000
131#define PERLIO_F_WRBUF 0x200000
132#define PERLIO_F_OPEN 0x400000
133#define PERLIO_F_USED 0x800000
134
135struct _PerlIO
136{
137 IV flags;
138 IV fd; /* Maybe pointer on some OSes */
139 int oflags; /* open/fcntl flags */
140 STDCHAR *buf; /* Start of buffer */
141 STDCHAR *end; /* End of valid part of buffer */
142 STDCHAR *ptr; /* Current position in buffer */
143 Size_t bufsiz; /* Size of buffer */
144 Off_t posn;
145 int oneword;
146};
147
148int _perlio_size = 0;
149PerlIO **_perlio = NULL;
150
151void
152PerlIO_alloc_buf(PerlIO *f)
153{
154 if (!f->bufsiz)
155 f->bufsiz = 2;
156 New('B',f->buf,f->bufsiz,char);
157 if (!f->buf)
158 {
159 f->buf = (STDCHAR *)&f->oneword;
160 f->bufsiz = sizeof(f->oneword);
161 }
162 f->ptr = f->buf;
163 f->end = f->ptr;
164 PerlIO_debug(__FUNCTION__ " f=%p b=%p p=%p e=%p\n",
165 f,f->buf,f->ptr,f->end);
166}
167
168#undef PerlIO_flush
169int
170PerlIO_flush(PerlIO *f)
171{
172 int code = 0;
173 if (f)
174 {
175 PerlIO_debug(__FUNCTION__ " f=%p flags=%08X c=%d buf=%p ptr=%p\n",
176 f,f->flags,(f->ptr-f->buf),f->buf,f->ptr);
177 if (f->flags & PERLIO_F_WRBUF)
178 {
179 STDCHAR *p = f->buf;
180 int count;
181 while (p < f->ptr)
182 {
183 count = write(f->fd,p,f->ptr - p);
184 if (count > 0)
185 {
186 p += count;
187 }
188 else if (count < 0 && errno != EINTR)
189 {
190 code = -1;
191 break;
192 }
193 }
194 f->posn += (p - f->buf);
195 }
196 else if (f->flags & PERLIO_F_RDBUF)
197 {
198 f->posn += (f->ptr - f->buf);
199 if (f->ptr < f->end)
200 {
201 f->posn = lseek(f->fd,f->posn,SEEK_SET);
202 }
203 }
204 f->ptr = f->end = f->buf;
205 f->flags &= ~(PERLIO_F_RDBUF|PERLIO_F_WRBUF);
206 }
207 else
208 {
209 int i;
210 for (i=_perlio_size; i >= 0; i--)
211 {
212 if ((f = _perlio[i]))
213 {
214 if (PerlIO_flush(f) != 0)
215 code = -1;
216 }
217 }
218 }
219 return code;
220}
221
222int
223PerlIO_oflags(const char *mode)
224{
225 int oflags = -1;
226 PerlIO_debug(__FUNCTION__ " %s = ",mode);
227 switch(*mode)
228 {
229 case 'r':
230 oflags = O_RDONLY;
231 if (*++mode == '+')
232 {
233 oflags = O_RDWR;
234 mode++;
235 }
236 break;
237
238 case 'w':
239 oflags = O_CREAT|O_TRUNC;
240 if (*++mode == '+')
241 {
242 oflags |= O_RDWR;
243 mode++;
244 }
245 else
246 oflags |= O_WRONLY;
247 break;
248
249 case 'a':
250 oflags = O_CREAT|O_TRUNC|O_APPEND;
251 if (*++mode == '+')
252 {
253 oflags |= O_RDWR;
254 mode++;
255 }
256 else
257 oflags |= O_WRONLY;
258 break;
259 }
260 if (*mode || oflags == -1)
261 {
262 errno = EINVAL;
263 oflags = -1;
264 }
265 PerlIO_debug(" %X '%s'\n",oflags,mode);
266 return oflags;
267}
268
760ac839 269PerlIO *
6f9d8c32 270PerlIO_allocate(void)
271{
272 PerlIO *f;
273 int i = 0;
274 while (1)
275 {
276 PerlIO **table = _perlio;
277 while (i < _perlio_size)
278 {
279 f = table[i];
280 PerlIO_debug(__FUNCTION__ " try %d %p\n",i,f);
281 if (!f)
282 {
283 Newz('F',f,1,PerlIO);
284 if (!f)
285 return NULL;
286 table[i] = f;
287 }
288 if (!(f->flags & PERLIO_F_USED))
289 {
290 Zero(f,1,PerlIO);
291 f->flags = PERLIO_F_USED;
292 return f;
293 }
294 i++;
295 }
296 Newz('I',table,_perlio_size+16,PerlIO *);
297 if (!table)
298 return NULL;
299 Copy(_perlio,table,_perlio_size,PerlIO *);
300 if (_perlio)
301 Safefree(_perlio);
302 _perlio = table;
303 _perlio_size += 16;
304 }
305}
306
307#undef PerlIO_fdopen
308PerlIO *
309PerlIO_fdopen(int fd, const char *mode)
310{
311 PerlIO *f = NULL;
312 if (fd >= 0)
313 {
314 if ((f = PerlIO_allocate()))
315 {
316 f->fd = fd;
317 f->oflags = PerlIO_oflags(mode);
318 f->flags |= (PERLIO_F_OPEN|PERLIO_F_USED);
319 }
320 }
321 PerlIO_debug(__FUNCTION__ " fd=%d m=%s f=%p\n",fd,mode,f);
322 return f;
323}
324
325#undef PerlIO_fileno
326int
327PerlIO_fileno(PerlIO *f)
760ac839 328{
6f9d8c32 329 if (f && (f->flags & PERLIO_F_OPEN))
330 {
331 return f->fd;
332 }
333 return -1;
334}
335
336#undef PerlIO_close
337int
338PerlIO_close(PerlIO *f)
339{
340 int code = -1;
341 if (f)
342 {
343 PerlIO_flush(f);
344 while ((code = close(f->fd)) && errno == EINTR);
345 f->flags &= ~PERLIO_F_OPEN;
346 f->fd = -1;
347 if (f->buf && f->buf != (STDCHAR *) &f->oneword)
348 {
349 Safefree(f->buf);
350 }
351 f->buf = NULL;
352 f->ptr = f->end = f->buf;
353 f->flags &= ~(PERLIO_F_USED|PERLIO_F_RDBUF|PERLIO_F_WRBUF);
354 }
355 return code;
356}
357
358void
359PerlIO_cleanup(void)
360{
361 int i;
362 PerlIO_debug(__FUNCTION__ "\n");
363 for (i=_perlio_size-1; i >= 0; i--)
364 {
365 PerlIO *f = _perlio[i];
366 if (f)
367 {
368 PerlIO_close(f);
369 Safefree(f);
370 }
371 }
372 if (_perlio)
373 Safefree(_perlio);
374 _perlio = NULL;
375 _perlio_size = 0;
376}
377
378#undef PerlIO_open
379PerlIO *
380PerlIO_open(const char *path, const char *mode)
381{
382 PerlIO *f = NULL;
383 int oflags = PerlIO_oflags(mode);
384 if (oflags != -1)
385 {
386 int fd = open(path,oflags,0666);
387 if (fd >= 0)
388 {
389 PerlIO_debug(__FUNCTION__ "fd=%d\n",fd);
390 f = PerlIO_fdopen(fd,mode);
391 if (!f)
392 close(fd);
393 }
394 }
395 PerlIO_debug(__FUNCTION__ " path=%s m=%s f=%p\n",path,mode,f);
396 return f;
397}
398
399#undef PerlIO_reopen
400PerlIO *
401PerlIO_reopen(const char *path, const char *mode, PerlIO *f)
402{
403 PerlIO_debug(__FUNCTION__ " n=%s m=%s f=%p\n",path,mode,f);
404 if (f)
405 {
406 int oflags = PerlIO_oflags(mode);
407 PerlIO_close(f);
408 if (oflags != -1)
409 {
410 int fd = open(path,oflags,0666);
411 if (fd >= 0)
412 {
413 PerlIO_debug(__FUNCTION__ "fd=%d\n",fd);
414 f->oflags = oflags;
415 f->flags |= (PERLIO_F_OPEN|PERLIO_F_USED);
416 }
417 }
418 else
419 {
420 return NULL;
421 }
422 }
423 return PerlIO_open(path,mode);
424}
425
426void
427PerlIO_init(void)
428{
429 if (!_perlio)
430 {
431 atexit(&PerlIO_cleanup);
432 PerlIO_fdopen(0,"r");
433 PerlIO_fdopen(1,"w");
434 PerlIO_fdopen(2,"w");
435 }
436 PerlIO_debug(__FUNCTION__ "\n");
760ac839 437}
438
439#undef PerlIO_stdin
440PerlIO *
c78749f2 441PerlIO_stdin(void)
760ac839 442{
6f9d8c32 443 if (!_perlio)
444 PerlIO_init();
445 return _perlio[0];
760ac839 446}
447
448#undef PerlIO_stdout
449PerlIO *
c78749f2 450PerlIO_stdout(void)
760ac839 451{
6f9d8c32 452 if (!_perlio)
453 PerlIO_init();
454 return _perlio[1];
455}
456
457#undef PerlIO_stderr
458PerlIO *
459PerlIO_stderr(void)
460{
461 if (!_perlio)
462 PerlIO_init();
463 return _perlio[2];
760ac839 464}
465
760ac839 466#undef PerlIO_fast_gets
6f9d8c32 467int
c78749f2 468PerlIO_fast_gets(PerlIO *f)
760ac839 469{
760ac839 470 return 1;
760ac839 471}
472
473#undef PerlIO_has_cntptr
6f9d8c32 474int
c78749f2 475PerlIO_has_cntptr(PerlIO *f)
760ac839 476{
760ac839 477 return 1;
760ac839 478}
479
480#undef PerlIO_canset_cnt
6f9d8c32 481int
c78749f2 482PerlIO_canset_cnt(PerlIO *f)
760ac839 483{
760ac839 484 return 1;
760ac839 485}
486
487#undef PerlIO_set_cnt
488void
a20bf0c3 489PerlIO_set_cnt(PerlIO *f, int cnt)
760ac839 490{
6f9d8c32 491 if (f)
492 {
493 dTHX;
494 if (!f->buf)
495 PerlIO_alloc_buf(f);
496 f->ptr = f->end - cnt;
497 assert(f->ptr >= f->buf);
498 }
760ac839 499}
500
6f9d8c32 501#undef PerlIO_get_cnt
502int
503PerlIO_get_cnt(PerlIO *f)
760ac839 504{
6f9d8c32 505 if (f)
506 {
507 if (!f->buf)
508 PerlIO_alloc_buf(f);
509 if (f->flags & PERLIO_F_RDBUF)
510 return (f->end - f->ptr);
511 }
512 return 0;
760ac839 513}
514
6f9d8c32 515#undef PerlIO_set_ptrcnt
516void
517PerlIO_set_ptrcnt(PerlIO *f, STDCHAR *ptr, int cnt)
760ac839 518{
6f9d8c32 519 if (f)
520 {
521 dTHX;
522 if (!f->buf)
523 PerlIO_alloc_buf(f);
524 f->ptr = ptr;
525 assert(f->ptr >= f->buf);
526 if (PerlIO_get_cnt(f) != cnt)
527 {
528 dTHX;
529 assert(PerlIO_get_cnt(f) != cnt);
530 }
531 }
760ac839 532}
533
534#undef PerlIO_get_bufsiz
6f9d8c32 535int
a20bf0c3 536PerlIO_get_bufsiz(PerlIO *f)
760ac839 537{
6f9d8c32 538 if (f)
539 {
540 if (!f->buf)
541 PerlIO_alloc_buf(f);
542 return f->bufsiz;
543 }
760ac839 544 return -1;
760ac839 545}
546
547#undef PerlIO_get_ptr
888911fc 548STDCHAR *
a20bf0c3 549PerlIO_get_ptr(PerlIO *f)
760ac839 550{
6f9d8c32 551 if (f)
552 {
553 if (!f->buf)
554 PerlIO_alloc_buf(f);
555 return f->ptr;
556 }
760ac839 557 return NULL;
760ac839 558}
559
560#undef PerlIO_get_base
888911fc 561STDCHAR *
a20bf0c3 562PerlIO_get_base(PerlIO *f)
760ac839 563{
6f9d8c32 564 if (f)
565 {
566 if (!f->buf)
567 PerlIO_alloc_buf(f);
568 return f->buf;
569 }
760ac839 570 return NULL;
760ac839 571}
572
6f9d8c32 573#undef PerlIO_has_base
574int
c78749f2 575PerlIO_has_base(PerlIO *f)
760ac839 576{
6f9d8c32 577 if (f)
578 {
579 if (!f->buf)
580 PerlIO_alloc_buf(f);
581 return f->buf != NULL;
582 }
760ac839 583}
584
585#undef PerlIO_puts
586int
c78749f2 587PerlIO_puts(PerlIO *f, const char *s)
760ac839 588{
6f9d8c32 589 STRLEN len = strlen(s);
590 return PerlIO_write(f,s,len);
760ac839 591}
592
593#undef PerlIO_eof
6f9d8c32 594int
c78749f2 595PerlIO_eof(PerlIO *f)
760ac839 596{
6f9d8c32 597 if (f)
598 {
599 return (f->flags & PERLIO_F_EOF) != 0;
600 }
601 return 1;
760ac839 602}
603
8c86a920 604#undef PerlIO_getname
605char *
a20bf0c3 606PerlIO_getname(PerlIO *f, char *buf)
8c86a920 607{
608#ifdef VMS
609 return fgetname(f,buf);
610#else
961e40ee 611 dTHX;
cea2e8a9 612 Perl_croak(aTHX_ "Don't know how to get file name");
c64afb19 613 return NULL;
8c86a920 614#endif
615}
616
6f9d8c32 617#undef PerlIO_ungetc
618int
619PerlIO_ungetc(PerlIO *f, int ch)
620{
621 PerlIO_debug(__FUNCTION__ " f=%p c=%c\n",f,ch);
622 if (f->buf && (f->flags & PERLIO_F_RDBUF) && f->ptr > f->buf)
623 {
624 *--(f->ptr) = ch;
625 return ch;
626 }
627 return -1;
628}
629
630#undef PerlIO_read
631SSize_t
632PerlIO_read(PerlIO *f, void *vbuf, Size_t count)
633{
634 STDCHAR *buf = (STDCHAR *) vbuf;
635 if (f)
636 {
637 Size_t got = 0;
638 if (!f->ptr)
639 PerlIO_alloc_buf(f);
640
641 while (count > 0)
642 {
643 SSize_t avail = (f->end - f->ptr);
644 if ((SSize_t) count < avail)
645 avail = count;
646 if (avail > 0)
647 {
648 Copy(f->ptr,buf,avail,char);
649 got += avail;
650 f->ptr += avail;
651 count -= avail;
652 buf += avail;
653 }
654 if (count && (f->ptr >= f->end))
655 {
656 f->ptr = f->end = f->buf;
657 avail = read(f->fd,f->ptr,f->bufsiz);
658 if (avail <= 0)
659 {
660 if (avail == 0)
661 f->flags |= PERLIO_F_EOF;
662 else if (errno == EINTR)
663 continue;
664 else
665 f->flags |= PERLIO_F_ERROR;
666 break;
667 }
668 f->end = f->buf+avail;
669 f->flags |= PERLIO_F_RDBUF;
670 }
671 }
672 return got;
673 }
674 return 0;
675}
676
760ac839 677#undef PerlIO_getc
6f9d8c32 678int
c78749f2 679PerlIO_getc(PerlIO *f)
760ac839 680{
6f9d8c32 681 STDCHAR buf;
682 int count = PerlIO_read(f,&buf,1);
683 if (count == 1)
684 return buf;
685 return -1;
760ac839 686}
687
688#undef PerlIO_error
6f9d8c32 689int
c78749f2 690PerlIO_error(PerlIO *f)
760ac839 691{
6f9d8c32 692 if (f)
693 {
694 return f->flags & PERLIO_F_ERROR;
695 }
696 return 1;
760ac839 697}
698
699#undef PerlIO_clearerr
700void
c78749f2 701PerlIO_clearerr(PerlIO *f)
760ac839 702{
6f9d8c32 703 if (f)
704 {
705 f->flags &= ~PERLIO_F_ERROR;
706 }
760ac839 707}
708
709#undef PerlIO_setlinebuf
710void
c78749f2 711PerlIO_setlinebuf(PerlIO *f)
760ac839 712{
6f9d8c32 713 if (f)
714 {
715 f->flags &= ~PERLIO_F_LINEBUF;
716 }
760ac839 717}
718
719#undef PerlIO_write
5b54f415 720SSize_t
6f9d8c32 721PerlIO_write(PerlIO *f, const void *vbuf, Size_t count)
760ac839 722{
6f9d8c32 723 const STDCHAR *buf = (const STDCHAR *) vbuf;
724 Size_t written = 0;
725 PerlIO_debug(__FUNCTION__ " f=%p c=%d\n",f,count);
726 if (f)
727 {
728 if (!f->buf)
729 PerlIO_alloc_buf(f);
730 while (count > 0)
731 {
732 Size_t avail = f->bufsiz - (f->ptr - f->buf);
733 if (count < avail)
734 avail = count;
735 f->flags |= PERLIO_F_WRBUF;
736 if (f->flags & PERLIO_F_LINEBUF)
737 {
738 while (avail > 0)
739 {
740 int ch = *buf++;
741 *(f->ptr)++ = ch;
742 count--;
743 avail--;
744 written++;
745 if (ch == '\n')
746 PerlIO_flush(f);
747 }
748 }
749 else
750 {
751 if (avail)
752 {
753 Copy(buf,f->ptr,avail,char);
754 count -= avail;
755 buf += avail;
756 written += avail;
757 f->ptr += avail;
758 }
759 }
760 if (f->ptr >= (f->buf + f->bufsiz))
761 PerlIO_flush(f);
762 }
763 }
764 return written;
760ac839 765}
766
6f9d8c32 767#undef PerlIO_putc
768int
769PerlIO_putc(PerlIO *f, int ch)
760ac839 770{
6f9d8c32 771 STDCHAR buf = ch;
772 PerlIO_write(f,&ch,1);
760ac839 773}
774
760ac839 775#undef PerlIO_tell
5ff3f7a4 776Off_t
c78749f2 777PerlIO_tell(PerlIO *f)
760ac839 778{
6f9d8c32 779 Off_t posn = f->posn + (f->ptr - f->buf);
780 return posn;
760ac839 781}
782
783#undef PerlIO_seek
784int
c78749f2 785PerlIO_seek(PerlIO *f, Off_t offset, int whence)
760ac839 786{
6f9d8c32 787 int code = PerlIO_flush(f);
788 if (code == 0)
789 {
790 f->flags &= ~PERLIO_F_EOF;
791 f->posn = lseek(f->fd,offset,whence);
792 if (f->posn == (Off_t) -1)
793 {
794 f->posn = 0;
795 code = -1;
796 }
797 }
798 return code;
760ac839 799}
800
801#undef PerlIO_rewind
802void
c78749f2 803PerlIO_rewind(PerlIO *f)
760ac839 804{
6f9d8c32 805 PerlIO_seek(f,(Off_t)0,SEEK_SET);
806}
807
808#undef PerlIO_vprintf
809int
810PerlIO_vprintf(PerlIO *f, const char *fmt, va_list ap)
811{
812 dTHX;
813 SV *sv = newSV(strlen(fmt));
814 char *s;
815 STRLEN len;
816 sv_vcatpvf(sv, fmt, &ap);
817 s = SvPV(sv,len);
818 return (PerlIO_write(f,s,len) == len) ? 1 : 0;
760ac839 819}
820
821#undef PerlIO_printf
6f9d8c32 822int
760ac839 823PerlIO_printf(PerlIO *f,const char *fmt,...)
760ac839 824{
825 va_list ap;
826 int result;
760ac839 827 va_start(ap,fmt);
6f9d8c32 828 result = PerlIO_vprintf(f,fmt,ap);
760ac839 829 va_end(ap);
830 return result;
831}
832
833#undef PerlIO_stdoutf
6f9d8c32 834int
760ac839 835PerlIO_stdoutf(const char *fmt,...)
760ac839 836{
837 va_list ap;
838 int result;
760ac839 839 va_start(ap,fmt);
760ac839 840 result = PerlIO_vprintf(PerlIO_stdout(),fmt,ap);
841 va_end(ap);
842 return result;
843}
844
845#undef PerlIO_tmpfile
846PerlIO *
c78749f2 847PerlIO_tmpfile(void)
760ac839 848{
6f9d8c32 849 dTHX;
850 SV *sv = newSVpv("/tmp/PerlIO_XXXXXX",0);
851 int fd = mkstemp(SvPVX(sv));
852 PerlIO *f = NULL;
853 if (fd >= 0)
854 {
855 PerlIO *f = PerlIO_fdopen(fd,"w+");
856 if (f)
857 {
858 f->flags |= PERLIO_F_TEMP;
859 }
860 unlink(SvPVX(sv));
861 SvREFCNT_dec(sv);
862 }
863 return f;
760ac839 864}
865
866#undef PerlIO_importFILE
867PerlIO *
c78749f2 868PerlIO_importFILE(FILE *f, int fl)
760ac839 869{
6f9d8c32 870 int fd = fileno(f);
871 return PerlIO_fdopen(fd,"r+");
760ac839 872}
873
874#undef PerlIO_exportFILE
875FILE *
c78749f2 876PerlIO_exportFILE(PerlIO *f, int fl)
760ac839 877{
6f9d8c32 878 PerlIO_flush(f);
879 return fdopen(PerlIO_fileno(f),"r+");
760ac839 880}
881
882#undef PerlIO_findFILE
883FILE *
c78749f2 884PerlIO_findFILE(PerlIO *f)
760ac839 885{
6f9d8c32 886 return PerlIO_exportFILE(f,0);
760ac839 887}
888
889#undef PerlIO_releaseFILE
890void
c78749f2 891PerlIO_releaseFILE(PerlIO *p, FILE *f)
760ac839 892{
893}
894
6f9d8c32 895#undef HAS_FSETPOS
896#undef HAS_FGETPOS
897
898/*======================================================================================*/
760ac839 899
900#endif /* USE_SFIO */
901#endif /* PERLIO_IS_STDIO */
902
903#ifndef HAS_FSETPOS
904#undef PerlIO_setpos
905int
c78749f2 906PerlIO_setpos(PerlIO *f, const Fpos_t *pos)
760ac839 907{
6f9d8c32 908 return PerlIO_seek(f,*pos,0);
760ac839 909}
c411622e 910#else
911#ifndef PERLIO_IS_STDIO
912#undef PerlIO_setpos
913int
c78749f2 914PerlIO_setpos(PerlIO *f, const Fpos_t *pos)
c411622e 915{
2d4389e4 916#if defined(USE_64_BIT_STDIO) && defined(USE_FSETPOS64)
d9b3e12d 917 return fsetpos64(f, pos);
918#else
c411622e 919 return fsetpos(f, pos);
d9b3e12d 920#endif
c411622e 921}
922#endif
760ac839 923#endif
924
925#ifndef HAS_FGETPOS
926#undef PerlIO_getpos
927int
c78749f2 928PerlIO_getpos(PerlIO *f, Fpos_t *pos)
760ac839 929{
930 *pos = PerlIO_tell(f);
931 return 0;
932}
c411622e 933#else
934#ifndef PERLIO_IS_STDIO
935#undef PerlIO_getpos
936int
c78749f2 937PerlIO_getpos(PerlIO *f, Fpos_t *pos)
c411622e 938{
2d4389e4 939#if defined(USE_64_BIT_STDIO) && defined(USE_FSETPOS64)
d9b3e12d 940 return fgetpos64(f, pos);
941#else
c411622e 942 return fgetpos(f, pos);
d9b3e12d 943#endif
c411622e 944}
945#endif
760ac839 946#endif
947
948#if (defined(PERLIO_IS_STDIO) || !defined(USE_SFIO)) && !defined(HAS_VPRINTF)
949
950int
c78749f2 951vprintf(char *pat, char *args)
662a7e3f 952{
953 _doprnt(pat, args, stdout);
954 return 0; /* wrong, but perl doesn't use the return value */
955}
956
957int
c78749f2 958vfprintf(FILE *fd, char *pat, char *args)
760ac839 959{
960 _doprnt(pat, args, fd);
961 return 0; /* wrong, but perl doesn't use the return value */
962}
963
964#endif
965
966#ifndef PerlIO_vsprintf
6f9d8c32 967int
8ac85365 968PerlIO_vsprintf(char *s, int n, const char *fmt, va_list ap)
760ac839 969{
970 int val = vsprintf(s, fmt, ap);
971 if (n >= 0)
972 {
8c86a920 973 if (strlen(s) >= (STRLEN)n)
760ac839 974 {
bf49b057 975 dTHX;
976 PerlIO_puts(Perl_error_log,"panic: sprintf overflow - memory corrupted!\n");
977 my_exit(1);
760ac839 978 }
979 }
980 return val;
981}
982#endif
983
984#ifndef PerlIO_sprintf
6f9d8c32 985int
760ac839 986PerlIO_sprintf(char *s, int n, const char *fmt,...)
760ac839 987{
988 va_list ap;
989 int result;
760ac839 990 va_start(ap,fmt);
760ac839 991 result = PerlIO_vsprintf(s, n, fmt, ap);
992 va_end(ap);
993 return result;
994}
995#endif
996
c5be433b 997#endif /* !PERL_IMPLICIT_SYS */
998