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