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