This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Const Boy II: The Localizing
[perl5.git] / pp_sys.c
1 /*    pp_sys.c
2  *
3  *    Copyright (C) 1995, 1996, 1997, 1998, 1999,
4  *    2000, 2001, 2002, 2003, 2004, 2005, by Larry Wall and others
5  *
6  *    You may distribute under the terms of either the GNU General Public
7  *    License or the Artistic License, as specified in the README file.
8  *
9  */
10
11 /*
12  * But only a short way ahead its floor and the walls on either side were
13  * cloven by a great fissure, out of which the red glare came, now leaping
14  * up, now dying down into darkness; and all the while far below there was
15  * a rumour and a trouble as of great engines throbbing and labouring.
16  */
17
18 /* This file contains system pp ("push/pop") functions that
19  * execute the opcodes that make up a perl program. A typical pp function
20  * expects to find its arguments on the stack, and usually pushes its
21  * results onto the stack, hence the 'pp' terminology. Each OP structure
22  * contains a pointer to the relevant pp_foo() function.
23  *
24  * By 'system', we mean ops which interact with the OS, such as pp_open().
25  */
26
27 #include "EXTERN.h"
28 #define PERL_IN_PP_SYS_C
29 #include "perl.h"
30
31 #ifdef I_SHADOW
32 /* Shadow password support for solaris - pdo@cs.umd.edu
33  * Not just Solaris: at least HP-UX, IRIX, Linux.
34  * The API is from SysV.
35  *
36  * There are at least two more shadow interfaces,
37  * see the comments in pp_gpwent().
38  *
39  * --jhi */
40 #   ifdef __hpux__
41 /* There is a MAXINT coming from <shadow.h> <- <hpsecurity.h> <- <values.h>
42  * and another MAXINT from "perl.h" <- <sys/param.h>. */
43 #       undef MAXINT
44 #   endif
45 #   include <shadow.h>
46 #endif
47
48 #ifdef I_SYS_WAIT
49 # include <sys/wait.h>
50 #endif
51
52 #ifdef I_SYS_RESOURCE
53 # include <sys/resource.h>
54 #endif
55
56 #ifdef NETWARE
57 NETDB_DEFINE_CONTEXT
58 #endif
59
60 #ifdef HAS_SELECT
61 # ifdef I_SYS_SELECT
62 #  include <sys/select.h>
63 # endif
64 #endif
65
66 /* XXX Configure test needed.
67    h_errno might not be a simple 'int', especially for multi-threaded
68    applications, see "extern int errno in perl.h".  Creating such
69    a test requires taking into account the differences between
70    compiling multithreaded and singlethreaded ($ccflags et al).
71    HOST_NOT_FOUND is typically defined in <netdb.h>.
72 */
73 #if defined(HOST_NOT_FOUND) && !defined(h_errno) && !defined(__CYGWIN__)
74 extern int h_errno;
75 #endif
76
77 #ifdef HAS_PASSWD
78 # ifdef I_PWD
79 #  include <pwd.h>
80 # else
81 #  if !defined(VMS)
82     struct passwd *getpwnam (char *);
83     struct passwd *getpwuid (Uid_t);
84 #  endif
85 # endif
86 # ifdef HAS_GETPWENT
87 #ifndef getpwent
88   struct passwd *getpwent (void);
89 #elif defined (VMS) && defined (my_getpwent)
90   struct passwd *Perl_my_getpwent (void);
91 #endif
92 # endif
93 #endif
94
95 #ifdef HAS_GROUP
96 # ifdef I_GRP
97 #  include <grp.h>
98 # else
99     struct group *getgrnam (char *);
100     struct group *getgrgid (Gid_t);
101 # endif
102 # ifdef HAS_GETGRENT
103 #ifndef getgrent
104     struct group *getgrent (void);
105 #endif
106 # endif
107 #endif
108
109 #ifdef I_UTIME
110 #  if defined(_MSC_VER) || defined(__MINGW32__)
111 #    include <sys/utime.h>
112 #  else
113 #    include <utime.h>
114 #  endif
115 #endif
116
117 #ifdef HAS_CHSIZE
118 # ifdef my_chsize  /* Probably #defined to Perl_my_chsize in embed.h */
119 #   undef my_chsize
120 # endif
121 # define my_chsize PerlLIO_chsize
122 #else
123 # ifdef HAS_TRUNCATE
124 #   define my_chsize PerlLIO_chsize
125 # else
126 I32 my_chsize(int fd, Off_t length);
127 # endif
128 #endif
129
130 #ifdef HAS_FLOCK
131 #  define FLOCK flock
132 #else /* no flock() */
133
134    /* fcntl.h might not have been included, even if it exists, because
135       the current Configure only sets I_FCNTL if it's needed to pick up
136       the *_OK constants.  Make sure it has been included before testing
137       the fcntl() locking constants. */
138 #  if defined(HAS_FCNTL) && !defined(I_FCNTL)
139 #    include <fcntl.h>
140 #  endif
141
142 #  if defined(HAS_FCNTL) && defined(FCNTL_CAN_LOCK)
143 #    define FLOCK fcntl_emulate_flock
144 #    define FCNTL_EMULATE_FLOCK
145 #  else /* no flock() or fcntl(F_SETLK,...) */
146 #    ifdef HAS_LOCKF
147 #      define FLOCK lockf_emulate_flock
148 #      define LOCKF_EMULATE_FLOCK
149 #    endif /* lockf */
150 #  endif /* no flock() or fcntl(F_SETLK,...) */
151
152 #  ifdef FLOCK
153      static int FLOCK (int, int);
154
155     /*
156      * These are the flock() constants.  Since this sytems doesn't have
157      * flock(), the values of the constants are probably not available.
158      */
159 #    ifndef LOCK_SH
160 #      define LOCK_SH 1
161 #    endif
162 #    ifndef LOCK_EX
163 #      define LOCK_EX 2
164 #    endif
165 #    ifndef LOCK_NB
166 #      define LOCK_NB 4
167 #    endif
168 #    ifndef LOCK_UN
169 #      define LOCK_UN 8
170 #    endif
171 #  endif /* emulating flock() */
172
173 #endif /* no flock() */
174
175 #define ZBTLEN 10
176 static const char zero_but_true[ZBTLEN + 1] = "0 but true";
177
178 #if defined(I_SYS_ACCESS) && !defined(R_OK)
179 #  include <sys/access.h>
180 #endif
181
182 #if defined(HAS_FCNTL) && defined(F_SETFD) && !defined(FD_CLOEXEC)
183 #  define FD_CLOEXEC 1          /* NeXT needs this */
184 #endif
185
186 #include "reentr.h"
187
188 #ifdef __Lynx__
189 /* Missing protos on LynxOS */
190 void sethostent(int);
191 void endhostent(void);
192 void setnetent(int);
193 void endnetent(void);
194 void setprotoent(int);
195 void endprotoent(void);
196 void setservent(int);
197 void endservent(void);
198 #endif
199
200 #undef PERL_EFF_ACCESS_R_OK     /* EFFective uid/gid ACCESS R_OK */
201 #undef PERL_EFF_ACCESS_W_OK
202 #undef PERL_EFF_ACCESS_X_OK
203
204 /* F_OK unused: if stat() cannot find it... */
205
206 #if !defined(PERL_EFF_ACCESS_R_OK) && defined(HAS_ACCESS) && defined(EFF_ONLY_OK) && !defined(NO_EFF_ONLY_OK)
207     /* Digital UNIX (when the EFF_ONLY_OK gets fixed), UnixWare */
208 #   define PERL_EFF_ACCESS_R_OK(p) (access((p), R_OK | EFF_ONLY_OK))
209 #   define PERL_EFF_ACCESS_W_OK(p) (access((p), W_OK | EFF_ONLY_OK))
210 #   define PERL_EFF_ACCESS_X_OK(p) (access((p), X_OK | EFF_ONLY_OK))
211 #endif
212
213 #if !defined(PERL_EFF_ACCESS_R_OK) && defined(HAS_EACCESS)
214 #   ifdef I_SYS_SECURITY
215 #       include <sys/security.h>
216 #   endif
217 #   ifdef ACC_SELF
218         /* HP SecureWare */
219 #       define PERL_EFF_ACCESS_R_OK(p) (eaccess((p), R_OK, ACC_SELF))
220 #       define PERL_EFF_ACCESS_W_OK(p) (eaccess((p), W_OK, ACC_SELF))
221 #       define PERL_EFF_ACCESS_X_OK(p) (eaccess((p), X_OK, ACC_SELF))
222 #   else
223         /* SCO */
224 #       define PERL_EFF_ACCESS_R_OK(p) (eaccess((p), R_OK))
225 #       define PERL_EFF_ACCESS_W_OK(p) (eaccess((p), W_OK))
226 #       define PERL_EFF_ACCESS_X_OK(p) (eaccess((p), X_OK))
227 #   endif
228 #endif
229
230 #if !defined(PERL_EFF_ACCESS_R_OK) && defined(HAS_ACCESSX) && defined(ACC_SELF)
231     /* AIX */
232 #   define PERL_EFF_ACCESS_R_OK(p) (accessx((p), R_OK, ACC_SELF))
233 #   define PERL_EFF_ACCESS_W_OK(p) (accessx((p), W_OK, ACC_SELF))
234 #   define PERL_EFF_ACCESS_X_OK(p) (accessx((p), X_OK, ACC_SELF))
235 #endif
236
237 #if !defined(PERL_EFF_ACCESS_R_OK) && defined(HAS_ACCESS)       \
238     && (defined(HAS_SETREUID) || defined(HAS_SETRESUID)         \
239         || defined(HAS_SETREGID) || defined(HAS_SETRESGID))
240 /* The Hard Way. */
241 STATIC int
242 S_emulate_eaccess(pTHX_ const char* path, Mode_t mode)
243 {
244     Uid_t ruid = getuid();
245     Uid_t euid = geteuid();
246     Gid_t rgid = getgid();
247     Gid_t egid = getegid();
248     int res;
249
250     LOCK_CRED_MUTEX;
251 #if !defined(HAS_SETREUID) && !defined(HAS_SETRESUID)
252     Perl_croak(aTHX_ "switching effective uid is not implemented");
253 #else
254 #ifdef HAS_SETREUID
255     if (setreuid(euid, ruid))
256 #else
257 #ifdef HAS_SETRESUID
258     if (setresuid(euid, ruid, (Uid_t)-1))
259 #endif
260 #endif
261         Perl_croak(aTHX_ "entering effective uid failed");
262 #endif
263
264 #if !defined(HAS_SETREGID) && !defined(HAS_SETRESGID)
265     Perl_croak(aTHX_ "switching effective gid is not implemented");
266 #else
267 #ifdef HAS_SETREGID
268     if (setregid(egid, rgid))
269 #else
270 #ifdef HAS_SETRESGID
271     if (setresgid(egid, rgid, (Gid_t)-1))
272 #endif
273 #endif
274         Perl_croak(aTHX_ "entering effective gid failed");
275 #endif
276
277     res = access(path, mode);
278
279 #ifdef HAS_SETREUID
280     if (setreuid(ruid, euid))
281 #else
282 #ifdef HAS_SETRESUID
283     if (setresuid(ruid, euid, (Uid_t)-1))
284 #endif
285 #endif
286         Perl_croak(aTHX_ "leaving effective uid failed");
287
288 #ifdef HAS_SETREGID
289     if (setregid(rgid, egid))
290 #else
291 #ifdef HAS_SETRESGID
292     if (setresgid(rgid, egid, (Gid_t)-1))
293 #endif
294 #endif
295         Perl_croak(aTHX_ "leaving effective gid failed");
296     UNLOCK_CRED_MUTEX;
297
298     return res;
299 }
300 #   define PERL_EFF_ACCESS_R_OK(p) (emulate_eaccess((p), R_OK))
301 #   define PERL_EFF_ACCESS_W_OK(p) (emulate_eaccess((p), W_OK))
302 #   define PERL_EFF_ACCESS_X_OK(p) (emulate_eaccess((p), X_OK))
303 #endif
304
305 #if !defined(PERL_EFF_ACCESS_R_OK)
306 /* With it or without it: anyway you get a warning: either that
307    it is unused, or it is declared static and never defined.
308  */
309 STATIC int
310 S_emulate_eaccess(pTHX_ const char* path, Mode_t mode)
311 {
312     (void)path;
313     (void)mode;
314     Perl_croak(aTHX_ "switching effective uid is not implemented");
315     /*NOTREACHED*/
316     return -1;
317 }
318 #endif
319
320 PP(pp_backtick)
321 {
322     dSP; dTARGET;
323     PerlIO *fp;
324     const char * const tmps = POPpconstx;
325     const I32 gimme = GIMME_V;
326     const char *mode = "r";
327
328     TAINT_PROPER("``");
329     if (PL_op->op_private & OPpOPEN_IN_RAW)
330         mode = "rb";
331     else if (PL_op->op_private & OPpOPEN_IN_CRLF)
332         mode = "rt";
333     fp = PerlProc_popen((char*)tmps, (char *)mode);
334     if (fp) {
335         const char *type = NULL;
336         if (PL_curcop->cop_io) {
337             type = SvPV_nolen_const(PL_curcop->cop_io);
338         }
339         if (type && *type)
340             PerlIO_apply_layers(aTHX_ fp,mode,type);
341
342         if (gimme == G_VOID) {
343             char tmpbuf[256];
344             while (PerlIO_read(fp, tmpbuf, sizeof tmpbuf) > 0)
345                 ;
346         }
347         else if (gimme == G_SCALAR) {
348             ENTER;
349             SAVESPTR(PL_rs);
350             PL_rs = &PL_sv_undef;
351             sv_setpvn(TARG, "", 0);     /* note that this preserves previous buffer */
352             while (sv_gets(TARG, fp, SvCUR(TARG)) != Nullch)
353                 ;
354             LEAVE;
355             XPUSHs(TARG);
356             SvTAINTED_on(TARG);
357         }
358         else {
359             for (;;) {
360                 SV * const sv = NEWSV(56, 79);
361                 if (sv_gets(sv, fp, 0) == Nullch) {
362                     SvREFCNT_dec(sv);
363                     break;
364                 }
365                 XPUSHs(sv_2mortal(sv));
366                 if (SvLEN(sv) - SvCUR(sv) > 20) {
367                     SvPV_shrink_to_cur(sv);
368                 }
369                 SvTAINTED_on(sv);
370             }
371         }
372         STATUS_NATIVE_SET(PerlProc_pclose(fp));
373         TAINT;          /* "I believe that this is not gratuitous!" */
374     }
375     else {
376         STATUS_NATIVE_SET(-1);
377         if (gimme == G_SCALAR)
378             RETPUSHUNDEF;
379     }
380
381     RETURN;
382 }
383
384 PP(pp_glob)
385 {
386     dVAR;
387     OP *result;
388     tryAMAGICunTARGET(iter, -1);
389
390     /* Note that we only ever get here if File::Glob fails to load
391      * without at the same time croaking, for some reason, or if
392      * perl was built with PERL_EXTERNAL_GLOB */
393
394     ENTER;
395
396 #ifndef VMS
397     if (PL_tainting) {
398         /*
399          * The external globbing program may use things we can't control,
400          * so for security reasons we must assume the worst.
401          */
402         TAINT;
403         taint_proper(PL_no_security, "glob");
404     }
405 #endif /* !VMS */
406
407     SAVESPTR(PL_last_in_gv);    /* We don't want this to be permanent. */
408     PL_last_in_gv = (GV*)*PL_stack_sp--;
409
410     SAVESPTR(PL_rs);            /* This is not permanent, either. */
411     PL_rs = sv_2mortal(newSVpvn("\000", 1));
412 #ifndef DOSISH
413 #ifndef CSH
414     *SvPVX(PL_rs) = '\n';
415 #endif  /* !CSH */
416 #endif  /* !DOSISH */
417
418     result = do_readline();
419     LEAVE;
420     return result;
421 }
422
423 PP(pp_rcatline)
424 {
425     PL_last_in_gv = cGVOP_gv;
426     return do_readline();
427 }
428
429 PP(pp_warn)
430 {
431     dSP; dMARK;
432     SV *tmpsv;
433     const char *tmps;
434     STRLEN len;
435     if (SP - MARK != 1) {
436         dTARGET;
437         do_join(TARG, &PL_sv_no, MARK, SP);
438         tmpsv = TARG;
439         SP = MARK + 1;
440     }
441     else {
442         tmpsv = TOPs;
443     }
444     tmps = SvPV_const(tmpsv, len);
445     if ((!tmps || !len) && PL_errgv) {
446         SV * const error = ERRSV;
447         SvUPGRADE(error, SVt_PV);
448         if (SvPOK(error) && SvCUR(error))
449             sv_catpv(error, "\t...caught");
450         tmpsv = error;
451         tmps = SvPV_const(tmpsv, len);
452     }
453     if (!tmps || !len)
454         tmpsv = sv_2mortal(newSVpvn("Warning: something's wrong", 26));
455
456     Perl_warn(aTHX_ "%"SVf, tmpsv);
457     RETSETYES;
458 }
459
460 PP(pp_die)
461 {
462     dSP; dMARK;
463     const char *tmps;
464     SV *tmpsv;
465     STRLEN len;
466     bool multiarg = 0;
467 #ifdef VMS
468     VMSISH_HUSHED  = VMSISH_HUSHED || (PL_op->op_private & OPpHUSH_VMSISH);
469 #endif
470     if (SP - MARK != 1) {
471         dTARGET;
472         do_join(TARG, &PL_sv_no, MARK, SP);
473         tmpsv = TARG;
474         tmps = SvPV_const(tmpsv, len);
475         multiarg = 1;
476         SP = MARK + 1;
477     }
478     else {
479         tmpsv = TOPs;
480         tmps = SvROK(tmpsv) ? Nullch : SvPV_const(tmpsv, len);
481     }
482     if (!tmps || !len) {
483         SV *error = ERRSV;
484         SvUPGRADE(error, SVt_PV);
485         if (multiarg ? SvROK(error) : SvROK(tmpsv)) {
486             if (!multiarg)
487                 SvSetSV(error,tmpsv);
488             else if (sv_isobject(error)) {
489                 HV *stash = SvSTASH(SvRV(error));
490                 GV *gv = gv_fetchmethod(stash, "PROPAGATE");
491                 if (gv) {
492                     SV *file = sv_2mortal(newSVpv(CopFILE(PL_curcop),0));
493                     SV *line = sv_2mortal(newSVuv(CopLINE(PL_curcop)));
494                     EXTEND(SP, 3);
495                     PUSHMARK(SP);
496                     PUSHs(error);
497                     PUSHs(file);
498                     PUSHs(line);
499                     PUTBACK;
500                     call_sv((SV*)GvCV(gv),
501                             G_SCALAR|G_EVAL|G_KEEPERR);
502                     sv_setsv(error,*PL_stack_sp--);
503                 }
504             }
505             DIE_NULL;
506         }
507         else {
508             if (SvPOK(error) && SvCUR(error))
509                 sv_catpv(error, "\t...propagated");
510             tmpsv = error;
511             tmps = SvPV_const(tmpsv, len);
512         }
513     }
514     if (!tmps || !len)
515         tmpsv = sv_2mortal(newSVpvn("Died", 4));
516
517     DIE(aTHX_ "%"SVf, tmpsv);
518 }
519
520 /* I/O. */
521
522 PP(pp_open)
523 {
524     dVAR; dSP;
525     dMARK; dORIGMARK;
526     dTARGET;
527     GV *gv;
528     SV *sv;
529     IO *io;
530     const char *tmps;
531     STRLEN len;
532     MAGIC *mg;
533     bool  ok;
534
535     gv = (GV *)*++MARK;
536     if (!isGV(gv))
537         DIE(aTHX_ PL_no_usym, "filehandle");
538     if ((io = GvIOp(gv)))
539         IoFLAGS(GvIOp(gv)) &= ~IOf_UNTAINT;
540
541     if (io && (mg = SvTIED_mg((SV*)io, PERL_MAGIC_tiedscalar))) {
542         /* Method's args are same as ours ... */
543         /* ... except handle is replaced by the object */
544         *MARK-- = SvTIED_obj((SV*)io, mg);
545         PUSHMARK(MARK);
546         PUTBACK;
547         ENTER;
548         call_method("OPEN", G_SCALAR);
549         LEAVE;
550         SPAGAIN;
551         RETURN;
552     }
553
554     if (MARK < SP) {
555         sv = *++MARK;
556     }
557     else {
558         sv = GvSV(gv);
559     }
560
561     tmps = SvPV_const(sv, len);
562     ok = do_openn(gv, (char *)tmps, len, FALSE, O_RDONLY, 0, Nullfp, MARK+1, (SP-MARK));
563     SP = ORIGMARK;
564     if (ok)
565         PUSHi( (I32)PL_forkprocess );
566     else if (PL_forkprocess == 0)               /* we are a new child */
567         PUSHi(0);
568     else
569         RETPUSHUNDEF;
570     RETURN;
571 }
572
573 PP(pp_close)
574 {
575     dVAR; dSP;
576     GV *gv;
577     IO *io;
578     MAGIC *mg;
579
580     if (MAXARG == 0)
581         gv = PL_defoutgv;
582     else
583         gv = (GV*)POPs;
584
585     if (gv && (io = GvIO(gv))
586         && (mg = SvTIED_mg((SV*)io, PERL_MAGIC_tiedscalar)))
587     {
588         PUSHMARK(SP);
589         XPUSHs(SvTIED_obj((SV*)io, mg));
590         PUTBACK;
591         ENTER;
592         call_method("CLOSE", G_SCALAR);
593         LEAVE;
594         SPAGAIN;
595         RETURN;
596     }
597     EXTEND(SP, 1);
598     PUSHs(boolSV(do_close(gv, TRUE)));
599     RETURN;
600 }
601
602 PP(pp_pipe_op)
603 {
604 #ifdef HAS_PIPE
605     dSP;
606     GV *rgv;
607     GV *wgv;
608     register IO *rstio;
609     register IO *wstio;
610     int fd[2];
611
612     wgv = (GV*)POPs;
613     rgv = (GV*)POPs;
614
615     if (!rgv || !wgv)
616         goto badexit;
617
618     if (SvTYPE(rgv) != SVt_PVGV || SvTYPE(wgv) != SVt_PVGV)
619         DIE(aTHX_ PL_no_usym, "filehandle");
620     rstio = GvIOn(rgv);
621     wstio = GvIOn(wgv);
622
623     if (IoIFP(rstio))
624         do_close(rgv, FALSE);
625     if (IoIFP(wstio))
626         do_close(wgv, FALSE);
627
628     if (PerlProc_pipe(fd) < 0)
629         goto badexit;
630
631     IoIFP(rstio) = PerlIO_fdopen(fd[0], "r"PIPE_OPEN_MODE);
632     IoOFP(wstio) = PerlIO_fdopen(fd[1], "w"PIPE_OPEN_MODE);
633     IoOFP(rstio) = IoIFP(rstio);
634     IoIFP(wstio) = IoOFP(wstio);
635     IoTYPE(rstio) = IoTYPE_RDONLY;
636     IoTYPE(wstio) = IoTYPE_WRONLY;
637
638     if (!IoIFP(rstio) || !IoOFP(wstio)) {
639         if (IoIFP(rstio)) PerlIO_close(IoIFP(rstio));
640         else PerlLIO_close(fd[0]);
641         if (IoOFP(wstio)) PerlIO_close(IoOFP(wstio));
642         else PerlLIO_close(fd[1]);
643         goto badexit;
644     }
645 #if defined(HAS_FCNTL) && defined(F_SETFD)
646     fcntl(fd[0],F_SETFD,fd[0] > PL_maxsysfd);   /* ensure close-on-exec */
647     fcntl(fd[1],F_SETFD,fd[1] > PL_maxsysfd);   /* ensure close-on-exec */
648 #endif
649     RETPUSHYES;
650
651 badexit:
652     RETPUSHUNDEF;
653 #else
654     DIE(aTHX_ PL_no_func, "pipe");
655 #endif
656 }
657
658 PP(pp_fileno)
659 {
660     dVAR; dSP; dTARGET;
661     GV *gv;
662     IO *io;
663     PerlIO *fp;
664     MAGIC  *mg;
665
666     if (MAXARG < 1)
667         RETPUSHUNDEF;
668     gv = (GV*)POPs;
669
670     if (gv && (io = GvIO(gv))
671         && (mg = SvTIED_mg((SV*)io, PERL_MAGIC_tiedscalar)))
672     {
673         PUSHMARK(SP);
674         XPUSHs(SvTIED_obj((SV*)io, mg));
675         PUTBACK;
676         ENTER;
677         call_method("FILENO", G_SCALAR);
678         LEAVE;
679         SPAGAIN;
680         RETURN;
681     }
682
683     if (!gv || !(io = GvIO(gv)) || !(fp = IoIFP(io))) {
684         /* Can't do this because people seem to do things like
685            defined(fileno($foo)) to check whether $foo is a valid fh.
686           if (ckWARN2(WARN_UNOPENED,WARN_CLOSED))
687               report_evil_fh(gv, io, PL_op->op_type);
688             */
689         RETPUSHUNDEF;
690     }
691
692     PUSHi(PerlIO_fileno(fp));
693     RETURN;
694 }
695
696 PP(pp_umask)
697 {
698     dSP;
699 #ifdef HAS_UMASK
700     dTARGET;
701     Mode_t anum;
702
703     if (MAXARG < 1) {
704         anum = PerlLIO_umask(0);
705         (void)PerlLIO_umask(anum);
706     }
707     else
708         anum = PerlLIO_umask(POPi);
709     TAINT_PROPER("umask");
710     XPUSHi(anum);
711 #else
712     /* Only DIE if trying to restrict permissions on "user" (self).
713      * Otherwise it's harmless and more useful to just return undef
714      * since 'group' and 'other' concepts probably don't exist here. */
715     if (MAXARG >= 1 && (POPi & 0700))
716         DIE(aTHX_ "umask not implemented");
717     XPUSHs(&PL_sv_undef);
718 #endif
719     RETURN;
720 }
721
722 PP(pp_binmode)
723 {
724     dVAR; dSP;
725     GV *gv;
726     IO *io;
727     PerlIO *fp;
728     MAGIC *mg;
729     SV *discp = Nullsv;
730
731     if (MAXARG < 1)
732         RETPUSHUNDEF;
733     if (MAXARG > 1) {
734         discp = POPs;
735     }
736
737     gv = (GV*)POPs;
738
739     if (gv && (io = GvIO(gv))
740         && (mg = SvTIED_mg((SV*)io, PERL_MAGIC_tiedscalar)))
741     {
742         PUSHMARK(SP);
743         XPUSHs(SvTIED_obj((SV*)io, mg));
744         if (discp)
745             XPUSHs(discp);
746         PUTBACK;
747         ENTER;
748         call_method("BINMODE", G_SCALAR);
749         LEAVE;
750         SPAGAIN;
751         RETURN;
752     }
753
754     EXTEND(SP, 1);
755     if (!(io = GvIO(gv)) || !(fp = IoIFP(io))) {
756         if (ckWARN2(WARN_UNOPENED,WARN_CLOSED))
757             report_evil_fh(gv, io, PL_op->op_type);
758         SETERRNO(EBADF,RMS_IFI);
759         RETPUSHUNDEF;
760     }
761
762     PUTBACK;
763     if (PerlIO_binmode(aTHX_ fp,IoTYPE(io),mode_from_discipline(discp),
764                        (discp) ? SvPV_nolen_const(discp) : Nullch)) {
765         if (IoOFP(io) && IoOFP(io) != IoIFP(io)) {
766              if (!PerlIO_binmode(aTHX_ IoOFP(io),IoTYPE(io),
767                         mode_from_discipline(discp),
768                        (discp) ? SvPV_nolen_const(discp) : Nullch)) {
769                 SPAGAIN;
770                 RETPUSHUNDEF;
771              }
772         }
773         SPAGAIN;
774         RETPUSHYES;
775     }
776     else {
777         SPAGAIN;
778         RETPUSHUNDEF;
779     }
780 }
781
782 PP(pp_tie)
783 {
784     dVAR; dSP; dMARK;
785     SV *varsv;
786     HV* stash;
787     GV *gv;
788     SV *sv;
789     const I32 markoff = MARK - PL_stack_base;
790     const char *methname;
791     int how = PERL_MAGIC_tied;
792     U32 items;
793
794     varsv = *++MARK;
795     switch(SvTYPE(varsv)) {
796         case SVt_PVHV:
797             methname = "TIEHASH";
798             HvEITER_set((HV *)varsv, 0);
799             break;
800         case SVt_PVAV:
801             methname = "TIEARRAY";
802             break;
803         case SVt_PVGV:
804 #ifdef GV_UNIQUE_CHECK
805             if (GvUNIQUE((GV*)varsv)) {
806                 Perl_croak(aTHX_ "Attempt to tie unique GV");
807             }
808 #endif
809             methname = "TIEHANDLE";
810             how = PERL_MAGIC_tiedscalar;
811             /* For tied filehandles, we apply tiedscalar magic to the IO
812                slot of the GP rather than the GV itself. AMS 20010812 */
813             if (!GvIOp(varsv))
814                 GvIOp(varsv) = newIO();
815             varsv = (SV *)GvIOp(varsv);
816             break;
817         default:
818             methname = "TIESCALAR";
819             how = PERL_MAGIC_tiedscalar;
820             break;
821     }
822     items = SP - MARK++;
823     if (sv_isobject(*MARK)) {
824         ENTER;
825         PUSHSTACKi(PERLSI_MAGIC);
826         PUSHMARK(SP);
827         EXTEND(SP,(I32)items);
828         while (items--)
829             PUSHs(*MARK++);
830         PUTBACK;
831         call_method(methname, G_SCALAR);
832     }
833     else {
834         /* Not clear why we don't call call_method here too.
835          * perhaps to get different error message ?
836          */
837         stash = gv_stashsv(*MARK, FALSE);
838         if (!stash || !(gv = gv_fetchmethod(stash, methname))) {
839             DIE(aTHX_ "Can't locate object method \"%s\" via package \"%"SVf"\"",
840                  methname, *MARK);
841         }
842         ENTER;
843         PUSHSTACKi(PERLSI_MAGIC);
844         PUSHMARK(SP);
845         EXTEND(SP,(I32)items);
846         while (items--)
847             PUSHs(*MARK++);
848         PUTBACK;
849         call_sv((SV*)GvCV(gv), G_SCALAR);
850     }
851     SPAGAIN;
852
853     sv = TOPs;
854     POPSTACK;
855     if (sv_isobject(sv)) {
856         sv_unmagic(varsv, how);
857         /* Croak if a self-tie on an aggregate is attempted. */
858         if (varsv == SvRV(sv) &&
859             (SvTYPE(varsv) == SVt_PVAV ||
860              SvTYPE(varsv) == SVt_PVHV))
861             Perl_croak(aTHX_
862                        "Self-ties of arrays and hashes are not supported");
863         sv_magic(varsv, (SvRV(sv) == varsv ? Nullsv : sv), how, Nullch, 0);
864     }
865     LEAVE;
866     SP = PL_stack_base + markoff;
867     PUSHs(sv);
868     RETURN;
869 }
870
871 PP(pp_untie)
872 {
873     dVAR; dSP;
874     MAGIC *mg;
875     SV *sv = POPs;
876     const char how = (SvTYPE(sv) == SVt_PVHV || SvTYPE(sv) == SVt_PVAV)
877                 ? PERL_MAGIC_tied : PERL_MAGIC_tiedscalar;
878
879     if (SvTYPE(sv) == SVt_PVGV && !(sv = (SV *)GvIOp(sv)))
880         RETPUSHYES;
881
882     if ((mg = SvTIED_mg(sv, how))) {
883         SV * const obj = SvRV(SvTIED_obj(sv, mg));
884         GV *gv;
885         CV *cv = NULL;
886         if (obj) {
887             if ((gv = gv_fetchmethod_autoload(SvSTASH(obj), "UNTIE", FALSE)) &&
888                isGV(gv) && (cv = GvCV(gv))) {
889                PUSHMARK(SP);
890                XPUSHs(SvTIED_obj((SV*)gv, mg));
891                XPUSHs(sv_2mortal(newSViv(SvREFCNT(obj)-1)));
892                PUTBACK;
893                ENTER;
894                call_sv((SV *)cv, G_VOID);
895                LEAVE;
896                SPAGAIN;
897             }
898            else if (ckWARN(WARN_UNTIE)) {
899                if (mg && SvREFCNT(obj) > 1)
900                   Perl_warner(aTHX_ packWARN(WARN_UNTIE),
901                       "untie attempted while %"UVuf" inner references still exist",
902                        (UV)SvREFCNT(obj) - 1 ) ;
903            }
904         }
905     }
906     sv_unmagic(sv, how) ;
907     RETPUSHYES;
908 }
909
910 PP(pp_tied)
911 {
912     dSP;
913     const MAGIC *mg;
914     SV *sv = POPs;
915     const char how = (SvTYPE(sv) == SVt_PVHV || SvTYPE(sv) == SVt_PVAV)
916                 ? PERL_MAGIC_tied : PERL_MAGIC_tiedscalar;
917
918     if (SvTYPE(sv) == SVt_PVGV && !(sv = (SV *)GvIOp(sv)))
919         RETPUSHUNDEF;
920
921     if ((mg = SvTIED_mg(sv, how))) {
922         SV *osv = SvTIED_obj(sv, mg);
923         if (osv == mg->mg_obj)
924             osv = sv_mortalcopy(osv);
925         PUSHs(osv);
926         RETURN;
927     }
928     RETPUSHUNDEF;
929 }
930
931 PP(pp_dbmopen)
932 {
933     dVAR; dSP;
934     dPOPPOPssrl;
935     HV* stash;
936     GV *gv;
937     SV *sv;
938
939     HV * const hv = (HV*)POPs;
940
941     sv = sv_mortalcopy(&PL_sv_no);
942     sv_setpv(sv, "AnyDBM_File");
943     stash = gv_stashsv(sv, FALSE);
944     if (!stash || !(gv = gv_fetchmethod(stash, "TIEHASH"))) {
945         PUTBACK;
946         require_pv("AnyDBM_File.pm");
947         SPAGAIN;
948         if (!(gv = gv_fetchmethod(stash, "TIEHASH")))
949             DIE(aTHX_ "No dbm on this machine");
950     }
951
952     ENTER;
953     PUSHMARK(SP);
954
955     EXTEND(SP, 5);
956     PUSHs(sv);
957     PUSHs(left);
958     if (SvIV(right))
959         PUSHs(sv_2mortal(newSVuv(O_RDWR|O_CREAT)));
960     else
961         PUSHs(sv_2mortal(newSVuv(O_RDWR)));
962     PUSHs(right);
963     PUTBACK;
964     call_sv((SV*)GvCV(gv), G_SCALAR);
965     SPAGAIN;
966
967     if (!sv_isobject(TOPs)) {
968         SP--;
969         PUSHMARK(SP);
970         PUSHs(sv);
971         PUSHs(left);
972         PUSHs(sv_2mortal(newSVuv(O_RDONLY)));
973         PUSHs(right);
974         PUTBACK;
975         call_sv((SV*)GvCV(gv), G_SCALAR);
976         SPAGAIN;
977     }
978
979     if (sv_isobject(TOPs)) {
980         sv_unmagic((SV *) hv, PERL_MAGIC_tied);
981         sv_magic((SV*)hv, TOPs, PERL_MAGIC_tied, Nullch, 0);
982     }
983     LEAVE;
984     RETURN;
985 }
986
987 PP(pp_dbmclose)
988 {
989     return pp_untie();
990 }
991
992 PP(pp_sselect)
993 {
994 #ifdef HAS_SELECT
995     dSP; dTARGET;
996     register I32 i;
997     register I32 j;
998     register char *s;
999     register SV *sv;
1000     NV value;
1001     I32 maxlen = 0;
1002     I32 nfound;
1003     struct timeval timebuf;
1004     struct timeval *tbuf = &timebuf;
1005     I32 growsize;
1006     char *fd_sets[4];
1007 #if BYTEORDER != 0x1234 && BYTEORDER != 0x12345678
1008         I32 masksize;
1009         I32 offset;
1010         I32 k;
1011
1012 #   if BYTEORDER & 0xf0000
1013 #       define ORDERBYTE (0x88888888 - BYTEORDER)
1014 #   else
1015 #       define ORDERBYTE (0x4444 - BYTEORDER)
1016 #   endif
1017
1018 #endif
1019
1020     SP -= 4;
1021     for (i = 1; i <= 3; i++) {
1022         SV *sv = SP[i];
1023         if (SvOK(sv) && SvREADONLY(sv)) {
1024             if (SvIsCOW(sv))
1025                 sv_force_normal_flags(sv, 0);
1026             if (SvREADONLY(sv))
1027                 DIE(aTHX_ PL_no_modify);
1028         }
1029         if (!SvPOK(sv))
1030             continue;
1031         j = SvCUR(sv);
1032         if (maxlen < j)
1033             maxlen = j;
1034     }
1035
1036 /* little endians can use vecs directly */
1037 #if BYTEORDER != 0x1234 && BYTEORDER != 0x12345678
1038 #  ifdef NFDBITS
1039
1040 #    ifndef NBBY
1041 #     define NBBY 8
1042 #    endif
1043
1044     masksize = NFDBITS / NBBY;
1045 #  else
1046     masksize = sizeof(long);    /* documented int, everyone seems to use long */
1047 #  endif
1048     Zero(&fd_sets[0], 4, char*);
1049 #endif
1050
1051 #  if SELECT_MIN_BITS == 1
1052     growsize = sizeof(fd_set);
1053 #  else
1054 #   if defined(__GLIBC__) && defined(__FD_SETSIZE)
1055 #      undef SELECT_MIN_BITS
1056 #      define SELECT_MIN_BITS __FD_SETSIZE
1057 #   endif
1058     /* If SELECT_MIN_BITS is greater than one we most probably will want
1059      * to align the sizes with SELECT_MIN_BITS/8 because for example
1060      * in many little-endian (Intel, Alpha) systems (Linux, OS/2, Digital
1061      * UNIX, Solaris, NeXT, Darwin) the smallest quantum select() operates
1062      * on (sets/tests/clears bits) is 32 bits.  */
1063     growsize = maxlen + (SELECT_MIN_BITS/8 - (maxlen % (SELECT_MIN_BITS/8)));
1064 #  endif
1065
1066     sv = SP[4];
1067     if (SvOK(sv)) {
1068         value = SvNV(sv);
1069         if (value < 0.0)
1070             value = 0.0;
1071         timebuf.tv_sec = (long)value;
1072         value -= (NV)timebuf.tv_sec;
1073         timebuf.tv_usec = (long)(value * 1000000.0);
1074     }
1075     else
1076         tbuf = Null(struct timeval*);
1077
1078     for (i = 1; i <= 3; i++) {
1079         sv = SP[i];
1080         if (!SvOK(sv)) {
1081             fd_sets[i] = 0;
1082             continue;
1083         }
1084         else if (!SvPOK(sv))
1085             SvPV_force_nolen(sv);       /* force string conversion */
1086         j = SvLEN(sv);
1087         if (j < growsize) {
1088             Sv_Grow(sv, growsize);
1089         }
1090         j = SvCUR(sv);
1091         s = SvPVX(sv) + j;
1092         while (++j <= growsize) {
1093             *s++ = '\0';
1094         }
1095
1096 #if BYTEORDER != 0x1234 && BYTEORDER != 0x12345678
1097         s = SvPVX(sv);
1098         New(403, fd_sets[i], growsize, char);
1099         for (offset = 0; offset < growsize; offset += masksize) {
1100             for (j = 0, k=ORDERBYTE; j < masksize; j++, (k >>= 4))
1101                 fd_sets[i][j+offset] = s[(k % masksize) + offset];
1102         }
1103 #else
1104         fd_sets[i] = SvPVX(sv);
1105 #endif
1106     }
1107
1108 #ifdef PERL_IRIX5_SELECT_TIMEVAL_VOID_CAST
1109     /* Can't make just the (void*) conditional because that would be
1110      * cpp #if within cpp macro, and not all compilers like that. */
1111     nfound = PerlSock_select(
1112         maxlen * 8,
1113         (Select_fd_set_t) fd_sets[1],
1114         (Select_fd_set_t) fd_sets[2],
1115         (Select_fd_set_t) fd_sets[3],
1116         (void*) tbuf); /* Workaround for compiler bug. */
1117 #else
1118     nfound = PerlSock_select(
1119         maxlen * 8,
1120         (Select_fd_set_t) fd_sets[1],
1121         (Select_fd_set_t) fd_sets[2],
1122         (Select_fd_set_t) fd_sets[3],
1123         tbuf);
1124 #endif
1125     for (i = 1; i <= 3; i++) {
1126         if (fd_sets[i]) {
1127             sv = SP[i];
1128 #if BYTEORDER != 0x1234 && BYTEORDER != 0x12345678
1129             s = SvPVX(sv);
1130             for (offset = 0; offset < growsize; offset += masksize) {
1131                 for (j = 0, k=ORDERBYTE; j < masksize; j++, (k >>= 4))
1132                     s[(k % masksize) + offset] = fd_sets[i][j+offset];
1133             }
1134             Safefree(fd_sets[i]);
1135 #endif
1136             SvSETMAGIC(sv);
1137         }
1138     }
1139
1140     if (nfound == -1)
1141         PUSHs(&PL_sv_undef);
1142     else
1143         PUSHi(nfound);
1144     if (GIMME == G_ARRAY && tbuf) {
1145         value = (NV)(timebuf.tv_sec) +
1146                 (NV)(timebuf.tv_usec) / 1000000.0;
1147         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
1148         sv_setnv(sv, value);
1149     }
1150     RETURN;
1151 #else
1152     DIE(aTHX_ "select not implemented");
1153 #endif
1154 }
1155
1156 void
1157 Perl_setdefout(pTHX_ GV *gv)
1158 {
1159     if (gv)
1160         (void)SvREFCNT_inc(gv);
1161     if (PL_defoutgv)
1162         SvREFCNT_dec(PL_defoutgv);
1163     PL_defoutgv = gv;
1164 }
1165
1166 PP(pp_select)
1167 {
1168     dSP; dTARGET;
1169     GV *egv;
1170     HV *hv;
1171
1172     GV * const newdefout = (PL_op->op_private > 0) ? ((GV *) POPs) : (GV *) NULL;
1173
1174     egv = GvEGV(PL_defoutgv);
1175     if (!egv)
1176         egv = PL_defoutgv;
1177     hv = GvSTASH(egv);
1178     if (! hv)
1179         XPUSHs(&PL_sv_undef);
1180     else {
1181         GV ** const gvp = (GV**)hv_fetch(hv, GvNAME(egv), GvNAMELEN(egv), FALSE);
1182         if (gvp && *gvp == egv) {
1183             gv_efullname4(TARG, PL_defoutgv, Nullch, TRUE);
1184             XPUSHTARG;
1185         }
1186         else {
1187             XPUSHs(sv_2mortal(newRV((SV*)egv)));
1188         }
1189     }
1190
1191     if (newdefout) {
1192         if (!GvIO(newdefout))
1193             gv_IOadd(newdefout);
1194         setdefout(newdefout);
1195     }
1196
1197     RETURN;
1198 }
1199
1200 PP(pp_getc)
1201 {
1202     dVAR; dSP; dTARGET;
1203     IO *io = NULL;
1204     MAGIC *mg;
1205     GV * const gv = (MAXARG==0) ? PL_stdingv : (GV*)POPs;
1206
1207     if (gv && (io = GvIO(gv))
1208         && (mg = SvTIED_mg((SV*)io, PERL_MAGIC_tiedscalar)))
1209     {
1210         const I32 gimme = GIMME_V;
1211         PUSHMARK(SP);
1212         XPUSHs(SvTIED_obj((SV*)io, mg));
1213         PUTBACK;
1214         ENTER;
1215         call_method("GETC", gimme);
1216         LEAVE;
1217         SPAGAIN;
1218         if (gimme == G_SCALAR)
1219             SvSetMagicSV_nosteal(TARG, TOPs);
1220         RETURN;
1221     }
1222     if (!gv || do_eof(gv)) { /* make sure we have fp with something */
1223         if (ckWARN2(WARN_UNOPENED,WARN_CLOSED)
1224                 && (!io || (!IoIFP(io) && IoTYPE(io) != IoTYPE_WRONLY)))
1225             report_evil_fh(gv, io, PL_op->op_type);
1226         SETERRNO(EBADF,RMS_IFI);
1227         RETPUSHUNDEF;
1228     }
1229     TAINT;
1230     sv_setpvn(TARG, " ", 1);
1231     *SvPVX(TARG) = PerlIO_getc(IoIFP(GvIOp(gv))); /* should never be EOF */
1232     if (PerlIO_isutf8(IoIFP(GvIOp(gv)))) {
1233         /* Find out how many bytes the char needs */
1234         Size_t len = UTF8SKIP(SvPVX_const(TARG));
1235         if (len > 1) {
1236             SvGROW(TARG,len+1);
1237             len = PerlIO_read(IoIFP(GvIOp(gv)),SvPVX(TARG)+1,len-1);
1238             SvCUR_set(TARG,1+len);
1239         }
1240         SvUTF8_on(TARG);
1241     }
1242     PUSHTARG;
1243     RETURN;
1244 }
1245
1246 PP(pp_read)
1247 {
1248     return pp_sysread();
1249 }
1250
1251 STATIC OP *
1252 S_doform(pTHX_ CV *cv, GV *gv, OP *retop)
1253 {
1254     dVAR;
1255     register PERL_CONTEXT *cx;
1256     const I32 gimme = GIMME_V;
1257
1258     ENTER;
1259     SAVETMPS;
1260
1261     PUSHBLOCK(cx, CXt_FORMAT, PL_stack_sp);
1262     PUSHFORMAT(cx);
1263     cx->blk_sub.retop = retop;
1264     PAD_SET_CUR(CvPADLIST(cv), 1);
1265
1266     setdefout(gv);          /* locally select filehandle so $% et al work */
1267     return CvSTART(cv);
1268 }
1269
1270 PP(pp_enterwrite)
1271 {
1272     dSP;
1273     register GV *gv;
1274     register IO *io;
1275     GV *fgv;
1276     CV *cv;
1277
1278     if (MAXARG == 0)
1279         gv = PL_defoutgv;
1280     else {
1281         gv = (GV*)POPs;
1282         if (!gv)
1283             gv = PL_defoutgv;
1284     }
1285     EXTEND(SP, 1);
1286     io = GvIO(gv);
1287     if (!io) {
1288         RETPUSHNO;
1289     }
1290     if (IoFMT_GV(io))
1291         fgv = IoFMT_GV(io);
1292     else
1293         fgv = gv;
1294
1295     cv = GvFORM(fgv);
1296     if (!cv) {
1297         if (fgv) {
1298             SV * const tmpsv = sv_newmortal();
1299             const char *name;
1300             gv_efullname4(tmpsv, fgv, Nullch, FALSE);
1301             name = SvPV_nolen_const(tmpsv);
1302             if (name && *name)
1303                 DIE(aTHX_ "Undefined format \"%s\" called", name);
1304         }
1305         DIE(aTHX_ "Not a format reference");
1306     }
1307     if (CvCLONE(cv))
1308         cv = (CV*)sv_2mortal((SV*)cv_clone(cv));
1309
1310     IoFLAGS(io) &= ~IOf_DIDTOP;
1311     return doform(cv,gv,PL_op->op_next);
1312 }
1313
1314 PP(pp_leavewrite)
1315 {
1316     dVAR; dSP;
1317     GV * const gv = cxstack[cxstack_ix].blk_sub.gv;
1318     register IO * const io = GvIOp(gv);
1319     PerlIO * const ofp = IoOFP(io);
1320     PerlIO *fp;
1321     SV **newsp;
1322     I32 gimme;
1323     register PERL_CONTEXT *cx;
1324     PERL_UNUSED_VAR(newsp);
1325     PERL_UNUSED_VAR(gimme);
1326
1327     DEBUG_f(PerlIO_printf(Perl_debug_log, "left=%ld, todo=%ld\n",
1328           (long)IoLINES_LEFT(io), (long)FmLINES(PL_formtarget)));
1329     if (!io || !ofp)
1330         goto forget_top;
1331     if (IoLINES_LEFT(io) < FmLINES(PL_formtarget) &&
1332         PL_formtarget != PL_toptarget)
1333     {
1334         GV *fgv;
1335         CV *cv;
1336         if (!IoTOP_GV(io)) {
1337             GV *topgv;
1338
1339             if (!IoTOP_NAME(io)) {
1340                 SV *topname;
1341                 if (!IoFMT_NAME(io))
1342                     IoFMT_NAME(io) = savepv(GvNAME(gv));
1343                 topname = sv_2mortal(Perl_newSVpvf(aTHX_ "%s_TOP", GvNAME(gv)));
1344                 topgv = gv_fetchsv(topname, FALSE, SVt_PVFM);
1345                 if ((topgv && GvFORM(topgv)) ||
1346                   !gv_fetchpv("top",FALSE,SVt_PVFM))
1347                     IoTOP_NAME(io) = savesvpv(topname);
1348                 else
1349                     IoTOP_NAME(io) = savepvn("top", 3);
1350             }
1351             topgv = gv_fetchpv(IoTOP_NAME(io),FALSE, SVt_PVFM);
1352             if (!topgv || !GvFORM(topgv)) {
1353                 IoLINES_LEFT(io) = IoPAGE_LEN(io);
1354                 goto forget_top;
1355             }
1356             IoTOP_GV(io) = topgv;
1357         }
1358         if (IoFLAGS(io) & IOf_DIDTOP) { /* Oh dear.  It still doesn't fit. */
1359             I32 lines = IoLINES_LEFT(io);
1360             const char *s = SvPVX_const(PL_formtarget);
1361             if (lines <= 0)             /* Yow, header didn't even fit!!! */
1362                 goto forget_top;
1363             while (lines-- > 0) {
1364                 s = strchr(s, '\n');
1365                 if (!s)
1366                     break;
1367                 s++;
1368             }
1369             if (s) {
1370                 const STRLEN save = SvCUR(PL_formtarget);
1371                 SvCUR_set(PL_formtarget, s - SvPVX_const(PL_formtarget));
1372                 do_print(PL_formtarget, ofp);
1373                 SvCUR_set(PL_formtarget, save);
1374                 sv_chop(PL_formtarget, s);
1375                 FmLINES(PL_formtarget) -= IoLINES_LEFT(io);
1376             }
1377         }
1378         if (IoLINES_LEFT(io) >= 0 && IoPAGE(io) > 0)
1379             do_print(PL_formfeed, ofp);
1380         IoLINES_LEFT(io) = IoPAGE_LEN(io);
1381         IoPAGE(io)++;
1382         PL_formtarget = PL_toptarget;
1383         IoFLAGS(io) |= IOf_DIDTOP;
1384         fgv = IoTOP_GV(io);
1385         if (!fgv)
1386             DIE(aTHX_ "bad top format reference");
1387         cv = GvFORM(fgv);
1388         if (!cv) {
1389             SV * const sv = sv_newmortal();
1390             const char *name;
1391             gv_efullname4(sv, fgv, Nullch, FALSE);
1392             name = SvPV_nolen_const(sv);
1393             if (name && *name)
1394                 DIE(aTHX_ "Undefined top format \"%s\" called",name);
1395         }
1396         /* why no:
1397         else
1398             DIE(aTHX_ "Undefined top format called");
1399         ?*/
1400         if (CvCLONE(cv))
1401             cv = (CV*)sv_2mortal((SV*)cv_clone(cv));
1402         return doform(cv,gv,PL_op);
1403     }
1404
1405   forget_top:
1406     POPBLOCK(cx,PL_curpm);
1407     POPFORMAT(cx);
1408     LEAVE;
1409
1410     fp = IoOFP(io);
1411     if (!fp) {
1412         if (ckWARN2(WARN_CLOSED,WARN_IO)) {
1413             if (IoIFP(io))
1414                 report_evil_fh(gv, io, OP_phoney_INPUT_ONLY);
1415             else if (ckWARN(WARN_CLOSED))
1416                 report_evil_fh(gv, io, PL_op->op_type);
1417         }
1418         PUSHs(&PL_sv_no);
1419     }
1420     else {
1421         if ((IoLINES_LEFT(io) -= FmLINES(PL_formtarget)) < 0) {
1422             if (ckWARN(WARN_IO))
1423                 Perl_warner(aTHX_ packWARN(WARN_IO), "page overflow");
1424         }
1425         if (!do_print(PL_formtarget, fp))
1426             PUSHs(&PL_sv_no);
1427         else {
1428             FmLINES(PL_formtarget) = 0;
1429             SvCUR_set(PL_formtarget, 0);
1430             *SvEND(PL_formtarget) = '\0';
1431             if (IoFLAGS(io) & IOf_FLUSH)
1432                 (void)PerlIO_flush(fp);
1433             PUSHs(&PL_sv_yes);
1434         }
1435     }
1436     /* bad_ofp: */
1437     PL_formtarget = PL_bodytarget;
1438     PUTBACK;
1439     return cx->blk_sub.retop;
1440 }
1441
1442 PP(pp_prtf)
1443 {
1444     dVAR; dSP; dMARK; dORIGMARK;
1445     GV *gv;
1446     IO *io;
1447     PerlIO *fp;
1448     SV *sv;
1449     MAGIC *mg;
1450
1451     if (PL_op->op_flags & OPf_STACKED)
1452         gv = (GV*)*++MARK;
1453     else
1454         gv = PL_defoutgv;
1455
1456     if (gv && (io = GvIO(gv))
1457         && (mg = SvTIED_mg((SV*)io, PERL_MAGIC_tiedscalar)))
1458     {
1459         if (MARK == ORIGMARK) {
1460             MEXTEND(SP, 1);
1461             ++MARK;
1462             Move(MARK, MARK + 1, (SP - MARK) + 1, SV*);
1463             ++SP;
1464         }
1465         PUSHMARK(MARK - 1);
1466         *MARK = SvTIED_obj((SV*)io, mg);
1467         PUTBACK;
1468         ENTER;
1469         call_method("PRINTF", G_SCALAR);
1470         LEAVE;
1471         SPAGAIN;
1472         MARK = ORIGMARK + 1;
1473         *MARK = *SP;
1474         SP = MARK;
1475         RETURN;
1476     }
1477
1478     sv = NEWSV(0,0);
1479     if (!(io = GvIO(gv))) {
1480         if (ckWARN2(WARN_UNOPENED,WARN_CLOSED))
1481             report_evil_fh(gv, io, PL_op->op_type);
1482         SETERRNO(EBADF,RMS_IFI);
1483         goto just_say_no;
1484     }
1485     else if (!(fp = IoOFP(io))) {
1486         if (ckWARN2(WARN_CLOSED,WARN_IO))  {
1487             if (IoIFP(io))
1488                 report_evil_fh(gv, io, OP_phoney_INPUT_ONLY);
1489             else if (ckWARN(WARN_CLOSED))
1490                 report_evil_fh(gv, io, PL_op->op_type);
1491         }
1492         SETERRNO(EBADF,IoIFP(io)?RMS_FAC:RMS_IFI);
1493         goto just_say_no;
1494     }
1495     else {
1496         do_sprintf(sv, SP - MARK, MARK + 1);
1497         if (!do_print(sv, fp))
1498             goto just_say_no;
1499
1500         if (IoFLAGS(io) & IOf_FLUSH)
1501             if (PerlIO_flush(fp) == EOF)
1502                 goto just_say_no;
1503     }
1504     SvREFCNT_dec(sv);
1505     SP = ORIGMARK;
1506     PUSHs(&PL_sv_yes);
1507     RETURN;
1508
1509   just_say_no:
1510     SvREFCNT_dec(sv);
1511     SP = ORIGMARK;
1512     PUSHs(&PL_sv_undef);
1513     RETURN;
1514 }
1515
1516 PP(pp_sysopen)
1517 {
1518     dSP;
1519     const int perm = (MAXARG > 3) ? POPi : 0666;
1520     const int mode = POPi;
1521     SV * const sv = POPs;
1522     GV * const gv = (GV *)POPs;
1523     STRLEN len;
1524
1525     /* Need TIEHANDLE method ? */
1526     const char * const tmps = SvPV_const(sv, len);
1527     /* FIXME? do_open should do const  */
1528     if (do_open(gv, (char*)tmps, len, TRUE, mode, perm, Nullfp)) {
1529         IoLINES(GvIOp(gv)) = 0;
1530         PUSHs(&PL_sv_yes);
1531     }
1532     else {
1533         PUSHs(&PL_sv_undef);
1534     }
1535     RETURN;
1536 }
1537
1538 PP(pp_sysread)
1539 {
1540     dVAR; dSP; dMARK; dORIGMARK; dTARGET;
1541     int offset;
1542     IO *io;
1543     char *buffer;
1544     SSize_t length;
1545     SSize_t count;
1546     Sock_size_t bufsize;
1547     SV *bufsv;
1548     STRLEN blen;
1549     int fp_utf8;
1550     int buffer_utf8;
1551     SV *read_target;
1552     Size_t got = 0;
1553     Size_t wanted;
1554     bool charstart = FALSE;
1555     STRLEN charskip = 0;
1556     STRLEN skip = 0;
1557
1558     GV * const gv = (GV*)*++MARK;
1559     if ((PL_op->op_type == OP_READ || PL_op->op_type == OP_SYSREAD)
1560         && gv && (io = GvIO(gv)) )
1561     {
1562         const MAGIC * mg = SvTIED_mg((SV*)io, PERL_MAGIC_tiedscalar);
1563         if (mg) {
1564             SV *sv;
1565             PUSHMARK(MARK-1);
1566             *MARK = SvTIED_obj((SV*)io, mg);
1567             ENTER;
1568             call_method("READ", G_SCALAR);
1569             LEAVE;
1570             SPAGAIN;
1571             sv = POPs;
1572             SP = ORIGMARK;
1573             PUSHs(sv);
1574             RETURN;
1575         }
1576     }
1577
1578     if (!gv)
1579         goto say_undef;
1580     bufsv = *++MARK;
1581     if (! SvOK(bufsv))
1582         sv_setpvn(bufsv, "", 0);
1583     length = SvIVx(*++MARK);
1584     SETERRNO(0,0);
1585     if (MARK < SP)
1586         offset = SvIVx(*++MARK);
1587     else
1588         offset = 0;
1589     io = GvIO(gv);
1590     if (!io || !IoIFP(io)) {
1591         if (ckWARN2(WARN_UNOPENED,WARN_CLOSED))
1592             report_evil_fh(gv, io, PL_op->op_type);
1593         SETERRNO(EBADF,RMS_IFI);
1594         goto say_undef;
1595     }
1596     if ((fp_utf8 = PerlIO_isutf8(IoIFP(io))) && !IN_BYTES) {
1597         buffer = SvPVutf8_force(bufsv, blen);
1598         /* UTF-8 may not have been set if they are all low bytes */
1599         SvUTF8_on(bufsv);
1600         buffer_utf8 = 0;
1601     }
1602     else {
1603         buffer = SvPV_force(bufsv, blen);
1604         buffer_utf8 = !IN_BYTES && SvUTF8(bufsv);
1605     }
1606     if (length < 0)
1607         DIE(aTHX_ "Negative length");
1608     wanted = length;
1609
1610     charstart = TRUE;
1611     charskip  = 0;
1612     skip = 0;
1613
1614 #ifdef HAS_SOCKET
1615     if (PL_op->op_type == OP_RECV) {
1616         char namebuf[MAXPATHLEN];
1617 #if (defined(VMS_DO_SOCKETS) && defined(DECCRTL_SOCKETS)) || defined(MPE) || defined(__QNXNTO__)
1618         bufsize = sizeof (struct sockaddr_in);
1619 #else
1620         bufsize = sizeof namebuf;
1621 #endif
1622 #ifdef OS2      /* At least Warp3+IAK: only the first byte of bufsize set */
1623         if (bufsize >= 256)
1624             bufsize = 255;
1625 #endif
1626         buffer = SvGROW(bufsv, (STRLEN)(length+1));
1627         /* 'offset' means 'flags' here */
1628         count = PerlSock_recvfrom(PerlIO_fileno(IoIFP(io)), buffer, length, offset,
1629                           (struct sockaddr *)namebuf, &bufsize);
1630         if (count < 0)
1631             RETPUSHUNDEF;
1632 #ifdef EPOC
1633         /* Bogus return without padding */
1634         bufsize = sizeof (struct sockaddr_in);
1635 #endif
1636         SvCUR_set(bufsv, count);
1637         *SvEND(bufsv) = '\0';
1638         (void)SvPOK_only(bufsv);
1639         if (fp_utf8)
1640             SvUTF8_on(bufsv);
1641         SvSETMAGIC(bufsv);
1642         /* This should not be marked tainted if the fp is marked clean */
1643         if (!(IoFLAGS(io) & IOf_UNTAINT))
1644             SvTAINTED_on(bufsv);
1645         SP = ORIGMARK;
1646         sv_setpvn(TARG, namebuf, bufsize);
1647         PUSHs(TARG);
1648         RETURN;
1649     }
1650 #else
1651     if (PL_op->op_type == OP_RECV)
1652         DIE(aTHX_ PL_no_sock_func, "recv");
1653 #endif
1654     if (DO_UTF8(bufsv)) {
1655         /* offset adjust in characters not bytes */
1656         blen = sv_len_utf8(bufsv);
1657     }
1658     if (offset < 0) {
1659         if (-offset > (int)blen)
1660             DIE(aTHX_ "Offset outside string");
1661         offset += blen;
1662     }
1663     if (DO_UTF8(bufsv)) {
1664         /* convert offset-as-chars to offset-as-bytes */
1665         if (offset >= (int)blen)
1666             offset += SvCUR(bufsv) - blen;
1667         else
1668             offset = utf8_hop((U8 *)buffer,offset) - (U8 *) buffer;
1669     }
1670  more_bytes:
1671     bufsize = SvCUR(bufsv);
1672     /* Allocating length + offset + 1 isn't perfect in the case of reading
1673        bytes from a byte file handle into a UTF8 buffer, but it won't harm us
1674        unduly.
1675        (should be 2 * length + offset + 1, or possibly something longer if
1676        PL_encoding is true) */
1677     buffer  = SvGROW(bufsv, (STRLEN)(length+offset+1));
1678     if (offset > 0 && (Sock_size_t)offset > bufsize) { /* Zero any newly allocated space */
1679         Zero(buffer+bufsize, offset-bufsize, char);
1680     }
1681     buffer = buffer + offset;
1682     if (!buffer_utf8) {
1683         read_target = bufsv;
1684     } else {
1685         /* Best to read the bytes into a new SV, upgrade that to UTF8, then
1686            concatenate it to the current buffer.  */
1687
1688         /* Truncate the existing buffer to the start of where we will be
1689            reading to:  */
1690         SvCUR_set(bufsv, offset);
1691
1692         read_target = sv_newmortal();
1693         SvUPGRADE(read_target, SVt_PV);
1694         buffer = SvGROW(read_target, (STRLEN)(length + 1));
1695     }
1696
1697     if (PL_op->op_type == OP_SYSREAD) {
1698 #ifdef PERL_SOCK_SYSREAD_IS_RECV
1699         if (IoTYPE(io) == IoTYPE_SOCKET) {
1700             count = PerlSock_recv(PerlIO_fileno(IoIFP(io)),
1701                                    buffer, length, 0);
1702         }
1703         else
1704 #endif
1705         {
1706             count = PerlLIO_read(PerlIO_fileno(IoIFP(io)),
1707                                   buffer, length);
1708         }
1709     }
1710     else
1711 #ifdef HAS_SOCKET__bad_code_maybe
1712     if (IoTYPE(io) == IoTYPE_SOCKET) {
1713         char namebuf[MAXPATHLEN];
1714 #if defined(VMS_DO_SOCKETS) && defined(DECCRTL_SOCKETS)
1715         bufsize = sizeof (struct sockaddr_in);
1716 #else
1717         bufsize = sizeof namebuf;
1718 #endif
1719         count = PerlSock_recvfrom(PerlIO_fileno(IoIFP(io)), buffer, length, 0,
1720                           (struct sockaddr *)namebuf, &bufsize);
1721     }
1722     else
1723 #endif
1724     {
1725         count = PerlIO_read(IoIFP(io), buffer, length);
1726         /* PerlIO_read() - like fread() returns 0 on both error and EOF */
1727         if (count == 0 && PerlIO_error(IoIFP(io)))
1728             count = -1;
1729     }
1730     if (count < 0) {
1731         if ((IoTYPE(io) == IoTYPE_WRONLY) && ckWARN(WARN_IO))
1732                 report_evil_fh(gv, io, OP_phoney_OUTPUT_ONLY);
1733         goto say_undef;
1734     }
1735     SvCUR_set(read_target, count+(buffer - SvPVX_const(read_target)));
1736     *SvEND(read_target) = '\0';
1737     (void)SvPOK_only(read_target);
1738     if (fp_utf8 && !IN_BYTES) {
1739         /* Look at utf8 we got back and count the characters */
1740         const char *bend = buffer + count;
1741         while (buffer < bend) {
1742             if (charstart) {
1743                 skip = UTF8SKIP(buffer);
1744                 charskip = 0;
1745             }
1746             if (buffer - charskip + skip > bend) {
1747                 /* partial character - try for rest of it */
1748                 length = skip - (bend-buffer);
1749                 offset = bend - SvPVX_const(bufsv);
1750                 charstart = FALSE;
1751                 charskip += count;
1752                 goto more_bytes;
1753             }
1754             else {
1755                 got++;
1756                 buffer += skip;
1757                 charstart = TRUE;
1758                 charskip  = 0;
1759             }
1760         }
1761         /* If we have not 'got' the number of _characters_ we 'wanted' get some more
1762            provided amount read (count) was what was requested (length)
1763          */
1764         if (got < wanted && count == length) {
1765             length = wanted - got;
1766             offset = bend - SvPVX_const(bufsv);
1767             goto more_bytes;
1768         }
1769         /* return value is character count */
1770         count = got;
1771         SvUTF8_on(bufsv);
1772     }
1773     else if (buffer_utf8) {
1774         /* Let svcatsv upgrade the bytes we read in to utf8.
1775            The buffer is a mortal so will be freed soon.  */
1776         sv_catsv_nomg(bufsv, read_target);
1777     }
1778     SvSETMAGIC(bufsv);
1779     /* This should not be marked tainted if the fp is marked clean */
1780     if (!(IoFLAGS(io) & IOf_UNTAINT))
1781         SvTAINTED_on(bufsv);
1782     SP = ORIGMARK;
1783     PUSHi(count);
1784     RETURN;
1785
1786   say_undef:
1787     SP = ORIGMARK;
1788     RETPUSHUNDEF;
1789 }
1790
1791 PP(pp_syswrite)
1792 {
1793     dVAR; dSP;
1794     const int items = (SP - PL_stack_base) - TOPMARK;
1795     if (items == 2) {
1796         SV *sv;
1797         EXTEND(SP, 1);
1798         sv = sv_2mortal(newSViv(sv_len(*SP)));
1799         PUSHs(sv);
1800         PUTBACK;
1801     }
1802     return pp_send();
1803 }
1804
1805 PP(pp_send)
1806 {
1807     dVAR; dSP; dMARK; dORIGMARK; dTARGET;
1808     GV *gv;
1809     IO *io;
1810     SV *bufsv;
1811     const char *buffer;
1812     Size_t length;
1813     SSize_t retval;
1814     STRLEN blen;
1815     MAGIC *mg;
1816
1817     gv = (GV*)*++MARK;
1818     if (PL_op->op_type == OP_SYSWRITE
1819         && gv && (io = GvIO(gv))
1820         && (mg = SvTIED_mg((SV*)io, PERL_MAGIC_tiedscalar)))
1821     {
1822         SV *sv;
1823         
1824         PUSHMARK(MARK-1);
1825         *MARK = SvTIED_obj((SV*)io, mg);
1826         ENTER;
1827         call_method("WRITE", G_SCALAR);
1828         LEAVE;
1829         SPAGAIN;
1830         sv = POPs;
1831         SP = ORIGMARK;
1832         PUSHs(sv);
1833         RETURN;
1834     }
1835     if (!gv)
1836         goto say_undef;
1837     bufsv = *++MARK;
1838 #if Size_t_size > IVSIZE
1839     length = (Size_t)SvNVx(*++MARK);
1840 #else
1841     length = (Size_t)SvIVx(*++MARK);
1842 #endif
1843     if ((SSize_t)length < 0)
1844         DIE(aTHX_ "Negative length");
1845     SETERRNO(0,0);
1846     io = GvIO(gv);
1847     if (!io || !IoIFP(io)) {
1848         retval = -1;
1849         if (ckWARN(WARN_CLOSED))
1850             report_evil_fh(gv, io, PL_op->op_type);
1851         SETERRNO(EBADF,RMS_IFI);
1852         goto say_undef;
1853     }
1854
1855     if (PerlIO_isutf8(IoIFP(io))) {
1856         if (!SvUTF8(bufsv)) {
1857             bufsv = sv_2mortal(newSVsv(bufsv));
1858             buffer = sv_2pvutf8(bufsv, &blen);
1859         } else
1860             buffer = SvPV_const(bufsv, blen);
1861     }
1862     else {
1863          if (DO_UTF8(bufsv)) {
1864               /* Not modifying source SV, so making a temporary copy. */
1865               bufsv = sv_2mortal(newSVsv(bufsv));
1866               sv_utf8_downgrade(bufsv, FALSE);
1867          }
1868          buffer = SvPV_const(bufsv, blen);
1869     }
1870
1871     if (PL_op->op_type == OP_SYSWRITE) {
1872         IV offset;
1873         if (DO_UTF8(bufsv)) {
1874             /* length and offset are in chars */
1875             blen   = sv_len_utf8(bufsv);
1876         }
1877         if (MARK < SP) {
1878             offset = SvIVx(*++MARK);
1879             if (offset < 0) {
1880                 if (-offset > (IV)blen)
1881                     DIE(aTHX_ "Offset outside string");
1882                 offset += blen;
1883             } else if (offset >= (IV)blen && blen > 0)
1884                 DIE(aTHX_ "Offset outside string");
1885         } else
1886             offset = 0;
1887         if (length > blen - offset)
1888             length = blen - offset;
1889         if (DO_UTF8(bufsv)) {
1890             buffer = (const char*)utf8_hop((const U8 *)buffer, offset);
1891             length = utf8_hop((U8 *)buffer, length) - (U8 *)buffer;
1892         }
1893         else {
1894             buffer = buffer+offset;
1895         }
1896 #ifdef PERL_SOCK_SYSWRITE_IS_SEND
1897         if (IoTYPE(io) == IoTYPE_SOCKET) {
1898             retval = PerlSock_send(PerlIO_fileno(IoIFP(io)),
1899                                    buffer, length, 0);
1900         }
1901         else
1902 #endif
1903         {
1904             /* See the note at doio.c:do_print about filesize limits. --jhi */
1905             retval = PerlLIO_write(PerlIO_fileno(IoIFP(io)),
1906                                    buffer, length);
1907         }
1908     }
1909 #ifdef HAS_SOCKET
1910     else if (SP > MARK) {
1911         STRLEN mlen;
1912         char * const sockbuf = SvPVx(*++MARK, mlen);
1913         /* length is really flags */
1914         retval = PerlSock_sendto(PerlIO_fileno(IoIFP(io)), buffer, blen,
1915                                  length, (struct sockaddr *)sockbuf, mlen);
1916     }
1917     else
1918         /* length is really flags */
1919         retval = PerlSock_send(PerlIO_fileno(IoIFP(io)), buffer, blen, length);
1920 #else
1921     else
1922         DIE(aTHX_ PL_no_sock_func, "send");
1923 #endif
1924     if (retval < 0)
1925         goto say_undef;
1926     SP = ORIGMARK;
1927     if (DO_UTF8(bufsv))
1928         retval = utf8_length((U8*)buffer, (U8*)buffer + retval);
1929 #if Size_t_size > IVSIZE
1930     PUSHn(retval);
1931 #else
1932     PUSHi(retval);
1933 #endif
1934     RETURN;
1935
1936   say_undef:
1937     SP = ORIGMARK;
1938     RETPUSHUNDEF;
1939 }
1940
1941 PP(pp_recv)
1942 {
1943     return pp_sysread();
1944 }
1945
1946 PP(pp_eof)
1947 {
1948     dVAR; dSP;
1949     GV *gv;
1950     IO *io;
1951     MAGIC *mg;
1952
1953     if (MAXARG == 0) {
1954         if (PL_op->op_flags & OPf_SPECIAL) {    /* eof() */
1955             IO *io;
1956             gv = PL_last_in_gv = GvEGV(PL_argvgv);
1957             io = GvIO(gv);
1958             if (io && !IoIFP(io)) {
1959                 if ((IoFLAGS(io) & IOf_START) && av_len(GvAVn(gv)) < 0) {
1960                     IoLINES(io) = 0;
1961                     IoFLAGS(io) &= ~IOf_START;
1962                     do_open(gv, (char *)"-", 1, FALSE, O_RDONLY, 0, Nullfp);
1963                     sv_setpvn(GvSV(gv), "-", 1);
1964                     SvSETMAGIC(GvSV(gv));
1965                 }
1966                 else if (!nextargv(gv))
1967                     RETPUSHYES;
1968             }
1969         }
1970         else
1971             gv = PL_last_in_gv;                 /* eof */
1972     }
1973     else
1974         gv = PL_last_in_gv = (GV*)POPs;         /* eof(FH) */
1975
1976     if (gv && (io = GvIO(gv))
1977         && (mg = SvTIED_mg((SV*)io, PERL_MAGIC_tiedscalar)))
1978     {
1979         PUSHMARK(SP);
1980         XPUSHs(SvTIED_obj((SV*)io, mg));
1981         PUTBACK;
1982         ENTER;
1983         call_method("EOF", G_SCALAR);
1984         LEAVE;
1985         SPAGAIN;
1986         RETURN;
1987     }
1988
1989     PUSHs(boolSV(!gv || do_eof(gv)));
1990     RETURN;
1991 }
1992
1993 PP(pp_tell)
1994 {
1995     dVAR; dSP; dTARGET;
1996     GV *gv;
1997     IO *io;
1998     MAGIC *mg;
1999
2000     if (MAXARG == 0)
2001         gv = PL_last_in_gv;
2002     else
2003         gv = PL_last_in_gv = (GV*)POPs;
2004
2005     if (gv && (io = GvIO(gv))
2006         && (mg = SvTIED_mg((SV*)io, PERL_MAGIC_tiedscalar)))
2007     {
2008         PUSHMARK(SP);
2009         XPUSHs(SvTIED_obj((SV*)io, mg));
2010         PUTBACK;
2011         ENTER;
2012         call_method("TELL", G_SCALAR);
2013         LEAVE;
2014         SPAGAIN;
2015         RETURN;
2016     }
2017
2018 #if LSEEKSIZE > IVSIZE
2019     PUSHn( do_tell(gv) );
2020 #else
2021     PUSHi( do_tell(gv) );
2022 #endif
2023     RETURN;
2024 }
2025
2026 PP(pp_seek)
2027 {
2028     return pp_sysseek();
2029 }
2030
2031 PP(pp_sysseek)
2032 {
2033     dVAR; dSP;
2034     GV *gv;
2035     IO *io;
2036     const int whence = POPi;
2037 #if LSEEKSIZE > IVSIZE
2038     Off_t offset = (Off_t)SvNVx(POPs);
2039 #else
2040     Off_t offset = (Off_t)SvIVx(POPs);
2041 #endif
2042     MAGIC *mg;
2043
2044     gv = PL_last_in_gv = (GV*)POPs;
2045
2046     if (gv && (io = GvIO(gv))
2047         && (mg = SvTIED_mg((SV*)io, PERL_MAGIC_tiedscalar)))
2048     {
2049         PUSHMARK(SP);
2050         XPUSHs(SvTIED_obj((SV*)io, mg));
2051 #if LSEEKSIZE > IVSIZE
2052         XPUSHs(sv_2mortal(newSVnv((NV) offset)));
2053 #else
2054         XPUSHs(sv_2mortal(newSViv(offset)));
2055 #endif
2056         XPUSHs(sv_2mortal(newSViv(whence)));
2057         PUTBACK;
2058         ENTER;
2059         call_method("SEEK", G_SCALAR);
2060         LEAVE;
2061         SPAGAIN;
2062         RETURN;
2063     }
2064
2065     if (PL_op->op_type == OP_SEEK)
2066         PUSHs(boolSV(do_seek(gv, offset, whence)));
2067     else {
2068         Off_t sought = do_sysseek(gv, offset, whence);
2069         if (sought < 0)
2070             PUSHs(&PL_sv_undef);
2071         else {
2072             SV* sv = sought ?
2073 #if LSEEKSIZE > IVSIZE
2074                 newSVnv((NV)sought)
2075 #else
2076                 newSViv(sought)
2077 #endif
2078                 : newSVpvn(zero_but_true, ZBTLEN);
2079             PUSHs(sv_2mortal(sv));
2080         }
2081     }
2082     RETURN;
2083 }
2084
2085 PP(pp_truncate)
2086 {
2087     dSP;
2088     /* There seems to be no consensus on the length type of truncate()
2089      * and ftruncate(), both off_t and size_t have supporters. In
2090      * general one would think that when using large files, off_t is
2091      * at least as wide as size_t, so using an off_t should be okay. */
2092     /* XXX Configure probe for the length type of *truncate() needed XXX */
2093     Off_t len;
2094
2095 #if Off_t_size > IVSIZE
2096     len = (Off_t)POPn;
2097 #else
2098     len = (Off_t)POPi;
2099 #endif
2100     /* Checking for length < 0 is problematic as the type might or
2101      * might not be signed: if it is not, clever compilers will moan. */
2102     /* XXX Configure probe for the signedness of the length type of *truncate() needed? XXX */
2103     SETERRNO(0,0);
2104     {
2105         int result = 1;
2106         GV *tmpgv;
2107         IO *io;
2108
2109         if (PL_op->op_flags & OPf_SPECIAL) {
2110             tmpgv = gv_fetchsv(POPs, FALSE, SVt_PVIO);
2111
2112         do_ftruncate_gv:
2113             if (!GvIO(tmpgv))
2114                 result = 0;
2115             else {
2116                 PerlIO *fp;
2117                 io = GvIOp(tmpgv);
2118             do_ftruncate_io:
2119                 TAINT_PROPER("truncate");
2120                 if (!(fp = IoIFP(io))) {
2121                     result = 0;
2122                 }
2123                 else {
2124                     PerlIO_flush(fp);
2125 #ifdef HAS_TRUNCATE
2126                     if (ftruncate(PerlIO_fileno(fp), len) < 0)
2127 #else
2128                     if (my_chsize(PerlIO_fileno(fp), len) < 0)
2129 #endif
2130                         result = 0;
2131                 }
2132             }
2133         }
2134         else {
2135             SV *sv = POPs;
2136             const char *name;
2137
2138             if (SvTYPE(sv) == SVt_PVGV) {
2139                 tmpgv = (GV*)sv;                /* *main::FRED for example */
2140                 goto do_ftruncate_gv;
2141             }
2142             else if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVGV) {
2143                 tmpgv = (GV*) SvRV(sv); /* \*main::FRED for example */
2144                 goto do_ftruncate_gv;
2145             }
2146             else if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVIO) {
2147                 io = (IO*) SvRV(sv); /* *main::FRED{IO} for example */
2148                 goto do_ftruncate_io;
2149             }
2150
2151             name = SvPV_nolen_const(sv);
2152             TAINT_PROPER("truncate");
2153 #ifdef HAS_TRUNCATE
2154             if (truncate(name, len) < 0)
2155                 result = 0;
2156 #else
2157             {
2158                 int tmpfd;
2159
2160                 if ((tmpfd = PerlLIO_open(name, O_RDWR)) < 0)
2161                     result = 0;
2162                 else {
2163                     if (my_chsize(tmpfd, len) < 0)
2164                         result = 0;
2165                     PerlLIO_close(tmpfd);
2166                 }
2167             }
2168 #endif
2169         }
2170
2171         if (result)
2172             RETPUSHYES;
2173         if (!errno)
2174             SETERRNO(EBADF,RMS_IFI);
2175         RETPUSHUNDEF;
2176     }
2177 }
2178
2179 PP(pp_fcntl)
2180 {
2181     return pp_ioctl();
2182 }
2183
2184 PP(pp_ioctl)
2185 {
2186     dSP; dTARGET;
2187     SV *argsv = POPs;
2188     const unsigned int func = POPu;
2189     const int optype = PL_op->op_type;
2190     char *s;
2191     IV retval;
2192     GV *gv = (GV*)POPs;
2193     IO *io = gv ? GvIOn(gv) : 0;
2194
2195     if (!io || !argsv || !IoIFP(io)) {
2196         if (ckWARN2(WARN_UNOPENED,WARN_CLOSED))
2197             report_evil_fh(gv, io, PL_op->op_type);
2198         SETERRNO(EBADF,RMS_IFI);        /* well, sort of... */
2199         RETPUSHUNDEF;
2200     }
2201
2202     if (SvPOK(argsv) || !SvNIOK(argsv)) {
2203         STRLEN len;
2204         STRLEN need;
2205         s = SvPV_force(argsv, len);
2206         need = IOCPARM_LEN(func);
2207         if (len < need) {
2208             s = Sv_Grow(argsv, need + 1);
2209             SvCUR_set(argsv, need);
2210         }
2211
2212         s[SvCUR(argsv)] = 17;   /* a little sanity check here */
2213     }
2214     else {
2215         retval = SvIV(argsv);
2216         s = INT2PTR(char*,retval);              /* ouch */
2217     }
2218
2219     TAINT_PROPER(optype == OP_IOCTL ? "ioctl" : "fcntl");
2220
2221     if (optype == OP_IOCTL)
2222 #ifdef HAS_IOCTL
2223         retval = PerlLIO_ioctl(PerlIO_fileno(IoIFP(io)), func, s);
2224 #else
2225         DIE(aTHX_ "ioctl is not implemented");
2226 #endif
2227     else
2228 #ifndef HAS_FCNTL
2229       DIE(aTHX_ "fcntl is not implemented");
2230 #else
2231 #if defined(OS2) && defined(__EMX__)
2232         retval = fcntl(PerlIO_fileno(IoIFP(io)), func, (int)s);
2233 #else
2234         retval = fcntl(PerlIO_fileno(IoIFP(io)), func, s);
2235 #endif
2236 #endif
2237
2238 #if defined(HAS_IOCTL) || defined(HAS_FCNTL)
2239     if (SvPOK(argsv)) {
2240         if (s[SvCUR(argsv)] != 17)
2241             DIE(aTHX_ "Possible memory corruption: %s overflowed 3rd argument",
2242                 OP_NAME(PL_op));
2243         s[SvCUR(argsv)] = 0;            /* put our null back */
2244         SvSETMAGIC(argsv);              /* Assume it has changed */
2245     }
2246
2247     if (retval == -1)
2248         RETPUSHUNDEF;
2249     if (retval != 0) {
2250         PUSHi(retval);
2251     }
2252     else {
2253         PUSHp(zero_but_true, ZBTLEN);
2254     }
2255 #endif
2256     RETURN;
2257 }
2258
2259 PP(pp_flock)
2260 {
2261 #ifdef FLOCK
2262     dSP; dTARGET;
2263     I32 value;
2264     int argtype;
2265     GV *gv;
2266     IO *io = NULL;
2267     PerlIO *fp;
2268
2269     argtype = POPi;
2270     if (MAXARG == 0)
2271         gv = PL_last_in_gv;
2272     else
2273         gv = (GV*)POPs;
2274     if (gv && (io = GvIO(gv)))
2275         fp = IoIFP(io);
2276     else {
2277         fp = Nullfp;
2278         io = NULL;
2279     }
2280     if (fp) {
2281         (void)PerlIO_flush(fp);
2282         value = (I32)(PerlLIO_flock(PerlIO_fileno(fp), argtype) >= 0);
2283     }
2284     else {
2285         if (ckWARN2(WARN_UNOPENED,WARN_CLOSED))
2286             report_evil_fh(gv, io, PL_op->op_type);
2287         value = 0;
2288         SETERRNO(EBADF,RMS_IFI);
2289     }
2290     PUSHi(value);
2291     RETURN;
2292 #else
2293     DIE(aTHX_ PL_no_func, "flock()");
2294 #endif
2295 }
2296
2297 /* Sockets. */
2298
2299 PP(pp_socket)
2300 {
2301 #ifdef HAS_SOCKET
2302     dSP;
2303     GV *gv;
2304     register IO *io;
2305     int protocol = POPi;
2306     int type = POPi;
2307     int domain = POPi;
2308     int fd;
2309
2310     gv = (GV*)POPs;
2311     io = gv ? GvIOn(gv) : NULL;
2312
2313     if (!gv || !io) {
2314         if (ckWARN2(WARN_UNOPENED,WARN_CLOSED))
2315             report_evil_fh(gv, io, PL_op->op_type);
2316         if (IoIFP(io))
2317             do_close(gv, FALSE);
2318         SETERRNO(EBADF,LIB_INVARG);
2319         RETPUSHUNDEF;
2320     }
2321
2322     if (IoIFP(io))
2323         do_close(gv, FALSE);
2324
2325     TAINT_PROPER("socket");
2326     fd = PerlSock_socket(domain, type, protocol);
2327     if (fd < 0)
2328         RETPUSHUNDEF;
2329     IoIFP(io) = PerlIO_fdopen(fd, "r"SOCKET_OPEN_MODE); /* stdio gets confused about sockets */
2330     IoOFP(io) = PerlIO_fdopen(fd, "w"SOCKET_OPEN_MODE);
2331     IoTYPE(io) = IoTYPE_SOCKET;
2332     if (!IoIFP(io) || !IoOFP(io)) {
2333         if (IoIFP(io)) PerlIO_close(IoIFP(io));
2334         if (IoOFP(io)) PerlIO_close(IoOFP(io));
2335         if (!IoIFP(io) && !IoOFP(io)) PerlLIO_close(fd);
2336         RETPUSHUNDEF;
2337     }
2338 #if defined(HAS_FCNTL) && defined(F_SETFD)
2339     fcntl(fd, F_SETFD, fd > PL_maxsysfd);       /* ensure close-on-exec */
2340 #endif
2341
2342 #ifdef EPOC
2343     setbuf( IoIFP(io), NULL); /* EPOC gets confused about sockets */
2344 #endif
2345
2346     RETPUSHYES;
2347 #else
2348     DIE(aTHX_ PL_no_sock_func, "socket");
2349 #endif
2350 }
2351
2352 PP(pp_sockpair)
2353 {
2354 #if defined (HAS_SOCKETPAIR) || (defined (HAS_SOCKET) && defined(SOCK_DGRAM) && defined(AF_INET) && defined(PF_INET))
2355     dSP;
2356     GV *gv1;
2357     GV *gv2;
2358     register IO *io1;
2359     register IO *io2;
2360     int protocol = POPi;
2361     int type = POPi;
2362     int domain = POPi;
2363     int fd[2];
2364
2365     gv2 = (GV*)POPs;
2366     gv1 = (GV*)POPs;
2367     io1 = gv1 ? GvIOn(gv1) : NULL;
2368     io2 = gv2 ? GvIOn(gv2) : NULL;
2369     if (!gv1 || !gv2 || !io1 || !io2) {
2370         if (ckWARN2(WARN_UNOPENED,WARN_CLOSED)) {
2371             if (!gv1 || !io1)
2372                 report_evil_fh(gv1, io1, PL_op->op_type);
2373             if (!gv2 || !io2)
2374                 report_evil_fh(gv1, io2, PL_op->op_type);
2375         }
2376         if (IoIFP(io1))
2377             do_close(gv1, FALSE);
2378         if (IoIFP(io2))
2379             do_close(gv2, FALSE);
2380         RETPUSHUNDEF;
2381     }
2382
2383     if (IoIFP(io1))
2384         do_close(gv1, FALSE);
2385     if (IoIFP(io2))
2386         do_close(gv2, FALSE);
2387
2388     TAINT_PROPER("socketpair");
2389     if (PerlSock_socketpair(domain, type, protocol, fd) < 0)
2390         RETPUSHUNDEF;
2391     IoIFP(io1) = PerlIO_fdopen(fd[0], "r"SOCKET_OPEN_MODE);
2392     IoOFP(io1) = PerlIO_fdopen(fd[0], "w"SOCKET_OPEN_MODE);
2393     IoTYPE(io1) = IoTYPE_SOCKET;
2394     IoIFP(io2) = PerlIO_fdopen(fd[1], "r"SOCKET_OPEN_MODE);
2395     IoOFP(io2) = PerlIO_fdopen(fd[1], "w"SOCKET_OPEN_MODE);
2396     IoTYPE(io2) = IoTYPE_SOCKET;
2397     if (!IoIFP(io1) || !IoOFP(io1) || !IoIFP(io2) || !IoOFP(io2)) {
2398         if (IoIFP(io1)) PerlIO_close(IoIFP(io1));
2399         if (IoOFP(io1)) PerlIO_close(IoOFP(io1));
2400         if (!IoIFP(io1) && !IoOFP(io1)) PerlLIO_close(fd[0]);
2401         if (IoIFP(io2)) PerlIO_close(IoIFP(io2));
2402         if (IoOFP(io2)) PerlIO_close(IoOFP(io2));
2403         if (!IoIFP(io2) && !IoOFP(io2)) PerlLIO_close(fd[1]);
2404         RETPUSHUNDEF;
2405     }
2406 #if defined(HAS_FCNTL) && defined(F_SETFD)
2407     fcntl(fd[0],F_SETFD,fd[0] > PL_maxsysfd);   /* ensure close-on-exec */
2408     fcntl(fd[1],F_SETFD,fd[1] > PL_maxsysfd);   /* ensure close-on-exec */
2409 #endif
2410
2411     RETPUSHYES;
2412 #else
2413     DIE(aTHX_ PL_no_sock_func, "socketpair");
2414 #endif
2415 }
2416
2417 PP(pp_bind)
2418 {
2419 #ifdef HAS_SOCKET
2420     dSP;
2421 #ifdef MPE /* Requires PRIV mode to bind() to ports < 1024 */
2422     extern void GETPRIVMODE();
2423     extern void GETUSERMODE();
2424 #endif
2425     SV *addrsv = POPs;
2426     /* OK, so on what platform does bind modify addr?  */
2427     const char *addr;
2428     GV *gv = (GV*)POPs;
2429     register IO *io = GvIOn(gv);
2430     STRLEN len;
2431     int bind_ok = 0;
2432 #ifdef MPE
2433     int mpeprivmode = 0;
2434 #endif
2435
2436     if (!io || !IoIFP(io))
2437         goto nuts;
2438
2439     addr = SvPV_const(addrsv, len);
2440     TAINT_PROPER("bind");
2441 #ifdef MPE /* Deal with MPE bind() peculiarities */
2442     if (((struct sockaddr *)addr)->sa_family == AF_INET) {
2443         /* The address *MUST* stupidly be zero. */
2444         ((struct sockaddr_in *)addr)->sin_addr.s_addr = INADDR_ANY;
2445         /* PRIV mode is required to bind() to ports < 1024. */
2446         if (((struct sockaddr_in *)addr)->sin_port < 1024 &&
2447             ((struct sockaddr_in *)addr)->sin_port > 0) {
2448             GETPRIVMODE(); /* If this fails, we are aborted by MPE/iX. */
2449             mpeprivmode = 1;
2450         }
2451     }
2452 #endif /* MPE */
2453     if (PerlSock_bind(PerlIO_fileno(IoIFP(io)),
2454                       (struct sockaddr *)addr, len) >= 0)
2455         bind_ok = 1;
2456
2457 #ifdef MPE /* Switch back to USER mode */
2458     if (mpeprivmode)
2459         GETUSERMODE();
2460 #endif /* MPE */
2461
2462     if (bind_ok)
2463         RETPUSHYES;
2464     else
2465         RETPUSHUNDEF;
2466
2467 nuts:
2468     if (ckWARN(WARN_CLOSED))
2469         report_evil_fh(gv, io, PL_op->op_type);
2470     SETERRNO(EBADF,SS_IVCHAN);
2471     RETPUSHUNDEF;
2472 #else
2473     DIE(aTHX_ PL_no_sock_func, "bind");
2474 #endif
2475 }
2476
2477 PP(pp_connect)
2478 {
2479 #ifdef HAS_SOCKET
2480     dSP;
2481     SV *addrsv = POPs;
2482     const char *addr;
2483     GV *gv = (GV*)POPs;
2484     register IO *io = GvIOn(gv);
2485     STRLEN len;
2486
2487     if (!io || !IoIFP(io))
2488         goto nuts;
2489
2490     addr = SvPV_const(addrsv, len);
2491     TAINT_PROPER("connect");
2492     if (PerlSock_connect(PerlIO_fileno(IoIFP(io)), (struct sockaddr *)addr, len) >= 0)
2493         RETPUSHYES;
2494     else
2495         RETPUSHUNDEF;
2496
2497 nuts:
2498     if (ckWARN(WARN_CLOSED))
2499         report_evil_fh(gv, io, PL_op->op_type);
2500     SETERRNO(EBADF,SS_IVCHAN);
2501     RETPUSHUNDEF;
2502 #else
2503     DIE(aTHX_ PL_no_sock_func, "connect");
2504 #endif
2505 }
2506
2507 PP(pp_listen)
2508 {
2509 #ifdef HAS_SOCKET
2510     dSP;
2511     int backlog = POPi;
2512     GV *gv = (GV*)POPs;
2513     register IO *io = gv ? GvIOn(gv) : NULL;
2514
2515     if (!gv || !io || !IoIFP(io))
2516         goto nuts;
2517
2518     if (PerlSock_listen(PerlIO_fileno(IoIFP(io)), backlog) >= 0)
2519         RETPUSHYES;
2520     else
2521         RETPUSHUNDEF;
2522
2523 nuts:
2524     if (ckWARN(WARN_CLOSED))
2525         report_evil_fh(gv, io, PL_op->op_type);
2526     SETERRNO(EBADF,SS_IVCHAN);
2527     RETPUSHUNDEF;
2528 #else
2529     DIE(aTHX_ PL_no_sock_func, "listen");
2530 #endif
2531 }
2532
2533 PP(pp_accept)
2534 {
2535 #ifdef HAS_SOCKET
2536     dSP; dTARGET;
2537     GV *ngv;
2538     GV *ggv;
2539     register IO *nstio;
2540     register IO *gstio;
2541     char namebuf[MAXPATHLEN];
2542 #if (defined(VMS_DO_SOCKETS) && defined(DECCRTL_SOCKETS)) || defined(MPE) || defined(__QNXNTO__)
2543     Sock_size_t len = sizeof (struct sockaddr_in);
2544 #else
2545     Sock_size_t len = sizeof namebuf;
2546 #endif
2547     int fd;
2548
2549     ggv = (GV*)POPs;
2550     ngv = (GV*)POPs;
2551
2552     if (!ngv)
2553         goto badexit;
2554     if (!ggv)
2555         goto nuts;
2556
2557     gstio = GvIO(ggv);
2558     if (!gstio || !IoIFP(gstio))
2559         goto nuts;
2560
2561     nstio = GvIOn(ngv);
2562     fd = PerlSock_accept(PerlIO_fileno(IoIFP(gstio)), (struct sockaddr *) namebuf, &len);
2563     if (fd < 0)
2564         goto badexit;
2565     if (IoIFP(nstio))
2566         do_close(ngv, FALSE);
2567     IoIFP(nstio) = PerlIO_fdopen(fd, "r"SOCKET_OPEN_MODE);
2568     IoOFP(nstio) = PerlIO_fdopen(fd, "w"SOCKET_OPEN_MODE);
2569     IoTYPE(nstio) = IoTYPE_SOCKET;
2570     if (!IoIFP(nstio) || !IoOFP(nstio)) {
2571         if (IoIFP(nstio)) PerlIO_close(IoIFP(nstio));
2572         if (IoOFP(nstio)) PerlIO_close(IoOFP(nstio));
2573         if (!IoIFP(nstio) && !IoOFP(nstio)) PerlLIO_close(fd);
2574         goto badexit;
2575     }
2576 #if defined(HAS_FCNTL) && defined(F_SETFD)
2577     fcntl(fd, F_SETFD, fd > PL_maxsysfd);       /* ensure close-on-exec */
2578 #endif
2579
2580 #ifdef EPOC
2581     len = sizeof (struct sockaddr_in); /* EPOC somehow truncates info */
2582     setbuf( IoIFP(nstio), NULL); /* EPOC gets confused about sockets */
2583 #endif
2584 #ifdef __SCO_VERSION__
2585     len = sizeof (struct sockaddr_in); /* OpenUNIX 8 somehow truncates info */
2586 #endif
2587
2588     PUSHp(namebuf, len);
2589     RETURN;
2590
2591 nuts:
2592     if (ckWARN(WARN_CLOSED))
2593         report_evil_fh(ggv, ggv ? GvIO(ggv) : 0, PL_op->op_type);
2594     SETERRNO(EBADF,SS_IVCHAN);
2595
2596 badexit:
2597     RETPUSHUNDEF;
2598
2599 #else
2600     DIE(aTHX_ PL_no_sock_func, "accept");
2601 #endif
2602 }
2603
2604 PP(pp_shutdown)
2605 {
2606 #ifdef HAS_SOCKET
2607     dSP; dTARGET;
2608     int how = POPi;
2609     GV *gv = (GV*)POPs;
2610     register IO *io = GvIOn(gv);
2611
2612     if (!io || !IoIFP(io))
2613         goto nuts;
2614
2615     PUSHi( PerlSock_shutdown(PerlIO_fileno(IoIFP(io)), how) >= 0 );
2616     RETURN;
2617
2618 nuts:
2619     if (ckWARN(WARN_CLOSED))
2620         report_evil_fh(gv, io, PL_op->op_type);
2621     SETERRNO(EBADF,SS_IVCHAN);
2622     RETPUSHUNDEF;
2623 #else
2624     DIE(aTHX_ PL_no_sock_func, "shutdown");
2625 #endif
2626 }
2627
2628 PP(pp_gsockopt)
2629 {
2630 #ifdef HAS_SOCKET
2631     return pp_ssockopt();
2632 #else
2633     DIE(aTHX_ PL_no_sock_func, "getsockopt");
2634 #endif
2635 }
2636
2637 PP(pp_ssockopt)
2638 {
2639 #ifdef HAS_SOCKET
2640     dSP;
2641     int optype = PL_op->op_type;
2642     SV *sv;
2643     int fd;
2644     unsigned int optname;
2645     unsigned int lvl;
2646     GV *gv;
2647     register IO *io;
2648     Sock_size_t len;
2649
2650     if (optype == OP_GSOCKOPT)
2651         sv = sv_2mortal(NEWSV(22, 257));
2652     else
2653         sv = POPs;
2654     optname = (unsigned int) POPi;
2655     lvl = (unsigned int) POPi;
2656
2657     gv = (GV*)POPs;
2658     io = GvIOn(gv);
2659     if (!io || !IoIFP(io))
2660         goto nuts;
2661
2662     fd = PerlIO_fileno(IoIFP(io));
2663     switch (optype) {
2664     case OP_GSOCKOPT:
2665         SvGROW(sv, 257);
2666         (void)SvPOK_only(sv);
2667         SvCUR_set(sv,256);
2668         *SvEND(sv) ='\0';
2669         len = SvCUR(sv);
2670         if (PerlSock_getsockopt(fd, lvl, optname, SvPVX(sv), &len) < 0)
2671             goto nuts2;
2672         SvCUR_set(sv, len);
2673         *SvEND(sv) ='\0';
2674         PUSHs(sv);
2675         break;
2676     case OP_SSOCKOPT: {
2677             const char *buf;
2678             int aint;
2679             if (SvPOKp(sv)) {
2680                 STRLEN l;
2681                 buf = SvPV_const(sv, l);
2682                 len = l;
2683             }
2684             else {
2685                 aint = (int)SvIV(sv);
2686                 buf = (const char*)&aint;
2687                 len = sizeof(int);
2688             }
2689             if (PerlSock_setsockopt(fd, lvl, optname, buf, len) < 0)
2690                 goto nuts2;
2691             PUSHs(&PL_sv_yes);
2692         }
2693         break;
2694     }
2695     RETURN;
2696
2697 nuts:
2698     if (ckWARN(WARN_CLOSED))
2699         report_evil_fh(gv, io, optype);
2700     SETERRNO(EBADF,SS_IVCHAN);
2701 nuts2:
2702     RETPUSHUNDEF;
2703
2704 #else
2705     DIE(aTHX_ PL_no_sock_func, "setsockopt");
2706 #endif
2707 }
2708
2709 PP(pp_getsockname)
2710 {
2711 #ifdef HAS_SOCKET
2712     return pp_getpeername();
2713 #else
2714     DIE(aTHX_ PL_no_sock_func, "getsockname");
2715 #endif
2716 }
2717
2718 PP(pp_getpeername)
2719 {
2720 #ifdef HAS_SOCKET
2721     dSP;
2722     int optype = PL_op->op_type;
2723     SV *sv;
2724     int fd;
2725     GV *gv = (GV*)POPs;
2726     register IO *io = GvIOn(gv);
2727     Sock_size_t len;
2728
2729     if (!io || !IoIFP(io))
2730         goto nuts;
2731
2732     sv = sv_2mortal(NEWSV(22, 257));
2733     (void)SvPOK_only(sv);
2734     len = 256;
2735     SvCUR_set(sv, len);
2736     *SvEND(sv) ='\0';
2737     fd = PerlIO_fileno(IoIFP(io));
2738     switch (optype) {
2739     case OP_GETSOCKNAME:
2740         if (PerlSock_getsockname(fd, (struct sockaddr *)SvPVX(sv), &len) < 0)
2741             goto nuts2;
2742         break;
2743     case OP_GETPEERNAME:
2744         if (PerlSock_getpeername(fd, (struct sockaddr *)SvPVX(sv), &len) < 0)
2745             goto nuts2;
2746 #if defined(VMS_DO_SOCKETS) && defined (DECCRTL_SOCKETS)
2747         {
2748             static const char nowhere[] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
2749             /* If the call succeeded, make sure we don't have a zeroed port/addr */
2750             if (((struct sockaddr *)SvPVX_const(sv))->sa_family == AF_INET &&
2751                 !memcmp((char *)SvPVX_const(sv) + sizeof(u_short), nowhere,
2752                         sizeof(u_short) + sizeof(struct in_addr))) {
2753                 goto nuts2;     
2754             }
2755         }
2756 #endif
2757         break;
2758     }
2759 #ifdef BOGUS_GETNAME_RETURN
2760     /* Interactive Unix, getpeername() and getsockname()
2761       does not return valid namelen */
2762     if (len == BOGUS_GETNAME_RETURN)
2763         len = sizeof(struct sockaddr);
2764 #endif
2765     SvCUR_set(sv, len);
2766     *SvEND(sv) ='\0';
2767     PUSHs(sv);
2768     RETURN;
2769
2770 nuts:
2771     if (ckWARN(WARN_CLOSED))
2772         report_evil_fh(gv, io, optype);
2773     SETERRNO(EBADF,SS_IVCHAN);
2774 nuts2:
2775     RETPUSHUNDEF;
2776
2777 #else
2778     DIE(aTHX_ PL_no_sock_func, "getpeername");
2779 #endif
2780 }
2781
2782 /* Stat calls. */
2783
2784 PP(pp_lstat)
2785 {
2786     return pp_stat();
2787 }
2788
2789 PP(pp_stat)
2790 {
2791     dSP;
2792     GV *gv;
2793     I32 gimme;
2794     I32 max = 13;
2795
2796     if (PL_op->op_flags & OPf_REF) {
2797         gv = cGVOP_gv;
2798         if (PL_op->op_type == OP_LSTAT) {
2799             if (gv != PL_defgv) {
2800                 if (ckWARN(WARN_IO))
2801                     Perl_warner(aTHX_ packWARN(WARN_IO),
2802                         "lstat() on filehandle %s", GvENAME(gv));
2803             } else if (PL_laststype != OP_LSTAT)
2804                 Perl_croak(aTHX_ "The stat preceding lstat() wasn't an lstat");
2805         }
2806
2807       do_fstat:
2808         if (gv != PL_defgv) {
2809             PL_laststype = OP_STAT;
2810             PL_statgv = gv;
2811             sv_setpvn(PL_statname, "", 0);
2812             PL_laststatval = (GvIO(gv) && IoIFP(GvIOp(gv))
2813                 ? PerlLIO_fstat(PerlIO_fileno(IoIFP(GvIOn(gv))), &PL_statcache) : -1);
2814         }
2815         if (PL_laststatval < 0) {
2816             if (ckWARN2(WARN_UNOPENED,WARN_CLOSED))
2817                 report_evil_fh(gv, GvIO(gv), PL_op->op_type);
2818             max = 0;
2819         }
2820     }
2821     else {
2822         SV* sv = POPs;
2823         if (SvTYPE(sv) == SVt_PVGV) {
2824             gv = (GV*)sv;
2825             goto do_fstat;
2826         }
2827         else if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVGV) {
2828             gv = (GV*)SvRV(sv);
2829             if (PL_op->op_type == OP_LSTAT && ckWARN(WARN_IO))
2830                 Perl_warner(aTHX_ packWARN(WARN_IO),
2831                         "lstat() on filehandle %s", GvENAME(gv));
2832             goto do_fstat;
2833         }
2834         sv_setpv(PL_statname, SvPV_nolen_const(sv));
2835         PL_statgv = Nullgv;
2836         PL_laststype = PL_op->op_type;
2837         if (PL_op->op_type == OP_LSTAT)
2838             PL_laststatval = PerlLIO_lstat(SvPV_nolen_const(PL_statname), &PL_statcache);
2839         else
2840             PL_laststatval = PerlLIO_stat(SvPV_nolen_const(PL_statname), &PL_statcache);
2841         if (PL_laststatval < 0) {
2842             if (ckWARN(WARN_NEWLINE) && strchr(SvPV_nolen_const(PL_statname), '\n'))
2843                 Perl_warner(aTHX_ packWARN(WARN_NEWLINE), PL_warn_nl, "stat");
2844             max = 0;
2845         }
2846     }
2847
2848     gimme = GIMME_V;
2849     if (gimme != G_ARRAY) {
2850         if (gimme != G_VOID)
2851             XPUSHs(boolSV(max));
2852         RETURN;
2853     }
2854     if (max) {
2855         EXTEND(SP, max);
2856         EXTEND_MORTAL(max);
2857         PUSHs(sv_2mortal(newSViv(PL_statcache.st_dev)));
2858         PUSHs(sv_2mortal(newSViv(PL_statcache.st_ino)));
2859         PUSHs(sv_2mortal(newSVuv(PL_statcache.st_mode)));
2860         PUSHs(sv_2mortal(newSVuv(PL_statcache.st_nlink)));
2861 #if Uid_t_size > IVSIZE
2862         PUSHs(sv_2mortal(newSVnv(PL_statcache.st_uid)));
2863 #else
2864 #   if Uid_t_sign <= 0
2865         PUSHs(sv_2mortal(newSViv(PL_statcache.st_uid)));
2866 #   else
2867         PUSHs(sv_2mortal(newSVuv(PL_statcache.st_uid)));
2868 #   endif
2869 #endif
2870 #if Gid_t_size > IVSIZE
2871         PUSHs(sv_2mortal(newSVnv(PL_statcache.st_gid)));
2872 #else
2873 #   if Gid_t_sign <= 0
2874         PUSHs(sv_2mortal(newSViv(PL_statcache.st_gid)));
2875 #   else
2876         PUSHs(sv_2mortal(newSVuv(PL_statcache.st_gid)));
2877 #   endif
2878 #endif
2879 #ifdef USE_STAT_RDEV
2880         PUSHs(sv_2mortal(newSViv(PL_statcache.st_rdev)));
2881 #else
2882         PUSHs(sv_2mortal(newSVpvn("", 0)));
2883 #endif
2884 #if Off_t_size > IVSIZE
2885         PUSHs(sv_2mortal(newSVnv((NV)PL_statcache.st_size)));
2886 #else
2887         PUSHs(sv_2mortal(newSViv(PL_statcache.st_size)));
2888 #endif
2889 #ifdef BIG_TIME
2890         PUSHs(sv_2mortal(newSVnv(PL_statcache.st_atime)));
2891         PUSHs(sv_2mortal(newSVnv(PL_statcache.st_mtime)));
2892         PUSHs(sv_2mortal(newSVnv(PL_statcache.st_ctime)));
2893 #else
2894         PUSHs(sv_2mortal(newSViv(PL_statcache.st_atime)));
2895         PUSHs(sv_2mortal(newSViv(PL_statcache.st_mtime)));
2896         PUSHs(sv_2mortal(newSViv(PL_statcache.st_ctime)));
2897 #endif
2898 #ifdef USE_STAT_BLOCKS
2899         PUSHs(sv_2mortal(newSVuv(PL_statcache.st_blksize)));
2900         PUSHs(sv_2mortal(newSVuv(PL_statcache.st_blocks)));
2901 #else
2902         PUSHs(sv_2mortal(newSVpvn("", 0)));
2903         PUSHs(sv_2mortal(newSVpvn("", 0)));
2904 #endif
2905     }
2906     RETURN;
2907 }
2908
2909 /* This macro is used by the stacked filetest operators :
2910  * if the previous filetest failed, short-circuit and pass its value.
2911  * Else, discard it from the stack and continue. --rgs
2912  */
2913 #define STACKED_FTEST_CHECK if (PL_op->op_private & OPpFT_STACKED) { \
2914         if (TOPs == &PL_sv_no || TOPs == &PL_sv_undef) { RETURN; } \
2915         else { (void)POPs; PUTBACK; } \
2916     }
2917
2918 PP(pp_ftrread)
2919 {
2920     I32 result;
2921     dSP;
2922     STACKED_FTEST_CHECK;
2923 #if defined(HAS_ACCESS) && defined(R_OK)
2924     if ((PL_op->op_private & OPpFT_ACCESS) && SvPOK(TOPs)) {
2925         result = access(POPpx, R_OK);
2926         if (result == 0)
2927             RETPUSHYES;
2928         if (result < 0)
2929             RETPUSHUNDEF;
2930         RETPUSHNO;
2931     }
2932     else
2933         result = my_stat();
2934 #else
2935     result = my_stat();
2936 #endif
2937     SPAGAIN;
2938     if (result < 0)
2939         RETPUSHUNDEF;
2940     if (cando(S_IRUSR, 0, &PL_statcache))
2941         RETPUSHYES;
2942     RETPUSHNO;
2943 }
2944
2945 PP(pp_ftrwrite)
2946 {
2947     I32 result;
2948     dSP;
2949     STACKED_FTEST_CHECK;
2950 #if defined(HAS_ACCESS) && defined(W_OK)
2951     if ((PL_op->op_private & OPpFT_ACCESS) && SvPOK(TOPs)) {
2952         result = access(POPpx, W_OK);
2953         if (result == 0)
2954             RETPUSHYES;
2955         if (result < 0)
2956             RETPUSHUNDEF;
2957         RETPUSHNO;
2958     }
2959     else
2960         result = my_stat();
2961 #else
2962     result = my_stat();
2963 #endif
2964     SPAGAIN;
2965     if (result < 0)
2966         RETPUSHUNDEF;
2967     if (cando(S_IWUSR, 0, &PL_statcache))
2968         RETPUSHYES;
2969     RETPUSHNO;
2970 }
2971
2972 PP(pp_ftrexec)
2973 {
2974     I32 result;
2975     dSP;
2976     STACKED_FTEST_CHECK;
2977 #if defined(HAS_ACCESS) && defined(X_OK)
2978     if ((PL_op->op_private & OPpFT_ACCESS) && SvPOK(TOPs)) {
2979         result = access(POPpx, X_OK);
2980         if (result == 0)
2981             RETPUSHYES;
2982         if (result < 0)
2983             RETPUSHUNDEF;
2984         RETPUSHNO;
2985     }
2986     else
2987         result = my_stat();
2988 #else
2989     result = my_stat();
2990 #endif
2991     SPAGAIN;
2992     if (result < 0)
2993         RETPUSHUNDEF;
2994     if (cando(S_IXUSR, 0, &PL_statcache))
2995         RETPUSHYES;
2996     RETPUSHNO;
2997 }
2998
2999 PP(pp_fteread)
3000 {
3001     I32 result;
3002     dSP;
3003     STACKED_FTEST_CHECK;
3004 #ifdef PERL_EFF_ACCESS_R_OK
3005     if ((PL_op->op_private & OPpFT_ACCESS) && SvPOK(TOPs)) {
3006         result = PERL_EFF_ACCESS_R_OK(POPpx);
3007         if (result == 0)
3008             RETPUSHYES;
3009         if (result < 0)
3010             RETPUSHUNDEF;
3011         RETPUSHNO;
3012     }
3013     else
3014         result = my_stat();
3015 #else
3016     result = my_stat();
3017 #endif
3018     SPAGAIN;
3019     if (result < 0)
3020         RETPUSHUNDEF;
3021     if (cando(S_IRUSR, 1, &PL_statcache))
3022         RETPUSHYES;
3023     RETPUSHNO;
3024 }
3025
3026 PP(pp_ftewrite)
3027 {
3028     I32 result;
3029     dSP;
3030     STACKED_FTEST_CHECK;
3031 #ifdef PERL_EFF_ACCESS_W_OK
3032     if ((PL_op->op_private & OPpFT_ACCESS) && SvPOK(TOPs)) {
3033         result = PERL_EFF_ACCESS_W_OK(POPpx);
3034         if (result == 0)
3035             RETPUSHYES;
3036         if (result < 0)
3037             RETPUSHUNDEF;
3038         RETPUSHNO;
3039     }
3040     else
3041         result = my_stat();
3042 #else
3043     result = my_stat();
3044 #endif
3045     SPAGAIN;
3046     if (result < 0)
3047         RETPUSHUNDEF;
3048     if (cando(S_IWUSR, 1, &PL_statcache))
3049         RETPUSHYES;
3050     RETPUSHNO;
3051 }
3052
3053 PP(pp_fteexec)
3054 {
3055     I32 result;
3056     dSP;
3057     STACKED_FTEST_CHECK;
3058 #ifdef PERL_EFF_ACCESS_X_OK
3059     if ((PL_op->op_private & OPpFT_ACCESS) && SvPOK(TOPs)) {
3060         result = PERL_EFF_ACCESS_X_OK(POPpx);
3061         if (result == 0)
3062             RETPUSHYES;
3063         if (result < 0)
3064             RETPUSHUNDEF;
3065         RETPUSHNO;
3066     }
3067     else
3068         result = my_stat();
3069 #else
3070     result = my_stat();
3071 #endif
3072     SPAGAIN;
3073     if (result < 0)
3074         RETPUSHUNDEF;
3075     if (cando(S_IXUSR, 1, &PL_statcache))
3076         RETPUSHYES;
3077     RETPUSHNO;
3078 }
3079
3080 PP(pp_ftis)
3081 {
3082     I32 result;
3083     dSP;
3084     STACKED_FTEST_CHECK;
3085     result = my_stat();
3086     SPAGAIN;
3087     if (result < 0)
3088         RETPUSHUNDEF;
3089     RETPUSHYES;
3090 }
3091
3092 PP(pp_fteowned)
3093 {
3094     return pp_ftrowned();
3095 }
3096
3097 PP(pp_ftrowned)
3098 {
3099     I32 result;
3100     dSP;
3101     STACKED_FTEST_CHECK;
3102     result = my_stat();
3103     SPAGAIN;
3104     if (result < 0)
3105         RETPUSHUNDEF;
3106     if (PL_statcache.st_uid == (PL_op->op_type == OP_FTEOWNED ?
3107                                 PL_euid : PL_uid) )
3108         RETPUSHYES;
3109     RETPUSHNO;
3110 }
3111
3112 PP(pp_ftzero)
3113 {
3114     I32 result;
3115     dSP;
3116     STACKED_FTEST_CHECK;
3117     result = my_stat();
3118     SPAGAIN;
3119     if (result < 0)
3120         RETPUSHUNDEF;
3121     if (PL_statcache.st_size == 0)
3122         RETPUSHYES;
3123     RETPUSHNO;
3124 }
3125
3126 PP(pp_ftsize)
3127 {
3128     I32 result;
3129     dSP; dTARGET;
3130     STACKED_FTEST_CHECK;
3131     result = my_stat();
3132     SPAGAIN;
3133     if (result < 0)
3134         RETPUSHUNDEF;
3135 #if Off_t_size > IVSIZE
3136     PUSHn(PL_statcache.st_size);
3137 #else
3138     PUSHi(PL_statcache.st_size);
3139 #endif
3140     RETURN;
3141 }
3142
3143 PP(pp_ftmtime)
3144 {
3145     I32 result;
3146     dSP; dTARGET;
3147     STACKED_FTEST_CHECK;
3148     result = my_stat();
3149     SPAGAIN;
3150     if (result < 0)
3151         RETPUSHUNDEF;
3152     PUSHn( (((NV)PL_basetime - PL_statcache.st_mtime)) / 86400.0 );
3153     RETURN;
3154 }
3155
3156 PP(pp_ftatime)
3157 {
3158     I32 result;
3159     dSP; dTARGET;
3160     STACKED_FTEST_CHECK;
3161     result = my_stat();
3162     SPAGAIN;
3163     if (result < 0)
3164         RETPUSHUNDEF;
3165     PUSHn( (((NV)PL_basetime - PL_statcache.st_atime)) / 86400.0 );
3166     RETURN;
3167 }
3168
3169 PP(pp_ftctime)
3170 {
3171     I32 result;
3172     dSP; dTARGET;
3173     STACKED_FTEST_CHECK;
3174     result = my_stat();
3175     SPAGAIN;
3176     if (result < 0)
3177         RETPUSHUNDEF;
3178     PUSHn( (((NV)PL_basetime - PL_statcache.st_ctime)) / 86400.0 );
3179     RETURN;
3180 }
3181
3182 PP(pp_ftsock)
3183 {
3184     I32 result;
3185     dSP;
3186     STACKED_FTEST_CHECK;
3187     result = my_stat();
3188     SPAGAIN;
3189     if (result < 0)
3190         RETPUSHUNDEF;
3191     if (S_ISSOCK(PL_statcache.st_mode))
3192         RETPUSHYES;
3193     RETPUSHNO;
3194 }
3195
3196 PP(pp_ftchr)
3197 {
3198     I32 result;
3199     dSP;
3200     STACKED_FTEST_CHECK;
3201     result = my_stat();
3202     SPAGAIN;
3203     if (result < 0)
3204         RETPUSHUNDEF;
3205     if (S_ISCHR(PL_statcache.st_mode))
3206         RETPUSHYES;
3207     RETPUSHNO;
3208 }
3209
3210 PP(pp_ftblk)
3211 {
3212     I32 result;
3213     dSP;
3214     STACKED_FTEST_CHECK;
3215     result = my_stat();
3216     SPAGAIN;
3217     if (result < 0)
3218         RETPUSHUNDEF;
3219     if (S_ISBLK(PL_statcache.st_mode))
3220         RETPUSHYES;
3221     RETPUSHNO;
3222 }
3223
3224 PP(pp_ftfile)
3225 {
3226     I32 result;
3227     dSP;
3228     STACKED_FTEST_CHECK;
3229     result = my_stat();
3230     SPAGAIN;
3231     if (result < 0)
3232         RETPUSHUNDEF;
3233     if (S_ISREG(PL_statcache.st_mode))
3234         RETPUSHYES;
3235     RETPUSHNO;
3236 }
3237
3238 PP(pp_ftdir)
3239 {
3240     I32 result;
3241     dSP;
3242     STACKED_FTEST_CHECK;
3243     result = my_stat();
3244     SPAGAIN;
3245     if (result < 0)
3246         RETPUSHUNDEF;
3247     if (S_ISDIR(PL_statcache.st_mode))
3248         RETPUSHYES;
3249     RETPUSHNO;
3250 }
3251
3252 PP(pp_ftpipe)
3253 {
3254     I32 result;
3255     dSP;
3256     STACKED_FTEST_CHECK;
3257     result = my_stat();
3258     SPAGAIN;
3259     if (result < 0)
3260         RETPUSHUNDEF;
3261     if (S_ISFIFO(PL_statcache.st_mode))
3262         RETPUSHYES;
3263     RETPUSHNO;
3264 }
3265
3266 PP(pp_ftlink)
3267 {
3268     I32 result = my_lstat();
3269     dSP;
3270     if (result < 0)
3271         RETPUSHUNDEF;
3272     if (S_ISLNK(PL_statcache.st_mode))
3273         RETPUSHYES;
3274     RETPUSHNO;
3275 }
3276
3277 PP(pp_ftsuid)
3278 {
3279     dSP;
3280 #ifdef S_ISUID
3281     I32 result;
3282     STACKED_FTEST_CHECK;
3283     result = my_stat();
3284     SPAGAIN;
3285     if (result < 0)
3286         RETPUSHUNDEF;
3287     if (PL_statcache.st_mode & S_ISUID)
3288         RETPUSHYES;
3289 #endif
3290     RETPUSHNO;
3291 }
3292
3293 PP(pp_ftsgid)
3294 {
3295     dSP;
3296 #ifdef S_ISGID
3297     I32 result;
3298     STACKED_FTEST_CHECK;
3299     result = my_stat();
3300     SPAGAIN;
3301     if (result < 0)
3302         RETPUSHUNDEF;
3303     if (PL_statcache.st_mode & S_ISGID)
3304         RETPUSHYES;
3305 #endif
3306     RETPUSHNO;
3307 }
3308
3309 PP(pp_ftsvtx)
3310 {
3311     dSP;
3312 #ifdef S_ISVTX
3313     I32 result;
3314     STACKED_FTEST_CHECK;
3315     result = my_stat();
3316     SPAGAIN;
3317     if (result < 0)
3318         RETPUSHUNDEF;
3319     if (PL_statcache.st_mode & S_ISVTX)
3320         RETPUSHYES;
3321 #endif
3322     RETPUSHNO;
3323 }
3324
3325 PP(pp_fttty)
3326 {
3327     dSP;
3328     int fd;
3329     GV *gv;
3330     SV *tmpsv = Nullsv;
3331
3332     STACKED_FTEST_CHECK;
3333
3334     if (PL_op->op_flags & OPf_REF)
3335         gv = cGVOP_gv;
3336     else if (isGV(TOPs))
3337         gv = (GV*)POPs;
3338     else if (SvROK(TOPs) && isGV(SvRV(TOPs)))
3339         gv = (GV*)SvRV(POPs);
3340     else
3341         gv = gv_fetchsv(tmpsv = POPs, FALSE, SVt_PVIO);
3342
3343     if (GvIO(gv) && IoIFP(GvIOp(gv)))
3344         fd = PerlIO_fileno(IoIFP(GvIOp(gv)));
3345     else if (tmpsv && SvOK(tmpsv)) {
3346         const char *tmps = SvPV_nolen_const(tmpsv);
3347         if (isDIGIT(*tmps))
3348             fd = atoi(tmps);
3349         else 
3350             RETPUSHUNDEF;
3351     }
3352     else
3353         RETPUSHUNDEF;
3354     if (PerlLIO_isatty(fd))
3355         RETPUSHYES;
3356     RETPUSHNO;
3357 }
3358
3359 #if defined(atarist) /* this will work with atariST. Configure will
3360                         make guesses for other systems. */
3361 # define FILE_base(f) ((f)->_base)
3362 # define FILE_ptr(f) ((f)->_ptr)
3363 # define FILE_cnt(f) ((f)->_cnt)
3364 # define FILE_bufsiz(f) ((f)->_cnt + ((f)->_ptr - (f)->_base))
3365 #endif
3366
3367 PP(pp_fttext)
3368 {
3369     dSP;
3370     I32 i;
3371     I32 len;
3372     I32 odd = 0;
3373     STDCHAR tbuf[512];
3374     register STDCHAR *s;
3375     register IO *io;
3376     register SV *sv;
3377     GV *gv;
3378     PerlIO *fp;
3379
3380     STACKED_FTEST_CHECK;
3381
3382     if (PL_op->op_flags & OPf_REF)
3383         gv = cGVOP_gv;
3384     else if (isGV(TOPs))
3385         gv = (GV*)POPs;
3386     else if (SvROK(TOPs) && isGV(SvRV(TOPs)))
3387         gv = (GV*)SvRV(POPs);
3388     else
3389         gv = Nullgv;
3390
3391     if (gv) {
3392         EXTEND(SP, 1);
3393         if (gv == PL_defgv) {
3394             if (PL_statgv)
3395                 io = GvIO(PL_statgv);
3396             else {
3397                 sv = PL_statname;
3398                 goto really_filename;
3399             }
3400         }
3401         else {
3402             PL_statgv = gv;
3403             PL_laststatval = -1;
3404             sv_setpvn(PL_statname, "", 0);
3405             io = GvIO(PL_statgv);
3406         }
3407         if (io && IoIFP(io)) {
3408             if (! PerlIO_has_base(IoIFP(io)))
3409                 DIE(aTHX_ "-T and -B not implemented on filehandles");
3410             PL_laststatval = PerlLIO_fstat(PerlIO_fileno(IoIFP(io)), &PL_statcache);
3411             if (PL_laststatval < 0)
3412                 RETPUSHUNDEF;
3413             if (S_ISDIR(PL_statcache.st_mode)) { /* handle NFS glitch */
3414                 if (PL_op->op_type == OP_FTTEXT)
3415                     RETPUSHNO;
3416                 else
3417                     RETPUSHYES;
3418             }
3419             if (PerlIO_get_cnt(IoIFP(io)) <= 0) {
3420                 i = PerlIO_getc(IoIFP(io));
3421                 if (i != EOF)
3422                     (void)PerlIO_ungetc(IoIFP(io),i);
3423             }
3424             if (PerlIO_get_cnt(IoIFP(io)) <= 0) /* null file is anything */
3425                 RETPUSHYES;
3426             len = PerlIO_get_bufsiz(IoIFP(io));
3427             s = (STDCHAR *) PerlIO_get_base(IoIFP(io));
3428             /* sfio can have large buffers - limit to 512 */
3429             if (len > 512)
3430                 len = 512;
3431         }
3432         else {
3433             if (ckWARN2(WARN_UNOPENED,WARN_CLOSED)) {
3434                 gv = cGVOP_gv;
3435                 report_evil_fh(gv, GvIO(gv), PL_op->op_type);
3436             }
3437             SETERRNO(EBADF,RMS_IFI);
3438             RETPUSHUNDEF;
3439         }
3440     }
3441     else {
3442         sv = POPs;
3443       really_filename:
3444         PL_statgv = Nullgv;
3445         PL_laststype = OP_STAT;
3446         sv_setpv(PL_statname, SvPV_nolen_const(sv));
3447         if (!(fp = PerlIO_open(SvPVX_const(PL_statname), "r"))) {
3448             if (ckWARN(WARN_NEWLINE) && strchr(SvPV_nolen_const(PL_statname),
3449                                                '\n'))
3450                 Perl_warner(aTHX_ packWARN(WARN_NEWLINE), PL_warn_nl, "open");
3451             RETPUSHUNDEF;
3452         }
3453         PL_laststatval = PerlLIO_fstat(PerlIO_fileno(fp), &PL_statcache);
3454         if (PL_laststatval < 0) {
3455             (void)PerlIO_close(fp);
3456             RETPUSHUNDEF;
3457         }
3458         PerlIO_binmode(aTHX_ fp, '<', O_BINARY, Nullch);
3459         len = PerlIO_read(fp, tbuf, sizeof(tbuf));
3460         (void)PerlIO_close(fp);
3461         if (len <= 0) {
3462             if (S_ISDIR(PL_statcache.st_mode) && PL_op->op_type == OP_FTTEXT)
3463                 RETPUSHNO;              /* special case NFS directories */
3464             RETPUSHYES;         /* null file is anything */
3465         }
3466         s = tbuf;
3467     }
3468
3469     /* now scan s to look for textiness */
3470     /*   XXX ASCII dependent code */
3471
3472 #if defined(DOSISH) || defined(USEMYBINMODE)
3473     /* ignore trailing ^Z on short files */
3474     if (len && len < sizeof(tbuf) && tbuf[len-1] == 26)
3475         --len;
3476 #endif
3477
3478     for (i = 0; i < len; i++, s++) {
3479         if (!*s) {                      /* null never allowed in text */
3480             odd += len;
3481             break;
3482         }
3483 #ifdef EBCDIC
3484         else if (!(isPRINT(*s) || isSPACE(*s)))
3485             odd++;
3486 #else
3487         else if (*s & 128) {
3488 #ifdef USE_LOCALE
3489             if (IN_LOCALE_RUNTIME && isALPHA_LC(*s))
3490                 continue;
3491 #endif
3492             /* utf8 characters don't count as odd */
3493             if (UTF8_IS_START(*s)) {
3494                 int ulen = UTF8SKIP(s);
3495                 if (ulen < len - i) {
3496                     int j;
3497                     for (j = 1; j < ulen; j++) {
3498                         if (!UTF8_IS_CONTINUATION(s[j]))
3499                             goto not_utf8;
3500                     }
3501                     --ulen;     /* loop does extra increment */
3502                     s += ulen;
3503                     i += ulen;
3504                     continue;
3505                 }
3506             }
3507           not_utf8:
3508             odd++;
3509         }
3510         else if (*s < 32 &&
3511           *s != '\n' && *s != '\r' && *s != '\b' &&
3512           *s != '\t' && *s != '\f' && *s != 27)
3513             odd++;
3514 #endif
3515     }
3516
3517     if ((odd * 3 > len) == (PL_op->op_type == OP_FTTEXT)) /* allow 1/3 odd */
3518         RETPUSHNO;
3519     else
3520         RETPUSHYES;
3521 }
3522
3523 PP(pp_ftbinary)
3524 {
3525     return pp_fttext();
3526 }
3527
3528 /* File calls. */
3529
3530 PP(pp_chdir)
3531 {
3532     dSP; dTARGET;
3533     const char *tmps;
3534     SV **svp;
3535
3536     if( MAXARG == 1 )
3537         tmps = POPpconstx;
3538     else
3539         tmps = 0;
3540
3541     if( !tmps || !*tmps ) {
3542         if (    (svp = hv_fetch(GvHVn(PL_envgv), "HOME", 4, FALSE))
3543              || (svp = hv_fetch(GvHVn(PL_envgv), "LOGDIR", 6, FALSE))
3544 #ifdef VMS
3545              || (svp = hv_fetch(GvHVn(PL_envgv), "SYS$LOGIN", 9, FALSE))
3546 #endif
3547            )
3548         {
3549             if( MAXARG == 1 )
3550                 deprecate("chdir('') or chdir(undef) as chdir()");
3551             tmps = SvPV_nolen_const(*svp);
3552         }
3553         else {
3554             PUSHi(0);
3555             TAINT_PROPER("chdir");
3556             RETURN;
3557         }
3558     }
3559
3560     TAINT_PROPER("chdir");
3561     PUSHi( PerlDir_chdir(tmps) >= 0 );
3562 #ifdef VMS
3563     /* Clear the DEFAULT element of ENV so we'll get the new value
3564      * in the future. */
3565     hv_delete(GvHVn(PL_envgv),"DEFAULT",7,G_DISCARD);
3566 #endif
3567     RETURN;
3568 }
3569
3570 PP(pp_chown)
3571 {
3572 #ifdef HAS_CHOWN
3573     dSP; dMARK; dTARGET;
3574     I32 value = (I32)apply(PL_op->op_type, MARK, SP);
3575
3576     SP = MARK;
3577     PUSHi(value);
3578     RETURN;
3579 #else
3580     DIE(aTHX_ PL_no_func, "chown");
3581 #endif
3582 }
3583
3584 PP(pp_chroot)
3585 {
3586 #ifdef HAS_CHROOT
3587     dSP; dTARGET;
3588     char *tmps = POPpx;
3589     TAINT_PROPER("chroot");
3590     PUSHi( chroot(tmps) >= 0 );
3591     RETURN;
3592 #else
3593     DIE(aTHX_ PL_no_func, "chroot");
3594 #endif
3595 }
3596
3597 PP(pp_unlink)
3598 {
3599     dSP; dMARK; dTARGET;
3600     I32 value;
3601     value = (I32)apply(PL_op->op_type, MARK, SP);
3602     SP = MARK;
3603     PUSHi(value);
3604     RETURN;
3605 }
3606
3607 PP(pp_chmod)
3608 {
3609     dSP; dMARK; dTARGET;
3610     I32 value;
3611     value = (I32)apply(PL_op->op_type, MARK, SP);
3612     SP = MARK;
3613     PUSHi(value);
3614     RETURN;
3615 }
3616
3617 PP(pp_utime)
3618 {
3619     dSP; dMARK; dTARGET;
3620     I32 value;
3621     value = (I32)apply(PL_op->op_type, MARK, SP);
3622     SP = MARK;
3623     PUSHi(value);
3624     RETURN;
3625 }
3626
3627 PP(pp_rename)
3628 {
3629     dSP; dTARGET;
3630     int anum;
3631     const char *tmps2 = POPpconstx;
3632     const char *tmps = SvPV_nolen_const(TOPs);
3633     TAINT_PROPER("rename");
3634 #ifdef HAS_RENAME
3635     anum = PerlLIO_rename(tmps, tmps2);
3636 #else
3637     if (!(anum = PerlLIO_stat(tmps, &PL_statbuf))) {
3638         if (same_dirent(tmps2, tmps))   /* can always rename to same name */
3639             anum = 1;
3640         else {
3641             if (PL_euid || PerlLIO_stat(tmps2, &PL_statbuf) < 0 || !S_ISDIR(PL_statbuf.st_mode))
3642                 (void)UNLINK(tmps2);
3643             if (!(anum = link(tmps, tmps2)))
3644                 anum = UNLINK(tmps);
3645         }
3646     }
3647 #endif
3648     SETi( anum >= 0 );
3649     RETURN;
3650 }
3651
3652 PP(pp_link)
3653 {
3654 #ifdef HAS_LINK
3655     dSP; dTARGET;
3656     const char *tmps2 = POPpconstx;
3657     const char *tmps = SvPV_nolen_const(TOPs);
3658     TAINT_PROPER("link");
3659     SETi( PerlLIO_link(tmps, tmps2) >= 0 );
3660     RETURN;
3661 #else
3662     DIE(aTHX_ PL_no_func, "link");
3663 #endif
3664 }
3665
3666 PP(pp_symlink)
3667 {
3668 #ifdef HAS_SYMLINK
3669     dSP; dTARGET;
3670     const char *tmps2 = POPpconstx;
3671     const char *tmps = SvPV_nolen_const(TOPs);
3672     TAINT_PROPER("symlink");
3673     SETi( symlink(tmps, tmps2) >= 0 );
3674     RETURN;
3675 #else
3676     DIE(aTHX_ PL_no_func, "symlink");
3677 #endif
3678 }
3679
3680 PP(pp_readlink)
3681 {
3682     dSP;
3683 #ifdef HAS_SYMLINK
3684     dTARGET;
3685     const char *tmps;
3686     char buf[MAXPATHLEN];
3687     int len;
3688
3689 #ifndef INCOMPLETE_TAINTS
3690     TAINT;
3691 #endif
3692     tmps = POPpconstx;
3693     len = readlink(tmps, buf, sizeof(buf) - 1);
3694     EXTEND(SP, 1);
3695     if (len < 0)
3696         RETPUSHUNDEF;
3697     PUSHp(buf, len);
3698     RETURN;
3699 #else
3700     EXTEND(SP, 1);
3701     RETSETUNDEF;                /* just pretend it's a normal file */
3702 #endif
3703 }
3704
3705 #if !defined(HAS_MKDIR) || !defined(HAS_RMDIR)
3706 STATIC int
3707 S_dooneliner(pTHX_ const char *cmd, const char *filename)
3708 {
3709     char * const save_filename = filename;
3710     char *cmdline;
3711     char *s;
3712     PerlIO *myfp;
3713     int anum = 1;
3714
3715     New(666, cmdline, strlen(cmd) + (strlen(filename) * 2) + 10, char);
3716     strcpy(cmdline, cmd);
3717     strcat(cmdline, " ");
3718     for (s = cmdline + strlen(cmdline); *filename; ) {
3719         *s++ = '\\';
3720         *s++ = *filename++;
3721     }
3722     strcpy(s, " 2>&1");
3723     myfp = PerlProc_popen(cmdline, "r");
3724     Safefree(cmdline);
3725
3726     if (myfp) {
3727         SV *tmpsv = sv_newmortal();
3728         /* Need to save/restore 'PL_rs' ?? */
3729         s = sv_gets(tmpsv, myfp, 0);
3730         (void)PerlProc_pclose(myfp);
3731         if (s != Nullch) {
3732             int e;
3733             for (e = 1;
3734 #ifdef HAS_SYS_ERRLIST
3735                  e <= sys_nerr
3736 #endif
3737                  ; e++)
3738             {
3739                 /* you don't see this */
3740                 char *errmsg =
3741 #ifdef HAS_SYS_ERRLIST
3742                     sys_errlist[e]
3743 #else
3744                     strerror(e)
3745 #endif
3746                     ;
3747                 if (!errmsg)
3748                     break;
3749                 if (instr(s, errmsg)) {
3750                     SETERRNO(e,0);
3751                     return 0;
3752                 }
3753             }
3754             SETERRNO(0,0);
3755 #ifndef EACCES
3756 #define EACCES EPERM
3757 #endif
3758             if (instr(s, "cannot make"))
3759                 SETERRNO(EEXIST,RMS_FEX);
3760             else if (instr(s, "existing file"))
3761                 SETERRNO(EEXIST,RMS_FEX);
3762             else if (instr(s, "ile exists"))
3763                 SETERRNO(EEXIST,RMS_FEX);
3764             else if (instr(s, "non-exist"))
3765                 SETERRNO(ENOENT,RMS_FNF);
3766             else if (instr(s, "does not exist"))
3767                 SETERRNO(ENOENT,RMS_FNF);
3768             else if (instr(s, "not empty"))
3769                 SETERRNO(EBUSY,SS_DEVOFFLINE);
3770             else if (instr(s, "cannot access"))
3771                 SETERRNO(EACCES,RMS_PRV);
3772             else
3773                 SETERRNO(EPERM,RMS_PRV);
3774             return 0;
3775         }
3776         else {  /* some mkdirs return no failure indication */
3777             anum = (PerlLIO_stat(save_filename, &PL_statbuf) >= 0);
3778             if (PL_op->op_type == OP_RMDIR)
3779                 anum = !anum;
3780             if (anum)
3781                 SETERRNO(0,0);
3782             else
3783                 SETERRNO(EACCES,RMS_PRV);       /* a guess */
3784         }
3785         return anum;
3786     }
3787     else
3788         return 0;
3789 }
3790 #endif
3791
3792 /* This macro removes trailing slashes from a directory name.
3793  * Different operating and file systems take differently to
3794  * trailing slashes.  According to POSIX 1003.1 1996 Edition
3795  * any number of trailing slashes should be allowed.
3796  * Thusly we snip them away so that even non-conforming
3797  * systems are happy.
3798  * We should probably do this "filtering" for all
3799  * the functions that expect (potentially) directory names:
3800  * -d, chdir(), chmod(), chown(), chroot(), fcntl()?,
3801  * (mkdir()), opendir(), rename(), rmdir(), stat(). --jhi */
3802
3803 #define TRIMSLASHES(tmps,len,copy) (tmps) = SvPV_const(TOPs, (len)); \
3804     if ((len) > 1 && (tmps)[(len)-1] == '/') { \
3805         do { \
3806             (len)--; \
3807         } while ((len) > 1 && (tmps)[(len)-1] == '/'); \
3808         (tmps) = savepvn((tmps), (len)); \
3809         (copy) = TRUE; \
3810     }
3811
3812 PP(pp_mkdir)
3813 {
3814     dSP; dTARGET;
3815     int mode;
3816 #ifndef HAS_MKDIR
3817     int oldumask;
3818 #endif
3819     STRLEN len;
3820     const char *tmps;
3821     bool copy = FALSE;
3822
3823     if (MAXARG > 1)
3824         mode = POPi;
3825     else
3826         mode = 0777;
3827
3828     TRIMSLASHES(tmps,len,copy);
3829
3830     TAINT_PROPER("mkdir");
3831 #ifdef HAS_MKDIR
3832     SETi( PerlDir_mkdir(tmps, mode) >= 0 );
3833 #else
3834     SETi( dooneliner("mkdir", tmps) );
3835     oldumask = PerlLIO_umask(0);
3836     PerlLIO_umask(oldumask);
3837     PerlLIO_chmod(tmps, (mode & ~oldumask) & 0777);
3838 #endif
3839     if (copy)
3840         Safefree(tmps);
3841     RETURN;
3842 }
3843
3844 PP(pp_rmdir)
3845 {
3846     dSP; dTARGET;
3847     STRLEN len;
3848     const char *tmps;
3849     bool copy = FALSE;
3850
3851     TRIMSLASHES(tmps,len,copy);
3852     TAINT_PROPER("rmdir");
3853 #ifdef HAS_RMDIR
3854     SETi( PerlDir_rmdir(tmps) >= 0 );
3855 #else
3856     SETi( dooneliner("rmdir", tmps) );
3857 #endif
3858     if (copy)
3859         Safefree(tmps);
3860     RETURN;
3861 }
3862
3863 /* Directory calls. */
3864
3865 PP(pp_open_dir)
3866 {
3867 #if defined(Direntry_t) && defined(HAS_READDIR)
3868     dSP;
3869     const char *dirname = POPpconstx;
3870     GV *gv = (GV*)POPs;
3871     register IO *io = GvIOn(gv);
3872
3873     if (!io)
3874         goto nope;
3875
3876     if (IoDIRP(io))
3877         PerlDir_close(IoDIRP(io));
3878     if (!(IoDIRP(io) = PerlDir_open(dirname)))
3879         goto nope;
3880
3881     RETPUSHYES;
3882 nope:
3883     if (!errno)
3884         SETERRNO(EBADF,RMS_DIR);
3885     RETPUSHUNDEF;
3886 #else
3887     DIE(aTHX_ PL_no_dir_func, "opendir");
3888 #endif
3889 }
3890
3891 PP(pp_readdir)
3892 {
3893 #if !defined(Direntry_t) || !defined(HAS_READDIR)
3894     DIE(aTHX_ PL_no_dir_func, "readdir");
3895 #else
3896 #if !defined(I_DIRENT) && !defined(VMS)
3897     Direntry_t *readdir (DIR *);
3898 #endif
3899     dSP;
3900
3901     SV *sv;
3902     const I32 gimme = GIMME;
3903     GV *gv = (GV *)POPs;
3904     register Direntry_t *dp;
3905     register IO *io = GvIOn(gv);
3906
3907     if (!io || !IoDIRP(io))
3908         goto nope;
3909
3910     do {
3911         dp = (Direntry_t *)PerlDir_read(IoDIRP(io));
3912         if (!dp)
3913             break;
3914 #ifdef DIRNAMLEN
3915         sv = newSVpvn(dp->d_name, dp->d_namlen);
3916 #else
3917         sv = newSVpv(dp->d_name, 0);
3918 #endif
3919 #ifndef INCOMPLETE_TAINTS
3920         if (!(IoFLAGS(io) & IOf_UNTAINT))
3921             SvTAINTED_on(sv);
3922 #endif
3923         XPUSHs(sv_2mortal(sv));
3924     }
3925     while (gimme == G_ARRAY);
3926
3927     if (!dp && gimme != G_ARRAY)
3928         goto nope;
3929
3930     RETURN;
3931
3932 nope:
3933     if (!errno)
3934         SETERRNO(EBADF,RMS_ISI);
3935     if (GIMME == G_ARRAY)
3936         RETURN;
3937     else
3938         RETPUSHUNDEF;
3939 #endif
3940 }
3941
3942 PP(pp_telldir)
3943 {
3944 #if defined(HAS_TELLDIR) || defined(telldir)
3945     dVAR; dSP; dTARGET;
3946  /* XXX does _anyone_ need this? --AD 2/20/1998 */
3947  /* XXX netbsd still seemed to.
3948     XXX HAS_TELLDIR_PROTO is new style, NEED_TELLDIR_PROTO is old style.
3949     --JHI 1999-Feb-02 */
3950 # if !defined(HAS_TELLDIR_PROTO) || defined(NEED_TELLDIR_PROTO)
3951     long telldir (DIR *);
3952 # endif
3953     GV *gv = (GV*)POPs;
3954     register IO *io = GvIOn(gv);
3955
3956     if (!io || !IoDIRP(io))
3957         goto nope;
3958
3959     PUSHi( PerlDir_tell(IoDIRP(io)) );
3960     RETURN;
3961 nope:
3962     if (!errno)
3963         SETERRNO(EBADF,RMS_ISI);
3964     RETPUSHUNDEF;
3965 #else
3966     DIE(aTHX_ PL_no_dir_func, "telldir");
3967 #endif
3968 }
3969
3970 PP(pp_seekdir)
3971 {
3972 #if defined(HAS_SEEKDIR) || defined(seekdir)
3973     dSP;
3974     long along = POPl;
3975     GV *gv = (GV*)POPs;
3976     register IO *io = GvIOn(gv);
3977
3978     if (!io || !IoDIRP(io))
3979         goto nope;
3980
3981     (void)PerlDir_seek(IoDIRP(io), along);
3982
3983     RETPUSHYES;
3984 nope:
3985     if (!errno)
3986         SETERRNO(EBADF,RMS_ISI);
3987     RETPUSHUNDEF;
3988 #else
3989     DIE(aTHX_ PL_no_dir_func, "seekdir");
3990 #endif
3991 }
3992
3993 PP(pp_rewinddir)
3994 {
3995 #if defined(HAS_REWINDDIR) || defined(rewinddir)
3996     dSP;
3997     GV *gv = (GV*)POPs;
3998     register IO *io = GvIOn(gv);
3999
4000     if (!io || !IoDIRP(io))
4001         goto nope;
4002
4003     (void)PerlDir_rewind(IoDIRP(io));
4004     RETPUSHYES;
4005 nope:
4006     if (!errno)
4007         SETERRNO(EBADF,RMS_ISI);
4008     RETPUSHUNDEF;
4009 #else
4010     DIE(aTHX_ PL_no_dir_func, "rewinddir");
4011 #endif
4012 }
4013
4014 PP(pp_closedir)
4015 {
4016 #if defined(Direntry_t) && defined(HAS_READDIR)
4017     dSP;
4018     GV *gv = (GV*)POPs;
4019     register IO *io = GvIOn(gv);
4020
4021     if (!io || !IoDIRP(io))
4022         goto nope;
4023
4024 #ifdef VOID_CLOSEDIR
4025     PerlDir_close(IoDIRP(io));
4026 #else
4027     if (PerlDir_close(IoDIRP(io)) < 0) {
4028         IoDIRP(io) = 0; /* Don't try to close again--coredumps on SysV */
4029         goto nope;
4030     }
4031 #endif
4032     IoDIRP(io) = 0;
4033
4034     RETPUSHYES;
4035 nope:
4036     if (!errno)
4037         SETERRNO(EBADF,RMS_IFI);
4038     RETPUSHUNDEF;
4039 #else
4040     DIE(aTHX_ PL_no_dir_func, "closedir");
4041 #endif
4042 }
4043
4044 /* Process control. */
4045
4046 PP(pp_fork)
4047 {
4048 #ifdef HAS_FORK
4049     dSP; dTARGET;
4050     Pid_t childpid;
4051     GV *tmpgv;
4052
4053     EXTEND(SP, 1);
4054     PERL_FLUSHALL_FOR_CHILD;
4055     childpid = PerlProc_fork();
4056     if (childpid < 0)
4057         RETSETUNDEF;
4058     if (!childpid) {
4059         if ((tmpgv = gv_fetchpv("$", TRUE, SVt_PV))) {
4060             SvREADONLY_off(GvSV(tmpgv));
4061             sv_setiv(GvSV(tmpgv), (IV)PerlProc_getpid());
4062             SvREADONLY_on(GvSV(tmpgv));
4063         }
4064 #ifdef THREADS_HAVE_PIDS
4065         PL_ppid = (IV)getppid();
4066 #endif
4067         hv_clear(PL_pidstatus); /* no kids, so don't wait for 'em */
4068     }
4069     PUSHi(childpid);
4070     RETURN;
4071 #else
4072 #  if defined(USE_ITHREADS) && defined(PERL_IMPLICIT_SYS)
4073     dSP; dTARGET;
4074     Pid_t childpid;
4075
4076     EXTEND(SP, 1);
4077     PERL_FLUSHALL_FOR_CHILD;
4078     childpid = PerlProc_fork();
4079     if (childpid == -1)
4080         RETSETUNDEF;
4081     PUSHi(childpid);
4082     RETURN;
4083 #  else
4084     DIE(aTHX_ PL_no_func, "fork");
4085 #  endif
4086 #endif
4087 }
4088
4089 PP(pp_wait)
4090 {
4091 #if (!defined(DOSISH) || defined(OS2) || defined(WIN32)) && !defined(MACOS_TRADITIONAL)
4092     dSP; dTARGET;
4093     Pid_t childpid;
4094     int argflags;
4095
4096     if (PL_signals & PERL_SIGNALS_UNSAFE_FLAG)
4097         childpid = wait4pid(-1, &argflags, 0);
4098     else {
4099         while ((childpid = wait4pid(-1, &argflags, 0)) == -1 &&
4100                errno == EINTR) {
4101           PERL_ASYNC_CHECK();
4102         }
4103     }
4104 #  if defined(USE_ITHREADS) && defined(PERL_IMPLICIT_SYS)
4105     /* 0 and -1 are both error returns (the former applies to WNOHANG case) */
4106     STATUS_NATIVE_SET((childpid && childpid != -1) ? argflags : -1);
4107 #  else
4108     STATUS_NATIVE_SET((childpid > 0) ? argflags : -1);
4109 #  endif
4110     XPUSHi(childpid);
4111     RETURN;
4112 #else
4113     DIE(aTHX_ PL_no_func, "wait");
4114 #endif
4115 }
4116
4117 PP(pp_waitpid)
4118 {
4119 #if (!defined(DOSISH) || defined(OS2) || defined(WIN32)) && !defined(MACOS_TRADITIONAL)
4120     dSP; dTARGET;
4121     Pid_t pid;
4122     Pid_t result;
4123     int optype;
4124     int argflags;
4125
4126     optype = POPi;
4127     pid = TOPi;
4128     if (PL_signals & PERL_SIGNALS_UNSAFE_FLAG)
4129         result = wait4pid(pid, &argflags, optype);
4130     else {
4131         while ((result = wait4pid(pid, &argflags, optype)) == -1 &&
4132                errno == EINTR) {
4133           PERL_ASYNC_CHECK();
4134         }
4135     }
4136 #  if defined(USE_ITHREADS) && defined(PERL_IMPLICIT_SYS)
4137     /* 0 and -1 are both error returns (the former applies to WNOHANG case) */
4138     STATUS_NATIVE_SET((result && result != -1) ? argflags : -1);
4139 #  else
4140     STATUS_NATIVE_SET((result > 0) ? argflags : -1);
4141 #  endif
4142     SETi(result);
4143     RETURN;
4144 #else
4145     DIE(aTHX_ PL_no_func, "waitpid");
4146 #endif
4147 }
4148
4149 PP(pp_system)
4150 {
4151     dSP; dMARK; dORIGMARK; dTARGET;
4152     I32 value;
4153     int result;
4154
4155     if (PL_tainting) {
4156         TAINT_ENV();
4157         while (++MARK <= SP) {
4158             (void)SvPV_nolen_const(*MARK);      /* stringify for taint check */
4159             if (PL_tainted)
4160                 break;
4161         }
4162         MARK = ORIGMARK;
4163         TAINT_PROPER("system");
4164     }
4165     PERL_FLUSHALL_FOR_CHILD;
4166 #if (defined(HAS_FORK) || defined(AMIGAOS)) && !defined(VMS) && !defined(OS2) || defined(PERL_MICRO)
4167     {
4168         Pid_t childpid;
4169         int pp[2];
4170         I32 did_pipes = 0;
4171
4172         if (PerlProc_pipe(pp) >= 0)
4173             did_pipes = 1;
4174         while ((childpid = PerlProc_fork()) == -1) {
4175             if (errno != EAGAIN) {
4176                 value = -1;
4177                 SP = ORIGMARK;
4178                 PUSHi(value);
4179                 if (did_pipes) {
4180                     PerlLIO_close(pp[0]);
4181                     PerlLIO_close(pp[1]);
4182                 }
4183                 RETURN;
4184             }
4185             sleep(5);
4186         }
4187         if (childpid > 0) {
4188             Sigsave_t ihand,qhand; /* place to save signals during system() */
4189             int status;
4190
4191             if (did_pipes)
4192                 PerlLIO_close(pp[1]);
4193 #ifndef PERL_MICRO
4194             rsignal_save(SIGINT, SIG_IGN, &ihand);
4195             rsignal_save(SIGQUIT, SIG_IGN, &qhand);
4196 #endif
4197             do {
4198                 result = wait4pid(childpid, &status, 0);
4199             } while (result == -1 && errno == EINTR);
4200 #ifndef PERL_MICRO
4201             (void)rsignal_restore(SIGINT, &ihand);
4202             (void)rsignal_restore(SIGQUIT, &qhand);
4203 #endif
4204             STATUS_NATIVE_SET(result == -1 ? -1 : status);
4205             do_execfree();      /* free any memory child malloced on fork */
4206             SP = ORIGMARK;
4207             if (did_pipes) {
4208                 int errkid;
4209                 int n = 0, n1;
4210
4211                 while (n < sizeof(int)) {
4212                     n1 = PerlLIO_read(pp[0],
4213                                       (void*)(((char*)&errkid)+n),
4214                                       (sizeof(int)) - n);
4215                     if (n1 <= 0)
4216                         break;
4217                     n += n1;
4218                 }
4219                 PerlLIO_close(pp[0]);
4220                 if (n) {                        /* Error */
4221                     if (n != sizeof(int))
4222                         DIE(aTHX_ "panic: kid popen errno read");
4223                     errno = errkid;             /* Propagate errno from kid */
4224                     STATUS_CURRENT = -1;
4225                 }
4226             }
4227             PUSHi(STATUS_CURRENT);
4228             RETURN;
4229         }
4230         if (did_pipes) {
4231             PerlLIO_close(pp[0]);
4232 #if defined(HAS_FCNTL) && defined(F_SETFD)
4233             fcntl(pp[1], F_SETFD, FD_CLOEXEC);
4234 #endif
4235         }
4236         if (PL_op->op_flags & OPf_STACKED) {
4237             SV *really = *++MARK;
4238             value = (I32)do_aexec5(really, MARK, SP, pp[1], did_pipes);
4239         }
4240         else if (SP - MARK != 1)
4241             value = (I32)do_aexec5(Nullsv, MARK, SP, pp[1], did_pipes);
4242         else {
4243             value = (I32)do_exec3(SvPVx_nolen(sv_mortalcopy(*SP)), pp[1], did_pipes);
4244         }
4245         PerlProc__exit(-1);
4246     }
4247 #else /* ! FORK or VMS or OS/2 */
4248     PL_statusvalue = 0;
4249     result = 0;
4250     if (PL_op->op_flags & OPf_STACKED) {
4251         SV *really = *++MARK;
4252 #  if defined(WIN32) || defined(OS2) || defined(SYMBIAN)
4253         value = (I32)do_aspawn(really, MARK, SP);
4254 #  else
4255         value = (I32)do_aspawn(really, (void **)MARK, (void **)SP);
4256 #  endif
4257     }
4258     else if (SP - MARK != 1) {
4259 #  if defined(WIN32) || defined(OS2) || defined(SYMBIAN)
4260         value = (I32)do_aspawn(Nullsv, MARK, SP);
4261 #  else
4262         value = (I32)do_aspawn(Nullsv, (void **)MARK, (void **)SP);
4263 #  endif
4264     }
4265     else {
4266         value = (I32)do_spawn(SvPVx_nolen(sv_mortalcopy(*SP)));
4267     }
4268     if (PL_statusvalue == -1)   /* hint that value must be returned as is */
4269         result = 1;
4270     STATUS_NATIVE_SET(value);
4271     do_execfree();
4272     SP = ORIGMARK;
4273     PUSHi(result ? value : STATUS_CURRENT);
4274 #endif /* !FORK or VMS */
4275     RETURN;
4276 }
4277
4278 PP(pp_exec)
4279 {
4280     dSP; dMARK; dORIGMARK; dTARGET;
4281     I32 value;
4282
4283     if (PL_tainting) {
4284         TAINT_ENV();
4285         while (++MARK <= SP) {
4286             (void)SvPV_nolen_const(*MARK);      /* stringify for taint check */
4287             if (PL_tainted)
4288                 break;
4289         }
4290         MARK = ORIGMARK;
4291         TAINT_PROPER("exec");
4292     }
4293     PERL_FLUSHALL_FOR_CHILD;
4294     if (PL_op->op_flags & OPf_STACKED) {
4295         SV *really = *++MARK;
4296         value = (I32)do_aexec(really, MARK, SP);
4297     }
4298     else if (SP - MARK != 1)
4299 #ifdef VMS
4300         value = (I32)vms_do_aexec(Nullsv, MARK, SP);
4301 #else
4302 #  ifdef __OPEN_VM
4303         {
4304            (void ) do_aspawn(Nullsv, MARK, SP);
4305            value = 0;
4306         }
4307 #  else
4308         value = (I32)do_aexec(Nullsv, MARK, SP);
4309 #  endif
4310 #endif
4311     else {
4312 #ifdef VMS
4313         value = (I32)vms_do_exec(SvPVx_nolen(sv_mortalcopy(*SP)));
4314 #else
4315 #  ifdef __OPEN_VM
4316         (void) do_spawn(SvPVx_nolen(sv_mortalcopy(*SP)));
4317         value = 0;
4318 #  else
4319         value = (I32)do_exec(SvPVx_nolen(sv_mortalcopy(*SP)));
4320 #  endif
4321 #endif
4322     }
4323
4324     SP = ORIGMARK;
4325     PUSHi(value);
4326     RETURN;
4327 }
4328
4329 PP(pp_kill)
4330 {
4331 #ifdef HAS_KILL
4332     dSP; dMARK; dTARGET;
4333     I32 value;
4334     value = (I32)apply(PL_op->op_type, MARK, SP);
4335     SP = MARK;
4336     PUSHi(value);
4337     RETURN;
4338 #else
4339     DIE(aTHX_ PL_no_func, "kill");
4340 #endif
4341 }
4342
4343 PP(pp_getppid)
4344 {
4345 #ifdef HAS_GETPPID
4346     dSP; dTARGET;
4347 #   ifdef THREADS_HAVE_PIDS
4348     if (PL_ppid != 1 && getppid() == 1)
4349         /* maybe the parent process has died. Refresh ppid cache */
4350         PL_ppid = 1;
4351     XPUSHi( PL_ppid );
4352 #   else
4353     XPUSHi( getppid() );
4354 #   endif
4355     RETURN;
4356 #else
4357     DIE(aTHX_ PL_no_func, "getppid");
4358 #endif
4359 }
4360
4361 PP(pp_getpgrp)
4362 {
4363 #ifdef HAS_GETPGRP
4364     dSP; dTARGET;
4365     Pid_t pid;
4366     Pid_t pgrp;
4367
4368     if (MAXARG < 1)
4369         pid = 0;
4370     else
4371         pid = SvIVx(POPs);
4372 #ifdef BSD_GETPGRP
4373     pgrp = (I32)BSD_GETPGRP(pid);
4374 #else
4375     if (pid != 0 && pid != PerlProc_getpid())
4376         DIE(aTHX_ "POSIX getpgrp can't take an argument");
4377     pgrp = getpgrp();
4378 #endif
4379     XPUSHi(pgrp);
4380     RETURN;
4381 #else
4382     DIE(aTHX_ PL_no_func, "getpgrp()");
4383 #endif
4384 }
4385
4386 PP(pp_setpgrp)
4387 {
4388 #ifdef HAS_SETPGRP
4389     dSP; dTARGET;
4390     Pid_t pgrp;
4391     Pid_t pid;
4392     if (MAXARG < 2) {
4393         pgrp = 0;
4394         pid = 0;
4395     }
4396     else {
4397         pgrp = POPi;
4398         pid = TOPi;
4399     }
4400
4401     TAINT_PROPER("setpgrp");
4402 #ifdef BSD_SETPGRP
4403     SETi( BSD_SETPGRP(pid, pgrp) >= 0 );
4404 #else
4405     if ((pgrp != 0 && pgrp != PerlProc_getpid())
4406         || (pid != 0 && pid != PerlProc_getpid()))
4407     {
4408         DIE(aTHX_ "setpgrp can't take arguments");
4409     }
4410     SETi( setpgrp() >= 0 );
4411 #endif /* USE_BSDPGRP */
4412     RETURN;
4413 #else
4414     DIE(aTHX_ PL_no_func, "setpgrp()");
4415 #endif
4416 }
4417
4418 PP(pp_getpriority)
4419 {
4420 #ifdef HAS_GETPRIORITY
4421     dSP; dTARGET;
4422     int who = POPi;
4423     int which = TOPi;
4424     SETi( getpriority(which, who) );
4425     RETURN;
4426 #else
4427     DIE(aTHX_ PL_no_func, "getpriority()");
4428 #endif
4429 }
4430
4431 PP(pp_setpriority)
4432 {
4433 #ifdef HAS_SETPRIORITY
4434     dSP; dTARGET;
4435     int niceval = POPi;
4436     int who = POPi;
4437     int which = TOPi;
4438     TAINT_PROPER("setpriority");
4439     SETi( setpriority(which, who, niceval) >= 0 );
4440     RETURN;
4441 #else
4442     DIE(aTHX_ PL_no_func, "setpriority()");
4443 #endif
4444 }
4445
4446 /* Time calls. */
4447
4448 PP(pp_time)
4449 {
4450     dSP; dTARGET;
4451 #ifdef BIG_TIME
4452     XPUSHn( time(Null(Time_t*)) );
4453 #else
4454     XPUSHi( time(Null(Time_t*)) );
4455 #endif
4456     RETURN;
4457 }
4458
4459 PP(pp_tms)
4460 {
4461 #ifdef HAS_TIMES
4462     dSP;
4463     EXTEND(SP, 4);
4464 #ifndef VMS
4465     (void)PerlProc_times(&PL_timesbuf);
4466 #else
4467     (void)PerlProc_times((tbuffer_t *)&PL_timesbuf);  /* time.h uses different name for */
4468                                                    /* struct tms, though same data   */
4469                                                    /* is returned.                   */
4470 #endif
4471
4472     PUSHs(sv_2mortal(newSVnv(((NV)PL_timesbuf.tms_utime)/(NV)PL_clocktick)));
4473     if (GIMME == G_ARRAY) {
4474         PUSHs(sv_2mortal(newSVnv(((NV)PL_timesbuf.tms_stime)/(NV)PL_clocktick)));
4475         PUSHs(sv_2mortal(newSVnv(((NV)PL_timesbuf.tms_cutime)/(NV)PL_clocktick)));
4476         PUSHs(sv_2mortal(newSVnv(((NV)PL_timesbuf.tms_cstime)/(NV)PL_clocktick)));
4477     }
4478     RETURN;
4479 #else
4480 #   ifdef PERL_MICRO
4481     dSP;
4482     PUSHs(sv_2mortal(newSVnv((NV)0.0)));
4483     EXTEND(SP, 4);
4484     if (GIMME == G_ARRAY) {
4485          PUSHs(sv_2mortal(newSVnv((NV)0.0)));
4486          PUSHs(sv_2mortal(newSVnv((NV)0.0)));
4487          PUSHs(sv_2mortal(newSVnv((NV)0.0)));
4488     }
4489     RETURN;
4490 #   else
4491     DIE(aTHX_ "times not implemented");
4492 #   endif
4493 #endif /* HAS_TIMES */
4494 }
4495
4496 PP(pp_localtime)
4497 {
4498     return pp_gmtime();
4499 }
4500
4501 PP(pp_gmtime)
4502 {
4503     dSP;
4504     Time_t when;
4505     const struct tm *tmbuf;
4506     static const char * const dayname[] =
4507         {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
4508     static const char * const monname[] =
4509         {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
4510          "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
4511
4512     if (MAXARG < 1)
4513         (void)time(&when);
4514     else
4515 #ifdef BIG_TIME
4516         when = (Time_t)SvNVx(POPs);
4517 #else
4518         when = (Time_t)SvIVx(POPs);
4519 #endif
4520
4521     if (PL_op->op_type == OP_LOCALTIME)
4522         tmbuf = localtime(&when);
4523     else
4524         tmbuf = gmtime(&when);
4525
4526     if (GIMME != G_ARRAY) {
4527         SV *tsv;
4528         EXTEND(SP, 1);
4529         EXTEND_MORTAL(1);
4530         if (!tmbuf)
4531             RETPUSHUNDEF;
4532         tsv = Perl_newSVpvf(aTHX_ "%s %s %2d %02d:%02d:%02d %d",
4533                             dayname[tmbuf->tm_wday],
4534                             monname[tmbuf->tm_mon],
4535                             tmbuf->tm_mday,
4536                             tmbuf->tm_hour,
4537                             tmbuf->tm_min,
4538                             tmbuf->tm_sec,
4539                             tmbuf->tm_year + 1900);
4540         PUSHs(sv_2mortal(tsv));
4541     }
4542     else if (tmbuf) {
4543         EXTEND(SP, 9);
4544         EXTEND_MORTAL(9);
4545         PUSHs(sv_2mortal(newSViv(tmbuf->tm_sec)));
4546         PUSHs(sv_2mortal(newSViv(tmbuf->tm_min)));
4547         PUSHs(sv_2mortal(newSViv(tmbuf->tm_hour)));
4548         PUSHs(sv_2mortal(newSViv(tmbuf->tm_mday)));
4549         PUSHs(sv_2mortal(newSViv(tmbuf->tm_mon)));
4550         PUSHs(sv_2mortal(newSViv(tmbuf->tm_year)));
4551         PUSHs(sv_2mortal(newSViv(tmbuf->tm_wday)));
4552         PUSHs(sv_2mortal(newSViv(tmbuf->tm_yday)));
4553         PUSHs(sv_2mortal(newSViv(tmbuf->tm_isdst)));
4554     }
4555     RETURN;
4556 }
4557
4558 PP(pp_alarm)
4559 {
4560 #ifdef HAS_ALARM
4561     dSP; dTARGET;
4562     int anum;
4563     anum = POPi;
4564     anum = alarm((unsigned int)anum);
4565     EXTEND(SP, 1);
4566     if (anum < 0)
4567         RETPUSHUNDEF;
4568     PUSHi(anum);
4569     RETURN;
4570 #else
4571     DIE(aTHX_ PL_no_func, "alarm");
4572 #endif
4573 }
4574
4575 PP(pp_sleep)
4576 {
4577     dSP; dTARGET;
4578     I32 duration;
4579     Time_t lasttime;
4580     Time_t when;
4581
4582     (void)time(&lasttime);
4583     if (MAXARG < 1)
4584         PerlProc_pause();
4585     else {
4586         duration = POPi;
4587         PerlProc_sleep((unsigned int)duration);
4588     }
4589     (void)time(&when);
4590     XPUSHi(when - lasttime);
4591     RETURN;
4592 }
4593
4594 /* Shared memory. */
4595
4596 PP(pp_shmget)
4597 {
4598     return pp_semget();
4599 }
4600
4601 PP(pp_shmctl)
4602 {
4603     return pp_semctl();
4604 }
4605
4606 PP(pp_shmread)
4607 {
4608     return pp_shmwrite();
4609 }
4610
4611 PP(pp_shmwrite)
4612 {
4613 #if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
4614     dSP; dMARK; dTARGET;
4615     I32 value = (I32)(do_shmio(PL_op->op_type, MARK, SP) >= 0);
4616     SP = MARK;
4617     PUSHi(value);
4618     RETURN;
4619 #else
4620     return pp_semget();
4621 #endif
4622 }
4623
4624 /* Message passing. */
4625
4626 PP(pp_msgget)
4627 {
4628     return pp_semget();
4629 }
4630
4631 PP(pp_msgctl)
4632 {
4633     return pp_semctl();
4634 }
4635
4636 PP(pp_msgsnd)
4637 {
4638 #if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
4639     dSP; dMARK; dTARGET;
4640     I32 value = (I32)(do_msgsnd(MARK, SP) >= 0);
4641     SP = MARK;
4642     PUSHi(value);
4643     RETURN;
4644 #else
4645     return pp_semget();
4646 #endif
4647 }
4648
4649 PP(pp_msgrcv)
4650 {
4651 #if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
4652     dSP; dMARK; dTARGET;
4653     I32 value = (I32)(do_msgrcv(MARK, SP) >= 0);
4654     SP = MARK;
4655     PUSHi(value);
4656     RETURN;
4657 #else
4658     return pp_semget();
4659 #endif
4660 }
4661
4662 /* Semaphores. */
4663
4664 PP(pp_semget)
4665 {
4666 #if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
4667     dSP; dMARK; dTARGET;
4668     int anum = do_ipcget(PL_op->op_type, MARK, SP);
4669     SP = MARK;
4670     if (anum == -1)
4671         RETPUSHUNDEF;
4672     PUSHi(anum);
4673     RETURN;
4674 #else
4675     DIE(aTHX_ "System V IPC is not implemented on this machine");
4676 #endif
4677 }
4678
4679 PP(pp_semctl)
4680 {
4681 #if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
4682     dSP; dMARK; dTARGET;
4683     int anum = do_ipcctl(PL_op->op_type, MARK, SP);
4684     SP = MARK;
4685     if (anum == -1)
4686         RETSETUNDEF;
4687     if (anum != 0) {
4688         PUSHi(anum);
4689     }
4690     else {
4691         PUSHp(zero_but_true, ZBTLEN);
4692     }
4693     RETURN;
4694 #else
4695     return pp_semget();
4696 #endif
4697 }
4698
4699 PP(pp_semop)
4700 {
4701 #if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
4702     dSP; dMARK; dTARGET;
4703     I32 value = (I32)(do_semop(MARK, SP) >= 0);
4704     SP = MARK;
4705     PUSHi(value);
4706     RETURN;
4707 #else
4708     return pp_semget();
4709 #endif
4710 }
4711
4712 /* Get system info. */
4713
4714 PP(pp_ghbyname)
4715 {
4716 #ifdef HAS_GETHOSTBYNAME
4717     return pp_ghostent();
4718 #else
4719     DIE(aTHX_ PL_no_sock_func, "gethostbyname");
4720 #endif
4721 }
4722
4723 PP(pp_ghbyaddr)
4724 {
4725 #ifdef HAS_GETHOSTBYADDR
4726     return pp_ghostent();
4727 #else
4728     DIE(aTHX_ PL_no_sock_func, "gethostbyaddr");
4729 #endif
4730 }
4731
4732 PP(pp_ghostent)
4733 {
4734 #if defined(HAS_GETHOSTBYNAME) || defined(HAS_GETHOSTBYADDR) || defined(HAS_GETHOSTENT)
4735     dSP;
4736     I32 which = PL_op->op_type;
4737     register char **elem;
4738     register SV *sv;
4739 #ifndef HAS_GETHOST_PROTOS /* XXX Do we need individual probes? */
4740     struct hostent *gethostbyaddr(Netdb_host_t, Netdb_hlen_t, int);
4741     struct hostent *gethostbyname(Netdb_name_t);
4742     struct hostent *gethostent(void);
4743 #endif
4744     struct hostent *hent;
4745     unsigned long len;
4746
4747     EXTEND(SP, 10);
4748     if (which == OP_GHBYNAME) {
4749 #ifdef HAS_GETHOSTBYNAME
4750         char* name = POPpbytex;
4751         hent = PerlSock_gethostbyname(name);
4752 #else
4753         DIE(aTHX_ PL_no_sock_func, "gethostbyname");
4754 #endif
4755     }
4756     else if (which == OP_GHBYADDR) {
4757 #ifdef HAS_GETHOSTBYADDR
4758         int addrtype = POPi;
4759         SV *addrsv = POPs;
4760         STRLEN addrlen;
4761         Netdb_host_t addr = (Netdb_host_t) SvPVbyte(addrsv, addrlen);
4762
4763         hent = PerlSock_gethostbyaddr(addr, (Netdb_hlen_t) addrlen, addrtype);
4764 #else
4765         DIE(aTHX_ PL_no_sock_func, "gethostbyaddr");
4766 #endif
4767     }
4768     else
4769 #ifdef HAS_GETHOSTENT
4770         hent = PerlSock_gethostent();
4771 #else
4772         DIE(aTHX_ PL_no_sock_func, "gethostent");
4773 #endif
4774
4775 #ifdef HOST_NOT_FOUND
4776         if (!hent) {
4777 #ifdef USE_REENTRANT_API
4778 #   ifdef USE_GETHOSTENT_ERRNO
4779             h_errno = PL_reentrant_buffer->_gethostent_errno;
4780 #   endif
4781 #endif
4782             STATUS_NATIVE_SET(h_errno);
4783         }
4784 #endif
4785
4786     if (GIMME != G_ARRAY) {
4787         PUSHs(sv = sv_newmortal());
4788         if (hent) {
4789             if (which == OP_GHBYNAME) {
4790                 if (hent->h_addr)
4791                     sv_setpvn(sv, hent->h_addr, hent->h_length);
4792             }
4793             else
4794                 sv_setpv(sv, (char*)hent->h_name);
4795         }
4796         RETURN;
4797     }
4798
4799     if (hent) {
4800         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
4801         sv_setpv(sv, (char*)hent->h_name);
4802         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
4803         for (elem = hent->h_aliases; elem && *elem; elem++) {
4804             sv_catpv(sv, *elem);
4805             if (elem[1])
4806                 sv_catpvn(sv, " ", 1);
4807         }
4808         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
4809         sv_setiv(sv, (IV)hent->h_addrtype);
4810         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
4811         len = hent->h_length;
4812         sv_setiv(sv, (IV)len);
4813 #ifdef h_addr
4814         for (elem = hent->h_addr_list; elem && *elem; elem++) {
4815             XPUSHs(sv = sv_mortalcopy(&PL_sv_no));
4816             sv_setpvn(sv, *elem, len);
4817         }
4818 #else
4819         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
4820         if (hent->h_addr)
4821             sv_setpvn(sv, hent->h_addr, len);
4822 #endif /* h_addr */
4823     }
4824     RETURN;
4825 #else
4826     DIE(aTHX_ PL_no_sock_func, "gethostent");
4827 #endif
4828 }
4829
4830 PP(pp_gnbyname)
4831 {
4832 #ifdef HAS_GETNETBYNAME
4833     return pp_gnetent();
4834 #else
4835     DIE(aTHX_ PL_no_sock_func, "getnetbyname");
4836 #endif
4837 }
4838
4839 PP(pp_gnbyaddr)
4840 {
4841 #ifdef HAS_GETNETBYADDR
4842     return pp_gnetent();
4843 #else
4844     DIE(aTHX_ PL_no_sock_func, "getnetbyaddr");
4845 #endif
4846 }
4847
4848 PP(pp_gnetent)
4849 {
4850 #if defined(HAS_GETNETBYNAME) || defined(HAS_GETNETBYADDR) || defined(HAS_GETNETENT)
4851     dSP;
4852     I32 which = PL_op->op_type;
4853     register char **elem;
4854     register SV *sv;
4855 #ifndef HAS_GETNET_PROTOS /* XXX Do we need individual probes? */
4856     struct netent *getnetbyaddr(Netdb_net_t, int);
4857     struct netent *getnetbyname(Netdb_name_t);
4858     struct netent *getnetent(void);
4859 #endif
4860     struct netent *nent;
4861
4862     if (which == OP_GNBYNAME){
4863 #ifdef HAS_GETNETBYNAME
4864         char *name = POPpbytex;
4865         nent = PerlSock_getnetbyname(name);
4866 #else
4867         DIE(aTHX_ PL_no_sock_func, "getnetbyname");
4868 #endif
4869     }
4870     else if (which == OP_GNBYADDR) {
4871 #ifdef HAS_GETNETBYADDR
4872         int addrtype = POPi;
4873         Netdb_net_t addr = (Netdb_net_t) (U32)POPu;
4874         nent = PerlSock_getnetbyaddr(addr, addrtype);
4875 #else
4876         DIE(aTHX_ PL_no_sock_func, "getnetbyaddr");
4877 #endif
4878     }
4879     else
4880 #ifdef HAS_GETNETENT
4881         nent = PerlSock_getnetent();
4882 #else
4883         DIE(aTHX_ PL_no_sock_func, "getnetent");
4884 #endif
4885
4886 #ifdef HOST_NOT_FOUND
4887         if (!nent) {
4888 #ifdef USE_REENTRANT_API
4889 #   ifdef USE_GETNETENT_ERRNO
4890              h_errno = PL_reentrant_buffer->_getnetent_errno;
4891 #   endif
4892 #endif
4893             STATUS_NATIVE_SET(h_errno);
4894         }
4895 #endif
4896
4897     EXTEND(SP, 4);
4898     if (GIMME != G_ARRAY) {
4899         PUSHs(sv = sv_newmortal());
4900         if (nent) {
4901             if (which == OP_GNBYNAME)
4902                 sv_setiv(sv, (IV)nent->n_net);
4903             else
4904                 sv_setpv(sv, nent->n_name);
4905         }
4906         RETURN;
4907     }
4908
4909     if (nent) {
4910         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
4911         sv_setpv(sv, nent->n_name);
4912         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
4913         for (elem = nent->n_aliases; elem && *elem; elem++) {
4914             sv_catpv(sv, *elem);
4915             if (elem[1])
4916                 sv_catpvn(sv, " ", 1);
4917         }
4918         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
4919         sv_setiv(sv, (IV)nent->n_addrtype);
4920         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
4921         sv_setiv(sv, (IV)nent->n_net);
4922     }
4923
4924     RETURN;
4925 #else
4926     DIE(aTHX_ PL_no_sock_func, "getnetent");
4927 #endif
4928 }
4929
4930 PP(pp_gpbyname)
4931 {
4932 #ifdef HAS_GETPROTOBYNAME
4933     return pp_gprotoent();
4934 #else
4935     DIE(aTHX_ PL_no_sock_func, "getprotobyname");
4936 #endif
4937 }
4938
4939 PP(pp_gpbynumber)
4940 {
4941 #ifdef HAS_GETPROTOBYNUMBER
4942     return pp_gprotoent();
4943 #else
4944     DIE(aTHX_ PL_no_sock_func, "getprotobynumber");
4945 #endif
4946 }
4947
4948 PP(pp_gprotoent)
4949 {
4950 #if defined(HAS_GETPROTOBYNAME) || defined(HAS_GETPROTOBYNUMBER) || defined(HAS_GETPROTOENT)
4951     dSP;
4952     I32 which = PL_op->op_type;
4953     register char **elem;
4954     register SV *sv;
4955 #ifndef HAS_GETPROTO_PROTOS /* XXX Do we need individual probes? */
4956     struct protoent *getprotobyname(Netdb_name_t);
4957     struct protoent *getprotobynumber(int);
4958     struct protoent *getprotoent(void);
4959 #endif
4960     struct protoent *pent;
4961
4962     if (which == OP_GPBYNAME) {
4963 #ifdef HAS_GETPROTOBYNAME
4964         char* name = POPpbytex;
4965         pent = PerlSock_getprotobyname(name);
4966 #else
4967         DIE(aTHX_ PL_no_sock_func, "getprotobyname");
4968 #endif
4969     }
4970     else if (which == OP_GPBYNUMBER) {
4971 #ifdef HAS_GETPROTOBYNUMBER
4972         int number = POPi;
4973         pent = PerlSock_getprotobynumber(number);
4974 #else
4975         DIE(aTHX_ PL_no_sock_func, "getprotobynumber");
4976 #endif
4977     }
4978     else
4979 #ifdef HAS_GETPROTOENT
4980         pent = PerlSock_getprotoent();
4981 #else
4982         DIE(aTHX_ PL_no_sock_func, "getprotoent");
4983 #endif
4984
4985     EXTEND(SP, 3);
4986     if (GIMME != G_ARRAY) {
4987         PUSHs(sv = sv_newmortal());
4988         if (pent) {
4989             if (which == OP_GPBYNAME)
4990                 sv_setiv(sv, (IV)pent->p_proto);
4991             else
4992                 sv_setpv(sv, pent->p_name);
4993         }
4994         RETURN;
4995     }
4996
4997     if (pent) {
4998         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
4999         sv_setpv(sv, pent->p_name);
5000         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
5001         for (elem = pent->p_aliases; elem && *elem; elem++) {
5002             sv_catpv(sv, *elem);
5003             if (elem[1])
5004                 sv_catpvn(sv, " ", 1);
5005         }
5006         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
5007         sv_setiv(sv, (IV)pent->p_proto);
5008     }
5009
5010     RETURN;
5011 #else
5012     DIE(aTHX_ PL_no_sock_func, "getprotoent");
5013 #endif
5014 }
5015
5016 PP(pp_gsbyname)
5017 {
5018 #ifdef HAS_GETSERVBYNAME
5019     return pp_gservent();
5020 #else
5021     DIE(aTHX_ PL_no_sock_func, "getservbyname");
5022 #endif
5023 }
5024
5025 PP(pp_gsbyport)
5026 {
5027 #ifdef HAS_GETSERVBYPORT
5028     return pp_gservent();
5029 #else
5030     DIE(aTHX_ PL_no_sock_func, "getservbyport");
5031 #endif
5032 }
5033
5034 PP(pp_gservent)
5035 {
5036 #if defined(HAS_GETSERVBYNAME) || defined(HAS_GETSERVBYPORT) || defined(HAS_GETSERVENT)
5037     dSP;
5038     I32 which = PL_op->op_type;
5039     register char **elem;
5040     register SV *sv;
5041 #ifndef HAS_GETSERV_PROTOS /* XXX Do we need individual probes? */
5042     struct servent *getservbyname(Netdb_name_t, Netdb_name_t);
5043     struct servent *getservbyport(int, Netdb_name_t);
5044     struct servent *getservent(void);
5045 #endif
5046     struct servent *sent;
5047
5048     if (which == OP_GSBYNAME) {
5049 #ifdef HAS_GETSERVBYNAME
5050         char *proto = POPpbytex;
5051         char *name = POPpbytex;
5052
5053         if (proto && !*proto)
5054             proto = Nullch;
5055
5056         sent = PerlSock_getservbyname(name, proto);
5057 #else
5058         DIE(aTHX_ PL_no_sock_func, "getservbyname");
5059 #endif
5060     }
5061     else if (which == OP_GSBYPORT) {
5062 #ifdef HAS_GETSERVBYPORT
5063         char *proto = POPpbytex;
5064         unsigned short port = (unsigned short)POPu;
5065
5066         if (proto && !*proto)
5067             proto = Nullch;
5068
5069 #ifdef HAS_HTONS
5070         port = PerlSock_htons(port);
5071 #endif
5072         sent = PerlSock_getservbyport(port, proto);
5073 #else
5074         DIE(aTHX_ PL_no_sock_func, "getservbyport");
5075 #endif
5076     }
5077     else
5078 #ifdef HAS_GETSERVENT
5079         sent = PerlSock_getservent();
5080 #else
5081         DIE(aTHX_ PL_no_sock_func, "getservent");
5082 #endif
5083
5084     EXTEND(SP, 4);
5085     if (GIMME != G_ARRAY) {
5086         PUSHs(sv = sv_newmortal());
5087         if (sent) {
5088             if (which == OP_GSBYNAME) {
5089 #ifdef HAS_NTOHS
5090                 sv_setiv(sv, (IV)PerlSock_ntohs(sent->s_port));
5091 #else
5092                 sv_setiv(sv, (IV)(sent->s_port));
5093 #endif
5094             }
5095             else
5096                 sv_setpv(sv, sent->s_name);
5097         }
5098         RETURN;
5099     }
5100
5101     if (sent) {
5102         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
5103         sv_setpv(sv, sent->s_name);
5104         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
5105         for (elem = sent->s_aliases; elem && *elem; elem++) {
5106             sv_catpv(sv, *elem);
5107             if (elem[1])
5108                 sv_catpvn(sv, " ", 1);
5109         }
5110         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
5111 #ifdef HAS_NTOHS
5112         sv_setiv(sv, (IV)PerlSock_ntohs(sent->s_port));
5113 #else
5114         sv_setiv(sv, (IV)(sent->s_port));
5115 #endif
5116         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
5117         sv_setpv(sv, sent->s_proto);
5118     }
5119
5120     RETURN;
5121 #else
5122     DIE(aTHX_ PL_no_sock_func, "getservent");
5123 #endif
5124 }
5125
5126 PP(pp_shostent)
5127 {
5128 #ifdef HAS_SETHOSTENT
5129     dSP;
5130     PerlSock_sethostent(TOPi);
5131     RETSETYES;
5132 #else
5133     DIE(aTHX_ PL_no_sock_func, "sethostent");
5134 #endif
5135 }
5136
5137 PP(pp_snetent)
5138 {
5139 #ifdef HAS_SETNETENT
5140     dSP;
5141     PerlSock_setnetent(TOPi);
5142     RETSETYES;
5143 #else
5144     DIE(aTHX_ PL_no_sock_func, "setnetent");
5145 #endif
5146 }
5147
5148 PP(pp_sprotoent)
5149 {
5150 #ifdef HAS_SETPROTOENT
5151     dSP;
5152     PerlSock_setprotoent(TOPi);
5153     RETSETYES;
5154 #else
5155     DIE(aTHX_ PL_no_sock_func, "setprotoent");
5156 #endif
5157 }
5158
5159 PP(pp_sservent)
5160 {
5161 #ifdef HAS_SETSERVENT
5162     dSP;
5163     PerlSock_setservent(TOPi);
5164     RETSETYES;
5165 #else
5166     DIE(aTHX_ PL_no_sock_func, "setservent");
5167 #endif
5168 }
5169
5170 PP(pp_ehostent)
5171 {
5172 #ifdef HAS_ENDHOSTENT
5173     dSP;
5174     PerlSock_endhostent();
5175     EXTEND(SP,1);
5176     RETPUSHYES;
5177 #else
5178     DIE(aTHX_ PL_no_sock_func, "endhostent");
5179 #endif
5180 }
5181
5182 PP(pp_enetent)
5183 {
5184 #ifdef HAS_ENDNETENT
5185     dSP;
5186     PerlSock_endnetent();
5187     EXTEND(SP,1);
5188     RETPUSHYES;
5189 #else
5190     DIE(aTHX_ PL_no_sock_func, "endnetent");
5191 #endif
5192 }
5193
5194 PP(pp_eprotoent)
5195 {
5196 #ifdef HAS_ENDPROTOENT
5197     dSP;
5198     PerlSock_endprotoent();
5199     EXTEND(SP,1);
5200     RETPUSHYES;
5201 #else
5202     DIE(aTHX_ PL_no_sock_func, "endprotoent");
5203 #endif
5204 }
5205
5206 PP(pp_eservent)
5207 {
5208 #ifdef HAS_ENDSERVENT
5209     dSP;
5210     PerlSock_endservent();
5211     EXTEND(SP,1);
5212     RETPUSHYES;
5213 #else
5214     DIE(aTHX_ PL_no_sock_func, "endservent");
5215 #endif
5216 }
5217
5218 PP(pp_gpwnam)
5219 {
5220 #ifdef HAS_PASSWD
5221     return pp_gpwent();
5222 #else
5223     DIE(aTHX_ PL_no_func, "getpwnam");
5224 #endif
5225 }
5226
5227 PP(pp_gpwuid)
5228 {
5229 #ifdef HAS_PASSWD
5230     return pp_gpwent();
5231 #else
5232     DIE(aTHX_ PL_no_func, "getpwuid");
5233 #endif
5234 }
5235
5236 PP(pp_gpwent)
5237 {
5238 #ifdef HAS_PASSWD
5239     dSP;
5240     I32 which = PL_op->op_type;
5241     register SV *sv;
5242     struct passwd *pwent  = NULL;