Maintainer catch from Rafael.
[p5sagit/p5-mst-13.2.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         /* UTF8 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( (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( (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( (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     dSP;
3801 #if !defined(I_DIRENT) && !defined(VMS)
3802     Direntry_t *readdir (DIR *);
3803 #endif
3804     register Direntry_t *dp;
3805     GV *gv = (GV*)POPs;
3806     register IO *io = GvIOn(gv);
3807     SV *sv;
3808
3809     if (!io || !IoDIRP(io))
3810         goto nope;
3811
3812     if (GIMME == G_ARRAY) {
3813         /*SUPPRESS 560*/
3814         while ((dp = (Direntry_t *)PerlDir_read(IoDIRP(io)))) {
3815 #ifdef DIRNAMLEN
3816             sv = newSVpvn(dp->d_name, dp->d_namlen);
3817 #else
3818             sv = newSVpv(dp->d_name, 0);
3819 #endif
3820 #ifndef INCOMPLETE_TAINTS
3821             if (!(IoFLAGS(io) & IOf_UNTAINT))
3822                 SvTAINTED_on(sv);
3823 #endif
3824             XPUSHs(sv_2mortal(sv));
3825         }
3826     }
3827     else {
3828         if (!(dp = (Direntry_t *)PerlDir_read(IoDIRP(io))))
3829             goto nope;
3830 #ifdef DIRNAMLEN
3831         sv = newSVpvn(dp->d_name, dp->d_namlen);
3832 #else
3833         sv = newSVpv(dp->d_name, 0);
3834 #endif
3835 #ifndef INCOMPLETE_TAINTS
3836         if (!(IoFLAGS(io) & IOf_UNTAINT))
3837             SvTAINTED_on(sv);
3838 #endif
3839         XPUSHs(sv_2mortal(sv));
3840     }
3841     RETURN;
3842
3843 nope:
3844     if (!errno)
3845         SETERRNO(EBADF,RMS_ISI);
3846     if (GIMME == G_ARRAY)
3847         RETURN;
3848     else
3849         RETPUSHUNDEF;
3850 #else
3851     DIE(aTHX_ PL_no_dir_func, "readdir");
3852 #endif
3853 }
3854
3855 PP(pp_telldir)
3856 {
3857 #if defined(HAS_TELLDIR) || defined(telldir)
3858     dSP; dTARGET;
3859  /* XXX does _anyone_ need this? --AD 2/20/1998 */
3860  /* XXX netbsd still seemed to.
3861     XXX HAS_TELLDIR_PROTO is new style, NEED_TELLDIR_PROTO is old style.
3862     --JHI 1999-Feb-02 */
3863 # if !defined(HAS_TELLDIR_PROTO) || defined(NEED_TELLDIR_PROTO)
3864     long telldir (DIR *);
3865 # endif
3866     GV *gv = (GV*)POPs;
3867     register IO *io = GvIOn(gv);
3868
3869     if (!io || !IoDIRP(io))
3870         goto nope;
3871
3872     PUSHi( PerlDir_tell(IoDIRP(io)) );
3873     RETURN;
3874 nope:
3875     if (!errno)
3876         SETERRNO(EBADF,RMS_ISI);
3877     RETPUSHUNDEF;
3878 #else
3879     DIE(aTHX_ PL_no_dir_func, "telldir");
3880 #endif
3881 }
3882
3883 PP(pp_seekdir)
3884 {
3885 #if defined(HAS_SEEKDIR) || defined(seekdir)
3886     dSP;
3887     long along = POPl;
3888     GV *gv = (GV*)POPs;
3889     register IO *io = GvIOn(gv);
3890
3891     if (!io || !IoDIRP(io))
3892         goto nope;
3893
3894     (void)PerlDir_seek(IoDIRP(io), along);
3895
3896     RETPUSHYES;
3897 nope:
3898     if (!errno)
3899         SETERRNO(EBADF,RMS_ISI);
3900     RETPUSHUNDEF;
3901 #else
3902     DIE(aTHX_ PL_no_dir_func, "seekdir");
3903 #endif
3904 }
3905
3906 PP(pp_rewinddir)
3907 {
3908 #if defined(HAS_REWINDDIR) || defined(rewinddir)
3909     dSP;
3910     GV *gv = (GV*)POPs;
3911     register IO *io = GvIOn(gv);
3912
3913     if (!io || !IoDIRP(io))
3914         goto nope;
3915
3916     (void)PerlDir_rewind(IoDIRP(io));
3917     RETPUSHYES;
3918 nope:
3919     if (!errno)
3920         SETERRNO(EBADF,RMS_ISI);
3921     RETPUSHUNDEF;
3922 #else
3923     DIE(aTHX_ PL_no_dir_func, "rewinddir");
3924 #endif
3925 }
3926
3927 PP(pp_closedir)
3928 {
3929 #if defined(Direntry_t) && defined(HAS_READDIR)
3930     dSP;
3931     GV *gv = (GV*)POPs;
3932     register IO *io = GvIOn(gv);
3933
3934     if (!io || !IoDIRP(io))
3935         goto nope;
3936
3937 #ifdef VOID_CLOSEDIR
3938     PerlDir_close(IoDIRP(io));
3939 #else
3940     if (PerlDir_close(IoDIRP(io)) < 0) {
3941         IoDIRP(io) = 0; /* Don't try to close again--coredumps on SysV */
3942         goto nope;
3943     }
3944 #endif
3945     IoDIRP(io) = 0;
3946
3947     RETPUSHYES;
3948 nope:
3949     if (!errno)
3950         SETERRNO(EBADF,RMS_IFI);
3951     RETPUSHUNDEF;
3952 #else
3953     DIE(aTHX_ PL_no_dir_func, "closedir");
3954 #endif
3955 }
3956
3957 /* Process control. */
3958
3959 PP(pp_fork)
3960 {
3961 #ifdef HAS_FORK
3962     dSP; dTARGET;
3963     Pid_t childpid;
3964     GV *tmpgv;
3965
3966     EXTEND(SP, 1);
3967     PERL_FLUSHALL_FOR_CHILD;
3968     childpid = PerlProc_fork();
3969     if (childpid < 0)
3970         RETSETUNDEF;
3971     if (!childpid) {
3972         /*SUPPRESS 560*/
3973         if ((tmpgv = gv_fetchpv("$", TRUE, SVt_PV))) {
3974             SvREADONLY_off(GvSV(tmpgv));
3975             sv_setiv(GvSV(tmpgv), (IV)PerlProc_getpid());
3976             SvREADONLY_on(GvSV(tmpgv));
3977         }
3978 #ifdef THREADS_HAVE_PIDS
3979         PL_ppid = (IV)getppid();
3980 #endif
3981         hv_clear(PL_pidstatus); /* no kids, so don't wait for 'em */
3982     }
3983     PUSHi(childpid);
3984     RETURN;
3985 #else
3986 #  if defined(USE_ITHREADS) && defined(PERL_IMPLICIT_SYS)
3987     dSP; dTARGET;
3988     Pid_t childpid;
3989
3990     EXTEND(SP, 1);
3991     PERL_FLUSHALL_FOR_CHILD;
3992     childpid = PerlProc_fork();
3993     if (childpid == -1)
3994         RETSETUNDEF;
3995     PUSHi(childpid);
3996     RETURN;
3997 #  else
3998     DIE(aTHX_ PL_no_func, "fork");
3999 #  endif
4000 #endif
4001 }
4002
4003 PP(pp_wait)
4004 {
4005 #if (!defined(DOSISH) || defined(OS2) || defined(WIN32)) && !defined(MACOS_TRADITIONAL)
4006     dSP; dTARGET;
4007     Pid_t childpid;
4008     int argflags;
4009
4010     if (PL_signals & PERL_SIGNALS_UNSAFE_FLAG)
4011         childpid = wait4pid(-1, &argflags, 0);
4012     else {
4013         while ((childpid = wait4pid(-1, &argflags, 0)) == -1 &&
4014                errno == EINTR) {
4015           PERL_ASYNC_CHECK();
4016         }
4017     }
4018 #  if defined(USE_ITHREADS) && defined(PERL_IMPLICIT_SYS)
4019     /* 0 and -1 are both error returns (the former applies to WNOHANG case) */
4020     STATUS_NATIVE_SET((childpid && childpid != -1) ? argflags : -1);
4021 #  else
4022     STATUS_NATIVE_SET((childpid > 0) ? argflags : -1);
4023 #  endif
4024     XPUSHi(childpid);
4025     RETURN;
4026 #else
4027     DIE(aTHX_ PL_no_func, "wait");
4028 #endif
4029 }
4030
4031 PP(pp_waitpid)
4032 {
4033 #if (!defined(DOSISH) || defined(OS2) || defined(WIN32)) && !defined(MACOS_TRADITIONAL)
4034     dSP; dTARGET;
4035     Pid_t childpid;
4036     int optype;
4037     int argflags;
4038
4039     optype = POPi;
4040     childpid = TOPi;
4041     if (PL_signals & PERL_SIGNALS_UNSAFE_FLAG)
4042         childpid = wait4pid(childpid, &argflags, optype);
4043     else {
4044         while ((childpid = wait4pid(childpid, &argflags, optype)) == -1 &&
4045                errno == EINTR) {
4046           PERL_ASYNC_CHECK();
4047         }
4048     }
4049 #  if defined(USE_ITHREADS) && defined(PERL_IMPLICIT_SYS)
4050     /* 0 and -1 are both error returns (the former applies to WNOHANG case) */
4051     STATUS_NATIVE_SET((childpid && childpid != -1) ? argflags : -1);
4052 #  else
4053     STATUS_NATIVE_SET((childpid > 0) ? argflags : -1);
4054 #  endif
4055     SETi(childpid);
4056     RETURN;
4057 #else
4058     DIE(aTHX_ PL_no_func, "waitpid");
4059 #endif
4060 }
4061
4062 PP(pp_system)
4063 {
4064     dSP; dMARK; dORIGMARK; dTARGET;
4065     I32 value;
4066     STRLEN n_a;
4067     int result;
4068     I32 did_pipes = 0;
4069
4070     if (PL_tainting) {
4071         TAINT_ENV();
4072         while (++MARK <= SP) {
4073             (void)SvPV_nolen(*MARK);      /* stringify for taint check */
4074             if (PL_tainted)
4075                 break;
4076         }
4077         MARK = ORIGMARK;
4078         TAINT_PROPER("system");
4079     }
4080     PERL_FLUSHALL_FOR_CHILD;
4081 #if (defined(HAS_FORK) || defined(AMIGAOS)) && !defined(VMS) && !defined(OS2) || defined(PERL_MICRO)
4082     {
4083         Pid_t childpid;
4084         int pp[2];
4085
4086         if (PerlProc_pipe(pp) >= 0)
4087             did_pipes = 1;
4088         while ((childpid = PerlProc_fork()) == -1) {
4089             if (errno != EAGAIN) {
4090                 value = -1;
4091                 SP = ORIGMARK;
4092                 PUSHi(value);
4093                 if (did_pipes) {
4094                     PerlLIO_close(pp[0]);
4095                     PerlLIO_close(pp[1]);
4096                 }
4097                 RETURN;
4098             }
4099             sleep(5);
4100         }
4101         if (childpid > 0) {
4102             Sigsave_t ihand,qhand; /* place to save signals during system() */
4103             int status;
4104
4105             if (did_pipes)
4106                 PerlLIO_close(pp[1]);
4107 #ifndef PERL_MICRO
4108             rsignal_save(SIGINT, SIG_IGN, &ihand);
4109             rsignal_save(SIGQUIT, SIG_IGN, &qhand);
4110 #endif
4111             do {
4112                 result = wait4pid(childpid, &status, 0);
4113             } while (result == -1 && errno == EINTR);
4114 #ifndef PERL_MICRO
4115             (void)rsignal_restore(SIGINT, &ihand);
4116             (void)rsignal_restore(SIGQUIT, &qhand);
4117 #endif
4118             STATUS_NATIVE_SET(result == -1 ? -1 : status);
4119             do_execfree();      /* free any memory child malloced on fork */
4120             SP = ORIGMARK;
4121             if (did_pipes) {
4122                 int errkid;
4123                 int n = 0, n1;
4124
4125                 while (n < sizeof(int)) {
4126                     n1 = PerlLIO_read(pp[0],
4127                                       (void*)(((char*)&errkid)+n),
4128                                       (sizeof(int)) - n);
4129                     if (n1 <= 0)
4130                         break;
4131                     n += n1;
4132                 }
4133                 PerlLIO_close(pp[0]);
4134                 if (n) {                        /* Error */
4135                     if (n != sizeof(int))
4136                         DIE(aTHX_ "panic: kid popen errno read");
4137                     errno = errkid;             /* Propagate errno from kid */
4138                     STATUS_CURRENT = -1;
4139                 }
4140             }
4141             PUSHi(STATUS_CURRENT);
4142             RETURN;
4143         }
4144         if (did_pipes) {
4145             PerlLIO_close(pp[0]);
4146 #if defined(HAS_FCNTL) && defined(F_SETFD)
4147             fcntl(pp[1], F_SETFD, FD_CLOEXEC);
4148 #endif
4149         }
4150         if (PL_op->op_flags & OPf_STACKED) {
4151             SV *really = *++MARK;
4152             value = (I32)do_aexec5(really, MARK, SP, pp[1], did_pipes);
4153         }
4154         else if (SP - MARK != 1)
4155             value = (I32)do_aexec5(Nullsv, MARK, SP, pp[1], did_pipes);
4156         else {
4157             value = (I32)do_exec3(SvPVx(sv_mortalcopy(*SP), n_a), pp[1], did_pipes);
4158         }
4159         PerlProc__exit(-1);
4160     }
4161 #else /* ! FORK or VMS or OS/2 */
4162     PL_statusvalue = 0;
4163     result = 0;
4164     if (PL_op->op_flags & OPf_STACKED) {
4165         SV *really = *++MARK;
4166 #  if defined(WIN32) || defined(OS2)
4167         value = (I32)do_aspawn(really, MARK, SP);
4168 #  else
4169         value = (I32)do_aspawn(really, (void **)MARK, (void **)SP);
4170 #  endif
4171     }
4172     else if (SP - MARK != 1) {
4173 #  if defined(WIN32) || defined(OS2)
4174         value = (I32)do_aspawn(Nullsv, MARK, SP);
4175 #  else
4176         value = (I32)do_aspawn(Nullsv, (void **)MARK, (void **)SP);
4177 #  endif
4178     }
4179     else {
4180         value = (I32)do_spawn(SvPVx(sv_mortalcopy(*SP), n_a));
4181     }
4182     if (PL_statusvalue == -1)   /* hint that value must be returned as is */
4183         result = 1;
4184     STATUS_NATIVE_SET(value);
4185     do_execfree();
4186     SP = ORIGMARK;
4187     PUSHi(result ? value : STATUS_CURRENT);
4188 #endif /* !FORK or VMS */
4189     RETURN;
4190 }
4191
4192 PP(pp_exec)
4193 {
4194     dSP; dMARK; dORIGMARK; dTARGET;
4195     I32 value;
4196     STRLEN n_a;
4197
4198     if (PL_tainting) {
4199         TAINT_ENV();
4200         while (++MARK <= SP) {
4201             (void)SvPV_nolen(*MARK);      /* stringify for taint check */
4202             if (PL_tainted)
4203                 break;
4204         }
4205         MARK = ORIGMARK;
4206         TAINT_PROPER("exec");
4207     }
4208     PERL_FLUSHALL_FOR_CHILD;
4209     if (PL_op->op_flags & OPf_STACKED) {
4210         SV *really = *++MARK;
4211         value = (I32)do_aexec(really, MARK, SP);
4212     }
4213     else if (SP - MARK != 1)
4214 #ifdef VMS
4215         value = (I32)vms_do_aexec(Nullsv, MARK, SP);
4216 #else
4217 #  ifdef __OPEN_VM
4218         {
4219            (void ) do_aspawn(Nullsv, MARK, SP);
4220            value = 0;
4221         }
4222 #  else
4223         value = (I32)do_aexec(Nullsv, MARK, SP);
4224 #  endif
4225 #endif
4226     else {
4227 #ifdef VMS
4228         value = (I32)vms_do_exec(SvPVx(sv_mortalcopy(*SP), n_a));
4229 #else
4230 #  ifdef __OPEN_VM
4231         (void) do_spawn(SvPVx(sv_mortalcopy(*SP), n_a));
4232         value = 0;
4233 #  else
4234         value = (I32)do_exec(SvPVx(sv_mortalcopy(*SP), n_a));
4235 #  endif
4236 #endif
4237     }
4238
4239     SP = ORIGMARK;
4240     PUSHi(value);
4241     RETURN;
4242 }
4243
4244 PP(pp_kill)
4245 {
4246 #ifdef HAS_KILL
4247     dSP; dMARK; dTARGET;
4248     I32 value;
4249     value = (I32)apply(PL_op->op_type, MARK, SP);
4250     SP = MARK;
4251     PUSHi(value);
4252     RETURN;
4253 #else
4254     DIE(aTHX_ PL_no_func, "kill");
4255 #endif
4256 }
4257
4258 PP(pp_getppid)
4259 {
4260 #ifdef HAS_GETPPID
4261     dSP; dTARGET;
4262 #   ifdef THREADS_HAVE_PIDS
4263     XPUSHi( PL_ppid );
4264 #   else
4265     XPUSHi( getppid() );
4266 #   endif
4267     RETURN;
4268 #else
4269     DIE(aTHX_ PL_no_func, "getppid");
4270 #endif
4271 }
4272
4273 PP(pp_getpgrp)
4274 {
4275 #ifdef HAS_GETPGRP
4276     dSP; dTARGET;
4277     Pid_t pid;
4278     Pid_t pgrp;
4279
4280     if (MAXARG < 1)
4281         pid = 0;
4282     else
4283         pid = SvIVx(POPs);
4284 #ifdef BSD_GETPGRP
4285     pgrp = (I32)BSD_GETPGRP(pid);
4286 #else
4287     if (pid != 0 && pid != PerlProc_getpid())
4288         DIE(aTHX_ "POSIX getpgrp can't take an argument");
4289     pgrp = getpgrp();
4290 #endif
4291     XPUSHi(pgrp);
4292     RETURN;
4293 #else
4294     DIE(aTHX_ PL_no_func, "getpgrp()");
4295 #endif
4296 }
4297
4298 PP(pp_setpgrp)
4299 {
4300 #ifdef HAS_SETPGRP
4301     dSP; dTARGET;
4302     Pid_t pgrp;
4303     Pid_t pid;
4304     if (MAXARG < 2) {
4305         pgrp = 0;
4306         pid = 0;
4307     }
4308     else {
4309         pgrp = POPi;
4310         pid = TOPi;
4311     }
4312
4313     TAINT_PROPER("setpgrp");
4314 #ifdef BSD_SETPGRP
4315     SETi( BSD_SETPGRP(pid, pgrp) >= 0 );
4316 #else
4317     if ((pgrp != 0 && pgrp != PerlProc_getpid())
4318         || (pid != 0 && pid != PerlProc_getpid()))
4319     {
4320         DIE(aTHX_ "setpgrp can't take arguments");
4321     }
4322     SETi( setpgrp() >= 0 );
4323 #endif /* USE_BSDPGRP */
4324     RETURN;
4325 #else
4326     DIE(aTHX_ PL_no_func, "setpgrp()");
4327 #endif
4328 }
4329
4330 PP(pp_getpriority)
4331 {
4332 #ifdef HAS_GETPRIORITY
4333     dSP; dTARGET;
4334     int who = POPi;
4335     int which = TOPi;
4336     SETi( getpriority(which, who) );
4337     RETURN;
4338 #else
4339     DIE(aTHX_ PL_no_func, "getpriority()");
4340 #endif
4341 }
4342
4343 PP(pp_setpriority)
4344 {
4345 #ifdef HAS_SETPRIORITY
4346     dSP; dTARGET;
4347     int niceval = POPi;
4348     int who = POPi;
4349     int which = TOPi;
4350     TAINT_PROPER("setpriority");
4351     SETi( setpriority(which, who, niceval) >= 0 );
4352     RETURN;
4353 #else
4354     DIE(aTHX_ PL_no_func, "setpriority()");
4355 #endif
4356 }
4357
4358 /* Time calls. */
4359
4360 PP(pp_time)
4361 {
4362     dSP; dTARGET;
4363 #ifdef BIG_TIME
4364     XPUSHn( time(Null(Time_t*)) );
4365 #else
4366     XPUSHi( time(Null(Time_t*)) );
4367 #endif
4368     RETURN;
4369 }
4370
4371 PP(pp_tms)
4372 {
4373 #ifdef HAS_TIMES
4374     dSP;
4375     EXTEND(SP, 4);
4376 #ifndef VMS
4377     (void)PerlProc_times(&PL_timesbuf);
4378 #else
4379     (void)PerlProc_times((tbuffer_t *)&PL_timesbuf);  /* time.h uses different name for */
4380                                                    /* struct tms, though same data   */
4381                                                    /* is returned.                   */
4382 #endif
4383
4384     PUSHs(sv_2mortal(newSVnv(((NV)PL_timesbuf.tms_utime)/(NV)PL_clocktick)));
4385     if (GIMME == G_ARRAY) {
4386         PUSHs(sv_2mortal(newSVnv(((NV)PL_timesbuf.tms_stime)/(NV)PL_clocktick)));
4387         PUSHs(sv_2mortal(newSVnv(((NV)PL_timesbuf.tms_cutime)/(NV)PL_clocktick)));
4388         PUSHs(sv_2mortal(newSVnv(((NV)PL_timesbuf.tms_cstime)/(NV)PL_clocktick)));
4389     }
4390     RETURN;
4391 #else
4392 #   ifdef PERL_MICRO
4393     dSP;
4394     PUSHs(sv_2mortal(newSVnv((NV)0.0)));
4395     EXTEND(SP, 4);
4396     if (GIMME == G_ARRAY) {
4397          PUSHs(sv_2mortal(newSVnv((NV)0.0)));
4398          PUSHs(sv_2mortal(newSVnv((NV)0.0)));
4399          PUSHs(sv_2mortal(newSVnv((NV)0.0)));
4400     }
4401     RETURN;
4402 #   else
4403     DIE(aTHX_ "times not implemented");
4404 #   endif
4405 #endif /* HAS_TIMES */
4406 }
4407
4408 PP(pp_localtime)
4409 {
4410     return pp_gmtime();
4411 }
4412
4413 PP(pp_gmtime)
4414 {
4415     dSP;
4416     Time_t when;
4417     struct tm *tmbuf;
4418     static char *dayname[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
4419     static char *monname[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
4420                               "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
4421
4422     if (MAXARG < 1)
4423         (void)time(&when);
4424     else
4425 #ifdef BIG_TIME
4426         when = (Time_t)SvNVx(POPs);
4427 #else
4428         when = (Time_t)SvIVx(POPs);
4429 #endif
4430
4431     if (PL_op->op_type == OP_LOCALTIME)
4432         tmbuf = localtime(&when);
4433     else
4434         tmbuf = gmtime(&when);
4435
4436     if (GIMME != G_ARRAY) {
4437         SV *tsv;
4438         EXTEND(SP, 1);
4439         EXTEND_MORTAL(1);
4440         if (!tmbuf)
4441             RETPUSHUNDEF;
4442         tsv = Perl_newSVpvf(aTHX_ "%s %s %2d %02d:%02d:%02d %d",
4443                             dayname[tmbuf->tm_wday],
4444                             monname[tmbuf->tm_mon],
4445                             tmbuf->tm_mday,
4446                             tmbuf->tm_hour,
4447                             tmbuf->tm_min,
4448                             tmbuf->tm_sec,
4449                             tmbuf->tm_year + 1900);
4450         PUSHs(sv_2mortal(tsv));
4451     }
4452     else if (tmbuf) {
4453         EXTEND(SP, 9);
4454         EXTEND_MORTAL(9);
4455         PUSHs(sv_2mortal(newSViv(tmbuf->tm_sec)));
4456         PUSHs(sv_2mortal(newSViv(tmbuf->tm_min)));
4457         PUSHs(sv_2mortal(newSViv(tmbuf->tm_hour)));
4458         PUSHs(sv_2mortal(newSViv(tmbuf->tm_mday)));
4459         PUSHs(sv_2mortal(newSViv(tmbuf->tm_mon)));
4460         PUSHs(sv_2mortal(newSViv(tmbuf->tm_year)));
4461         PUSHs(sv_2mortal(newSViv(tmbuf->tm_wday)));
4462         PUSHs(sv_2mortal(newSViv(tmbuf->tm_yday)));
4463         PUSHs(sv_2mortal(newSViv(tmbuf->tm_isdst)));
4464     }
4465     RETURN;
4466 }
4467
4468 PP(pp_alarm)
4469 {
4470 #ifdef HAS_ALARM
4471     dSP; dTARGET;
4472     int anum;
4473     anum = POPi;
4474     anum = alarm((unsigned int)anum);
4475     EXTEND(SP, 1);
4476     if (anum < 0)
4477         RETPUSHUNDEF;
4478     PUSHi(anum);
4479     RETURN;
4480 #else
4481     DIE(aTHX_ PL_no_func, "alarm");
4482 #endif
4483 }
4484
4485 PP(pp_sleep)
4486 {
4487     dSP; dTARGET;
4488     I32 duration;
4489     Time_t lasttime;
4490     Time_t when;
4491
4492     (void)time(&lasttime);
4493     if (MAXARG < 1)
4494         PerlProc_pause();
4495     else {
4496         duration = POPi;
4497         PerlProc_sleep((unsigned int)duration);
4498     }
4499     (void)time(&when);
4500     XPUSHi(when - lasttime);
4501     RETURN;
4502 }
4503
4504 /* Shared memory. */
4505
4506 PP(pp_shmget)
4507 {
4508     return pp_semget();
4509 }
4510
4511 PP(pp_shmctl)
4512 {
4513     return pp_semctl();
4514 }
4515
4516 PP(pp_shmread)
4517 {
4518     return pp_shmwrite();
4519 }
4520
4521 PP(pp_shmwrite)
4522 {
4523 #if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
4524     dSP; dMARK; dTARGET;
4525     I32 value = (I32)(do_shmio(PL_op->op_type, MARK, SP) >= 0);
4526     SP = MARK;
4527     PUSHi(value);
4528     RETURN;
4529 #else
4530     return pp_semget();
4531 #endif
4532 }
4533
4534 /* Message passing. */
4535
4536 PP(pp_msgget)
4537 {
4538     return pp_semget();
4539 }
4540
4541 PP(pp_msgctl)
4542 {
4543     return pp_semctl();
4544 }
4545
4546 PP(pp_msgsnd)
4547 {
4548 #if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
4549     dSP; dMARK; dTARGET;
4550     I32 value = (I32)(do_msgsnd(MARK, SP) >= 0);
4551     SP = MARK;
4552     PUSHi(value);
4553     RETURN;
4554 #else
4555     return pp_semget();
4556 #endif
4557 }
4558
4559 PP(pp_msgrcv)
4560 {
4561 #if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
4562     dSP; dMARK; dTARGET;
4563     I32 value = (I32)(do_msgrcv(MARK, SP) >= 0);
4564     SP = MARK;
4565     PUSHi(value);
4566     RETURN;
4567 #else
4568     return pp_semget();
4569 #endif
4570 }
4571
4572 /* Semaphores. */
4573
4574 PP(pp_semget)
4575 {
4576 #if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
4577     dSP; dMARK; dTARGET;
4578     int anum = do_ipcget(PL_op->op_type, MARK, SP);
4579     SP = MARK;
4580     if (anum == -1)
4581         RETPUSHUNDEF;
4582     PUSHi(anum);
4583     RETURN;
4584 #else
4585     DIE(aTHX_ "System V IPC is not implemented on this machine");
4586 #endif
4587 }
4588
4589 PP(pp_semctl)
4590 {
4591 #if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
4592     dSP; dMARK; dTARGET;
4593     int anum = do_ipcctl(PL_op->op_type, MARK, SP);
4594     SP = MARK;
4595     if (anum == -1)
4596         RETSETUNDEF;
4597     if (anum != 0) {
4598         PUSHi(anum);
4599     }
4600     else {
4601         PUSHp(zero_but_true, ZBTLEN);
4602     }
4603     RETURN;
4604 #else
4605     return pp_semget();
4606 #endif
4607 }
4608
4609 PP(pp_semop)
4610 {
4611 #if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
4612     dSP; dMARK; dTARGET;
4613     I32 value = (I32)(do_semop(MARK, SP) >= 0);
4614     SP = MARK;
4615     PUSHi(value);
4616     RETURN;
4617 #else
4618     return pp_semget();
4619 #endif
4620 }
4621
4622 /* Get system info. */
4623
4624 PP(pp_ghbyname)
4625 {
4626 #ifdef HAS_GETHOSTBYNAME
4627     return pp_ghostent();
4628 #else
4629     DIE(aTHX_ PL_no_sock_func, "gethostbyname");
4630 #endif
4631 }
4632
4633 PP(pp_ghbyaddr)
4634 {
4635 #ifdef HAS_GETHOSTBYADDR
4636     return pp_ghostent();
4637 #else
4638     DIE(aTHX_ PL_no_sock_func, "gethostbyaddr");
4639 #endif
4640 }
4641
4642 PP(pp_ghostent)
4643 {
4644 #if defined(HAS_GETHOSTBYNAME) || defined(HAS_GETHOSTBYADDR) || defined(HAS_GETHOSTENT)
4645     dSP;
4646     I32 which = PL_op->op_type;
4647     register char **elem;
4648     register SV *sv;
4649 #ifndef HAS_GETHOST_PROTOS /* XXX Do we need individual probes? */
4650     struct hostent *gethostbyaddr(Netdb_host_t, Netdb_hlen_t, int);
4651     struct hostent *gethostbyname(Netdb_name_t);
4652     struct hostent *gethostent(void);
4653 #endif
4654     struct hostent *hent;
4655     unsigned long len;
4656     STRLEN n_a;
4657
4658     EXTEND(SP, 10);
4659     if (which == OP_GHBYNAME) {
4660 #ifdef HAS_GETHOSTBYNAME
4661         char* name = POPpbytex;
4662         hent = PerlSock_gethostbyname(name);
4663 #else
4664         DIE(aTHX_ PL_no_sock_func, "gethostbyname");
4665 #endif
4666     }
4667     else if (which == OP_GHBYADDR) {
4668 #ifdef HAS_GETHOSTBYADDR
4669         int addrtype = POPi;
4670         SV *addrsv = POPs;
4671         STRLEN addrlen;
4672         Netdb_host_t addr = (Netdb_host_t) SvPVbyte(addrsv, addrlen);
4673
4674         hent = PerlSock_gethostbyaddr(addr, (Netdb_hlen_t) addrlen, addrtype);
4675 #else
4676         DIE(aTHX_ PL_no_sock_func, "gethostbyaddr");
4677 #endif
4678     }
4679     else
4680 #ifdef HAS_GETHOSTENT
4681         hent = PerlSock_gethostent();
4682 #else
4683         DIE(aTHX_ PL_no_sock_func, "gethostent");
4684 #endif
4685
4686 #ifdef HOST_NOT_FOUND
4687         if (!hent) {
4688 #ifdef USE_REENTRANT_API
4689 #   ifdef USE_GETHOSTENT_ERRNO
4690             h_errno = PL_reentrant_buffer->_gethostent_errno;
4691 #   endif
4692 #endif
4693             STATUS_NATIVE_SET(h_errno);
4694         }
4695 #endif
4696
4697     if (GIMME != G_ARRAY) {
4698         PUSHs(sv = sv_newmortal());
4699         if (hent) {
4700             if (which == OP_GHBYNAME) {
4701                 if (hent->h_addr)
4702                     sv_setpvn(sv, hent->h_addr, hent->h_length);
4703             }
4704             else
4705                 sv_setpv(sv, (char*)hent->h_name);
4706         }
4707         RETURN;
4708     }
4709
4710     if (hent) {
4711         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
4712         sv_setpv(sv, (char*)hent->h_name);
4713         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
4714         for (elem = hent->h_aliases; elem && *elem; elem++) {
4715             sv_catpv(sv, *elem);
4716             if (elem[1])
4717                 sv_catpvn(sv, " ", 1);
4718         }
4719         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
4720         sv_setiv(sv, (IV)hent->h_addrtype);
4721         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
4722         len = hent->h_length;
4723         sv_setiv(sv, (IV)len);
4724 #ifdef h_addr
4725         for (elem = hent->h_addr_list; elem && *elem; elem++) {
4726             XPUSHs(sv = sv_mortalcopy(&PL_sv_no));
4727             sv_setpvn(sv, *elem, len);
4728         }
4729 #else
4730         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
4731         if (hent->h_addr)
4732             sv_setpvn(sv, hent->h_addr, len);
4733 #endif /* h_addr */
4734     }
4735     RETURN;
4736 #else
4737     DIE(aTHX_ PL_no_sock_func, "gethostent");
4738 #endif
4739 }
4740
4741 PP(pp_gnbyname)
4742 {
4743 #ifdef HAS_GETNETBYNAME
4744     return pp_gnetent();
4745 #else
4746     DIE(aTHX_ PL_no_sock_func, "getnetbyname");
4747 #endif
4748 }
4749
4750 PP(pp_gnbyaddr)
4751 {
4752 #ifdef HAS_GETNETBYADDR
4753     return pp_gnetent();
4754 #else
4755     DIE(aTHX_ PL_no_sock_func, "getnetbyaddr");
4756 #endif
4757 }
4758
4759 PP(pp_gnetent)
4760 {
4761 #if defined(HAS_GETNETBYNAME) || defined(HAS_GETNETBYADDR) || defined(HAS_GETNETENT)
4762     dSP;
4763     I32 which = PL_op->op_type;
4764     register char **elem;
4765     register SV *sv;
4766 #ifndef HAS_GETNET_PROTOS /* XXX Do we need individual probes? */
4767     struct netent *getnetbyaddr(Netdb_net_t, int);
4768     struct netent *getnetbyname(Netdb_name_t);
4769     struct netent *getnetent(void);
4770 #endif
4771     struct netent *nent;
4772     STRLEN n_a;
4773
4774     if (which == OP_GNBYNAME){
4775 #ifdef HAS_GETNETBYNAME
4776         char *name = POPpbytex;
4777         nent = PerlSock_getnetbyname(name);
4778 #else
4779         DIE(aTHX_ PL_no_sock_func, "getnetbyname");
4780 #endif
4781     }
4782     else if (which == OP_GNBYADDR) {
4783 #ifdef HAS_GETNETBYADDR
4784         int addrtype = POPi;
4785         Netdb_net_t addr = (Netdb_net_t) (U32)POPu;
4786         nent = PerlSock_getnetbyaddr(addr, addrtype);
4787 #else
4788         DIE(aTHX_ PL_no_sock_func, "getnetbyaddr");
4789 #endif
4790     }
4791     else
4792 #ifdef HAS_GETNETENT
4793         nent = PerlSock_getnetent();
4794 #else
4795         DIE(aTHX_ PL_no_sock_func, "getnetent");
4796 #endif
4797
4798 #ifdef HOST_NOT_FOUND
4799         if (!nent) {
4800 #ifdef USE_REENTRANT_API
4801 #   ifdef USE_GETNETENT_ERRNO
4802              h_errno = PL_reentrant_buffer->_getnetent_errno;
4803 #   endif
4804 #endif
4805             STATUS_NATIVE_SET(h_errno);
4806         }
4807 #endif
4808
4809     EXTEND(SP, 4);
4810     if (GIMME != G_ARRAY) {
4811         PUSHs(sv = sv_newmortal());
4812         if (nent) {
4813             if (which == OP_GNBYNAME)
4814                 sv_setiv(sv, (IV)nent->n_net);
4815             else
4816                 sv_setpv(sv, nent->n_name);
4817         }
4818         RETURN;
4819     }
4820
4821     if (nent) {
4822         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
4823         sv_setpv(sv, nent->n_name);
4824         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
4825         for (elem = nent->n_aliases; elem && *elem; elem++) {
4826             sv_catpv(sv, *elem);
4827             if (elem[1])
4828                 sv_catpvn(sv, " ", 1);
4829         }
4830         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
4831         sv_setiv(sv, (IV)nent->n_addrtype);
4832         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
4833         sv_setiv(sv, (IV)nent->n_net);
4834     }
4835
4836     RETURN;
4837 #else
4838     DIE(aTHX_ PL_no_sock_func, "getnetent");
4839 #endif
4840 }
4841
4842 PP(pp_gpbyname)
4843 {
4844 #ifdef HAS_GETPROTOBYNAME
4845     return pp_gprotoent();
4846 #else
4847     DIE(aTHX_ PL_no_sock_func, "getprotobyname");
4848 #endif
4849 }
4850
4851 PP(pp_gpbynumber)
4852 {
4853 #ifdef HAS_GETPROTOBYNUMBER
4854     return pp_gprotoent();
4855 #else
4856     DIE(aTHX_ PL_no_sock_func, "getprotobynumber");
4857 #endif
4858 }
4859
4860 PP(pp_gprotoent)
4861 {
4862 #if defined(HAS_GETPROTOBYNAME) || defined(HAS_GETPROTOBYNUMBER) || defined(HAS_GETPROTOENT)
4863     dSP;
4864     I32 which = PL_op->op_type;
4865     register char **elem;
4866     register SV *sv;
4867 #ifndef HAS_GETPROTO_PROTOS /* XXX Do we need individual probes? */
4868     struct protoent *getprotobyname(Netdb_name_t);
4869     struct protoent *getprotobynumber(int);
4870     struct protoent *getprotoent(void);
4871 #endif
4872     struct protoent *pent;
4873     STRLEN n_a;
4874
4875     if (which == OP_GPBYNAME) {
4876 #ifdef HAS_GETPROTOBYNAME
4877         char* name = POPpbytex;
4878         pent = PerlSock_getprotobyname(name);
4879 #else
4880         DIE(aTHX_ PL_no_sock_func, "getprotobyname");
4881 #endif
4882     }
4883     else if (which == OP_GPBYNUMBER) {
4884 #ifdef HAS_GETPROTOBYNUMBER
4885         int number = POPi;
4886         pent = PerlSock_getprotobynumber(number);
4887 #else
4888         DIE(aTHX_ PL_no_sock_func, "getprotobynumber");
4889 #endif
4890     }
4891     else
4892 #ifdef HAS_GETPROTOENT
4893         pent = PerlSock_getprotoent();
4894 #else
4895         DIE(aTHX_ PL_no_sock_func, "getprotoent");
4896 #endif
4897
4898     EXTEND(SP, 3);
4899     if (GIMME != G_ARRAY) {
4900         PUSHs(sv = sv_newmortal());
4901         if (pent) {
4902             if (which == OP_GPBYNAME)
4903                 sv_setiv(sv, (IV)pent->p_proto);
4904             else
4905                 sv_setpv(sv, pent->p_name);
4906         }
4907         RETURN;
4908     }
4909
4910     if (pent) {
4911         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
4912         sv_setpv(sv, pent->p_name);
4913         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
4914         for (elem = pent->p_aliases; elem && *elem; elem++) {
4915             sv_catpv(sv, *elem);
4916             if (elem[1])
4917                 sv_catpvn(sv, " ", 1);
4918         }
4919         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
4920         sv_setiv(sv, (IV)pent->p_proto);
4921     }
4922
4923     RETURN;
4924 #else
4925     DIE(aTHX_ PL_no_sock_func, "getprotoent");
4926 #endif
4927 }
4928
4929 PP(pp_gsbyname)
4930 {
4931 #ifdef HAS_GETSERVBYNAME
4932     return pp_gservent();
4933 #else
4934     DIE(aTHX_ PL_no_sock_func, "getservbyname");
4935 #endif
4936 }
4937
4938 PP(pp_gsbyport)
4939 {
4940 #ifdef HAS_GETSERVBYPORT
4941     return pp_gservent();
4942 #else
4943     DIE(aTHX_ PL_no_sock_func, "getservbyport");
4944 #endif
4945 }
4946
4947 PP(pp_gservent)
4948 {
4949 #if defined(HAS_GETSERVBYNAME) || defined(HAS_GETSERVBYPORT) || defined(HAS_GETSERVENT)
4950     dSP;
4951     I32 which = PL_op->op_type;
4952     register char **elem;
4953     register SV *sv;
4954 #ifndef HAS_GETSERV_PROTOS /* XXX Do we need individual probes? */
4955     struct servent *getservbyname(Netdb_name_t, Netdb_name_t);
4956     struct servent *getservbyport(int, Netdb_name_t);
4957     struct servent *getservent(void);
4958 #endif
4959     struct servent *sent;
4960     STRLEN n_a;
4961
4962     if (which == OP_GSBYNAME) {
4963 #ifdef HAS_GETSERVBYNAME
4964         char *proto = POPpbytex;
4965         char *name = POPpbytex;
4966
4967         if (proto && !*proto)
4968             proto = Nullch;
4969
4970         sent = PerlSock_getservbyname(name, proto);
4971 #else
4972         DIE(aTHX_ PL_no_sock_func, "getservbyname");
4973 #endif
4974     }
4975     else if (which == OP_GSBYPORT) {
4976 #ifdef HAS_GETSERVBYPORT
4977         char *proto = POPpbytex;
4978         unsigned short port = (unsigned short)POPu;
4979
4980         if (proto && !*proto)
4981             proto = Nullch;
4982
4983 #ifdef HAS_HTONS
4984         port = PerlSock_htons(port);
4985 #endif
4986         sent = PerlSock_getservbyport(port, proto);
4987 #else
4988         DIE(aTHX_ PL_no_sock_func, "getservbyport");
4989 #endif
4990     }
4991     else
4992 #ifdef HAS_GETSERVENT
4993         sent = PerlSock_getservent();
4994 #else
4995         DIE(aTHX_ PL_no_sock_func, "getservent");
4996 #endif
4997
4998     EXTEND(SP, 4);
4999     if (GIMME != G_ARRAY) {
5000         PUSHs(sv = sv_newmortal());
5001         if (sent) {
5002             if (which == OP_GSBYNAME) {
5003 #ifdef HAS_NTOHS
5004                 sv_setiv(sv, (IV)PerlSock_ntohs(sent->s_port));
5005 #else
5006                 sv_setiv(sv, (IV)(sent->s_port));
5007 #endif
5008             }
5009             else
5010                 sv_setpv(sv, sent->s_name);
5011         }
5012         RETURN;
5013     }
5014
5015     if (sent) {
5016         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
5017         sv_setpv(sv, sent->s_name);
5018         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
5019         for (elem = sent->s_aliases; elem && *elem; elem++) {
5020             sv_catpv(sv, *elem);
5021             if (elem[1])
5022                 sv_catpvn(sv, " ", 1);
5023         }
5024         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
5025 #ifdef HAS_NTOHS
5026         sv_setiv(sv, (IV)PerlSock_ntohs(sent->s_port));
5027 #else
5028         sv_setiv(sv, (IV)(sent->s_port));
5029 #endif
5030         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
5031         sv_setpv(sv, sent->s_proto);
5032     }
5033
5034     RETURN;
5035 #else
5036     DIE(aTHX_ PL_no_sock_func, "getservent");
5037 #endif
5038 }
5039
5040 PP(pp_shostent)
5041 {
5042 #ifdef HAS_SETHOSTENT
5043     dSP;
5044     PerlSock_sethostent(TOPi);
5045     RETSETYES;
5046 #else
5047     DIE(aTHX_ PL_no_sock_func, "sethostent");
5048 #endif
5049 }
5050
5051 PP(pp_snetent)
5052 {
5053 #ifdef HAS_SETNETENT
5054     dSP;
5055     PerlSock_setnetent(TOPi);
5056     RETSETYES;
5057 #else
5058     DIE(aTHX_ PL_no_sock_func, "setnetent");
5059 #endif
5060 }
5061
5062 PP(pp_sprotoent)
5063 {
5064 #ifdef HAS_SETPROTOENT
5065     dSP;
5066     PerlSock_setprotoent(TOPi);
5067     RETSETYES;
5068 #else
5069     DIE(aTHX_ PL_no_sock_func, "setprotoent");
5070 #endif
5071 }
5072
5073 PP(pp_sservent)
5074 {
5075 #ifdef HAS_SETSERVENT
5076     dSP;
5077     PerlSock_setservent(TOPi);
5078     RETSETYES;
5079 #else
5080     DIE(aTHX_ PL_no_sock_func, "setservent");
5081 #endif
5082 }
5083
5084 PP(pp_ehostent)
5085 {
5086 #ifdef HAS_ENDHOSTENT
5087     dSP;
5088     PerlSock_endhostent();
5089     EXTEND(SP,1);
5090     RETPUSHYES;
5091 #else
5092     DIE(aTHX_ PL_no_sock_func, "endhostent");
5093 #endif
5094 }
5095
5096 PP(pp_enetent)
5097 {
5098 #ifdef HAS_ENDNETENT
5099     dSP;
5100     PerlSock_endnetent();
5101     EXTEND(SP,1);
5102     RETPUSHYES;
5103 #else
5104     DIE(aTHX_ PL_no_sock_func, "endnetent");
5105 #endif
5106 }
5107
5108 PP(pp_eprotoent)
5109 {
5110 #ifdef HAS_ENDPROTOENT
5111     dSP;
5112     PerlSock_endprotoent();
5113     EXTEND(SP,1);
5114     RETPUSHYES;
5115 #else
5116     DIE(aTHX_ PL_no_sock_func, "endprotoent");
5117 #endif
5118 }
5119
5120 PP(pp_eservent)
5121 {
5122 #ifdef HAS_ENDSERVENT
5123     dSP;
5124     PerlSock_endservent();
5125     EXTEND(SP,1);
5126     RETPUSHYES;
5127 #else
5128     DIE(aTHX_ PL_no_sock_func, "endservent");
5129 #endif
5130 }
5131
5132 PP(pp_gpwnam)
5133 {
5134 #ifdef HAS_PASSWD
5135     return pp_gpwent();
5136 #else
5137     DIE(aTHX_ PL_no_func, "getpwnam");
5138 #endif
5139 }
5140
5141 PP(pp_gpwuid)
5142 {
5143 #ifdef HAS_PASSWD
5144     return pp_gpwent();
5145 #else
5146     DIE(aTHX_ PL_no_func, "getpwuid");
5147 #endif
5148 }
5149
5150 PP(pp_gpwent)
5151 {
5152 #ifdef HAS_PASSWD
5153     dSP;
5154     I32 which = PL_op->op_type;
5155     register SV *sv;
5156     STRLEN n_a;
5157     struct passwd *pwent  = NULL;
5158     /*
5159      * We currently support only the SysV getsp* shadow password interface.
5160      * The interface is declared in <shadow.h> and often one needs to link
5161      * with -lsecurity or some such.
5162      * This interface is used at least by Solaris, HP-UX, IRIX, and Linux.
5163      * (and SCO?)
5164      *
5165      * AIX getpwnam() is clever enough to return the encrypted password
5166      * only if the caller (euid?) is root.
5167      *
5168      * There are at least three other shadow password APIs.  Many platforms
5169      * seem to contain more than one interface for accessing the shadow
5170      * password databases, possibly for compatibility reasons.
5171      * The getsp*() is by far he simplest one, the other two interfaces
5172      * are much more complicated, but also very similar to each other.
5173      *
5174      * <sys/types.h>
5175      * <sys/security.h>
5176      * <prot.h>
5177      * struct pr_passwd *getprpw*();
5178      * The password is in
5179      * char getprpw*(...).ufld.fd_encrypt[]
5180      * Mention HAS_GETPRPWNAM here so that Configure probes for it.
5181      *
5182      * <sys/types.h>
5183      * <sys/security.h>
5184      * <prot.h>
5185      * struct es_passwd *getespw*();
5186      * The password is in
5187      * char *(getespw*(...).ufld.fd_encrypt)
5188      * Mention HAS_GETESPWNAM here so that Configure probes for it.
5189      *
5190      * <userpw.h> (AIX)
5191      * struct userpw *getuserpw();
5192      * The password is in
5193      * char *(getuserpw(...)).spw_upw_passwd
5194      * (but the de facto standard getpwnam() should work okay)
5195      *
5196      * Mention I_PROT here so that Configure probes for it.
5197      *
5198      * In HP-UX for getprpw*() the manual page claims that one should include
5199      * <hpsecurity.h> instead of <sys/security.h>, but that is not needed
5200      * if one includes <shadow.h> as that includes <hpsecurity.h>,
5201      * and pp_sys.c already includes <shadow.h> if there is such.
5202      *
5203      * Note that <sys/security.h> is already probed for, but currently
5204      * it is only included in special cases.
5205      *
5206      * In Digital UNIX/Tru64 if using the getespw*() (which seems to be
5207      * be preferred interface, even though also the getprpw*() interface
5208      * is available) one needs to link with -lsecurity -ldb -laud -lm.
5209      * One also needs to call set_auth_parameters() in main() before
5210      * doing anything else, whether one is using getespw*() or getprpw*().
5211      *
5212      * Note that accessing the shadow databases can be magnitudes
5213      * slower than accessing the standard databases.
5214      *
5215      * --jhi
5216      */
5217
5218     switch (which) {
5219     case OP_GPWNAM:
5220       {
5221         char* name = POPpbytex;
5222         pwent  = getpwnam(name);
5223       }
5224       break;
5225     case OP_GPWUID:
5226       {
5227         Uid_t uid = POPi;
5228         pwent = getpwuid(uid);
5229       }
5230         break;
5231     case OP_GPWENT:
5232 #   ifdef HAS_GETPWENT
5233         pwent  = getpwent();
5234 #ifdef POSIX_BC   /* In some cases pw_passwd has invalid addresses */
5235         if (pwent) pwent = getpwnam(pwent->pw_name);
5236 #endif
5237 #   else
5238         DIE(aTHX_ PL_no_func, "getpwent");
5239 #   endif
5240         break;
5241     }
5242
5243     EXTEND(SP, 10);
5244     if (GIMME != G_ARRAY) {
5245         PUSHs(sv = sv_newmortal());
5246         if (pwent) {
5247             if (which == OP_GPWNAM)
5248 #   if Uid_t_sign <= 0
5249                 sv_setiv(sv, (IV)pwent->pw_uid);
5250 #   else
5251                 sv_setuv(sv, (UV)pwent->pw_uid);
5252 #   endif
5253             else
5254                 sv_setpv(sv, pwent->pw_name);
5255         }
5256         RETURN;
5257     }
5258
5259     if (pwent) {
5260         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
5261         sv_setpv(sv, pwent->pw_name);
5262
5263         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
5264         SvPOK_off(sv);
5265         /* If we have getspnam(), we try to dig up the shadow
5266          * password.  If we are underprivileged, the shadow
5267          * interface will set the errno to EACCES or similar,
5268          * and return a null pointer.  If this happens, we will
5269          * use the dummy password (usually "*" or "x") from the
5270          * standard password database.
5271          *
5272          * In theory we could skip the shadow call completely
5273          * if euid != 0 but in practice we cannot know which
5274          * security measures are guarding the shadow databases
5275          * on a random platform.
5276          *
5277          * Resist the urge to use additional shadow interfaces.
5278          * Divert the urge to writing an extension instead.
5279          *
5280          * --jhi */
5281         /* Some AIX setups falsely(?) detect some getspnam(), which
5282          * has a different API than the Solaris/IRIX one. */
5283 #   if defined(HAS_GETSPNAM) && !defined(_AIX)
5284         {
5285             struct spwd *spwent;
5286             int saverrno; /* Save and restore errno so that
5287                            * underprivileged attempts seem
5288                            * to have never made the unsccessful
5289                            * attempt to retrieve the shadow password. */
5290
5291             saverrno = errno;
5292             spwent = getspnam(pwent->pw_name);
5293             errno = saverrno;
5294             if (spwent && spwent->sp_pwdp)
5295                 sv_setpv(sv, spwent->sp_pwdp);
5296         }
5297 #   endif
5298 #   ifdef PWPASSWD
5299         if (!SvPOK(sv)) /* Use the standard password, then. */
5300             sv_setpv(sv, pwent->pw_passwd);
5301 #   endif
5302
5303 #   ifndef INCOMPLETE_TAINTS
5304         /* passwd is tainted because user himself can diddle with it.
5305          * admittedly not much and in a very limited way, but nevertheless. */
5306         SvTAINTED_on(sv);
5307 #   endif
5308
5309         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
5310 #   if Uid_t_sign <= 0
5311         sv_setiv(sv, (IV)pwent->pw_uid);
5312 #   else
5313         sv_setuv(sv, (UV)pwent->pw_uid);
5314 #   endif
5315
5316         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
5317 #   if Uid_t_sign <= 0
5318         sv_setiv(sv, (IV)pwent->pw_gid);
5319 #   else
5320         sv_setuv(sv, (UV)pwent->pw_gid);
5321 #   endif
5322         /* pw_change, pw_quota, and pw_age are mutually exclusive--
5323          * because of the poor interface of the Perl getpw*(),
5324          * not because there's some standard/convention saying so.
5325          * A better interface would have been to return a hash,
5326          * but we are accursed by our history, alas. --jhi.  */
5327         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
5328 #   ifdef PWCHANGE
5329         sv_setiv(sv, (IV)pwent->pw_change);
5330 #   else
5331 #       ifdef PWQUOTA
5332         sv_setiv(sv, (IV)pwent->pw_quota);
5333 #       else
5334 #           ifdef PWAGE
5335         sv_setpv(sv, pwent->pw_age);
5336 #           endif
5337 #       endif
5338 #   endif
5339
5340         /* pw_class and pw_comment are mutually exclusive--.
5341          * see the above note for pw_change, pw_quota, and pw_age. */
5342         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
5343 #   ifdef PWCLASS
5344         sv_setpv(sv, pwent->pw_class);
5345 #   else
5346 #       ifdef PWCOMMENT
5347         sv_setpv(sv, pwent->pw_comment);
5348 #       endif
5349 #   endif
5350
5351         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
5352 #   ifdef PWGECOS
5353         sv_setpv(sv, pwent->pw_gecos);
5354 #   endif
5355 #   ifndef INCOMPLETE_TAINTS
5356         /* pw_gecos is tainted because user himself can diddle with it. */
5357         SvTAINTED_on(sv);
5358 #   endif
5359
5360         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
5361         sv_setpv(sv, pwent->pw_dir);
5362
5363         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
5364         sv_setpv(sv, pwent->pw_shell);
5365 #   ifndef INCOMPLETE_TAINTS
5366         /* pw_shell is tainted because user himself can diddle with it. */
5367         SvTAINTED_on(sv);
5368 #   endif
5369
5370 #   ifdef PWEXPIRE
5371         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
5372         sv_setiv(sv, (IV)pwent->pw_expire);
5373 #   endif
5374     }
5375     RETURN;
5376 #else
5377     DIE(aTHX_ PL_no_func, "getpwent");
5378 #endif
5379 }
5380
5381 PP(pp_spwent)
5382 {
5383 #if defined(HAS_PASSWD) && defined(HAS_SETPWENT)
5384     dSP;
5385     setpwent();
5386     RETPUSHYES;
5387 #else
5388     DIE(aTHX_ PL_no_func, "setpwent");
5389 #endif
5390 }
5391
5392 PP(pp_epwent)
5393 {
5394 #if defined(HAS_PASSWD) && defined(HAS_ENDPWENT)
5395     dSP;
5396     endpwent();
5397     RETPUSHYES;
5398 #else
5399     DIE(aTHX_ PL_no_func, "endpwent");
5400 #endif
5401 }
5402
5403 PP(pp_ggrnam)
5404 {
5405 #ifdef HAS_GROUP
5406     return pp_ggrent();
5407 #else
5408     DIE(aTHX_ PL_no_func, "getgrnam");
5409 #endif
5410 }
5411
5412 PP(pp_ggrgid)
5413 {
5414 #ifdef HAS_GROUP
5415     return pp_ggrent();
5416 #else
5417     DIE(aTHX_ PL_no_func, "getgrgid");
5418 #endif
5419 }
5420
5421 PP(pp_ggrent)
5422 {
5423 #ifdef HAS_GROUP
5424     dSP;
5425     I32 which = PL_op->op_type;
5426     register char **elem;
5427     register SV *sv;
5428     struct group *grent;
5429     STRLEN n_a;
5430
5431     if (which == OP_GGRNAM) {
5432         char* name = POPpbytex;
5433         grent = (struct group *)getgrnam(name);
5434     }
5435     else if (which == OP_GGRGID) {
5436         Gid_t gid = POPi;
5437         grent = (struct group *)getgrgid(gid);
5438     }
5439     else
5440 #ifdef HAS_GETGRENT
5441         grent = (struct group *)getgrent();
5442 #else
5443         DIE(aTHX_ PL_no_func, "getgrent");
5444 #endif
5445
5446     EXTEND(SP, 4);
5447     if (GIMME != G_ARRAY) {
5448         PUSHs(sv = sv_newmortal());
5449         if (grent) {
5450             if (which == OP_GGRNAM)
5451                 sv_setiv(sv, (IV)grent->gr_gid);
5452             else
5453                 sv_setpv(sv, grent->gr_name);
5454         }
5455         RETURN;
5456     }
5457
5458     if (grent) {
5459         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
5460         sv_setpv(sv, grent->gr_name);
5461
5462         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
5463 #ifdef GRPASSWD
5464         sv_setpv(sv, grent->gr_passwd);
5465 #endif
5466
5467         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
5468         sv_setiv(sv, (IV)grent->gr_gid);
5469
5470 #if !(defined(_CRAYMPP) && defined(USE_REENTRANT_API))
5471         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
5472         /* In UNICOS/mk (_CRAYMPP) the multithreading
5473          * versions (getgrnam_r, getgrgid_r)
5474          * seem to return an illegal pointer
5475          * as the group members list, gr_mem.
5476          * getgrent() doesn't even have a _r version
5477          * but the gr_mem is poisonous anyway.
5478          * So yes, you cannot get the list of group
5479          * members if building multithreaded in UNICOS/mk. */
5480         for (elem = grent->gr_mem; elem && *elem; elem++) {
5481             sv_catpv(sv, *elem);
5482             if (elem[1])
5483                 sv_catpvn(sv, " ", 1);
5484         }
5485 #endif
5486     }
5487
5488     RETURN;
5489 #else
5490     DIE(aTHX_ PL_no_func, "getgrent");
5491 #endif
5492 }
5493
5494 PP(pp_sgrent)
5495 {
5496 #if defined(HAS_GROUP) && defined(HAS_SETGRENT)
5497     dSP;
5498     setgrent();
5499     RETPUSHYES;
5500 #else
5501     DIE(aTHX_ PL_no_func, "setgrent");
5502 #endif
5503 }
5504
5505 PP(pp_egrent)
5506 {
5507 #if defined(HAS_GROUP) && defined(HAS_ENDGRENT)
5508     dSP;
5509     endgrent();
5510     RETPUSHYES;
5511 #else
5512     DIE(aTHX_ PL_no_func, "endgrent");
5513 #endif
5514 }
5515
5516 PP(pp_getlogin)
5517 {
5518 #ifdef HAS_GETLOGIN
5519     dSP; dTARGET;
5520     char *tmps;
5521     EXTEND(SP, 1);
5522     if (!(tmps = PerlProc_getlogin()))
5523         RETPUSHUNDEF;
5524     PUSHp(tmps, strlen(tmps));
5525     RETURN;
5526 #else
5527     DIE(aTHX_ PL_no_func, "getlogin");
5528 #endif
5529 }
5530
5531 /* Miscellaneous. */
5532
5533 PP(pp_syscall)
5534 {
5535 #ifdef HAS_SYSCALL
5536     dSP; dMARK; dORIGMARK; dTARGET;
5537     register I32 items = SP - MARK;
5538     unsigned long a[20];
5539     register I32 i = 0;
5540     I32 retval = -1;
5541     STRLEN n_a;
5542
5543     if (PL_tainting) {
5544         while (++MARK <= SP) {
5545             if (SvTAINTED(*MARK)) {
5546                 TAINT;
5547                 break;
5548             }
5549         }
5550         MARK = ORIGMARK;
5551         TAINT_PROPER("syscall");
5552     }
5553
5554     /* This probably won't work on machines where sizeof(long) != sizeof(int)
5555      * or where sizeof(long) != sizeof(char*).  But such machines will
5556      * not likely have syscall implemented either, so who cares?
5557      */
5558     while (++MARK <= SP) {
5559         if (SvNIOK(*MARK) || !i)
5560             a[i++] = SvIV(*MARK);
5561         else if (*MARK == &PL_sv_undef)
5562             a[i++] = 0;
5563         else
5564             a[i++] = (unsigned long)SvPV_force(*MARK, n_a);
5565         if (i > 15)
5566             break;
5567     }
5568     switch (items) {
5569     default:
5570         DIE(aTHX_ "Too many args to syscall");
5571     case 0:
5572         DIE(aTHX_ "Too few args to syscall");
5573     case 1:
5574         retval = syscall(a[0]);
5575         break;
5576     case 2:
5577         retval = syscall(a[0],a[1]);
5578         break;
5579     case 3:
5580         retval = syscall(a[0],a[1],a[2]);
5581         break;
5582     case 4:
5583         retval = syscall(a[0],a[1],a[2],a[3]);
5584         break;
5585     case 5:
5586         retval = syscall(a[0],a[1],a[2],a[3],a[4]);
5587         break;
5588     case 6:
5589         retval = syscall(a[0],a[1],a[2],a[3],a[4],a[5]);
5590         break;
5591     case 7:
5592         retval = syscall(a[0],a[1],a[2],a[3],a[4],a[5],a[6]);
5593         break;
5594     case 8:
5595         retval = syscall(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7]);
5596         break;
5597 #ifdef atarist
5598     case 9:
5599         retval = syscall(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8]);
5600         break;
5601     case 10:
5602         retval = syscall(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9]);
5603         break;
5604     case 11:
5605         retval = syscall(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9],
5606           a[10]);
5607         break;
5608     case 12:
5609         retval = syscall(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9],
5610           a[10],a[11]);
5611         break;
5612     case 13:
5613         retval = syscall(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9],
5614           a[10],a[11],a[12]);
5615         break;
5616     case 14:
5617         retval = syscall(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9],
5618           a[10],a[11],a[12],a[13]);
5619         break;
5620 #endif /* atarist */
5621     }
5622     SP = ORIGMARK;
5623     PUSHi(retval);
5624     RETURN;
5625 #else
5626     DIE(aTHX_ PL_no_func, "syscall");
5627 #endif
5628 }
5629
5630 #ifdef FCNTL_EMULATE_FLOCK
5631
5632 /*  XXX Emulate flock() with fcntl().
5633     What's really needed is a good file locking module.
5634 */
5635
5636 static int
5637 fcntl_emulate_flock(int fd, int operation)
5638 {
5639     struct flock flock;
5640
5641     switch (operation & ~LOCK_NB) {
5642     case LOCK_SH:
5643         flock.l_type = F_RDLCK;
5644         break;
5645     case LOCK_EX:
5646         flock.l_type = F_WRLCK;
5647         break;
5648     case LOCK_UN:
5649         flock.l_type = F_UNLCK;
5650         break;
5651     default:
5652         errno = EINVAL;
5653         return -1;
5654     }
5655     flock.l_whence = SEEK_SET;
5656     flock.l_start = flock.l_len = (Off_t)0;
5657
5658     return fcntl(fd, (operation & LOCK_NB) ? F_SETLK : F_SETLKW, &flock);
5659 }
5660
5661 #endif /* FCNTL_EMULATE_FLOCK */
5662
5663 #ifdef LOCKF_EMULATE_FLOCK
5664
5665 /*  XXX Emulate flock() with lockf().  This is just to increase
5666     portability of scripts.  The calls are not completely
5667     interchangeable.  What's really needed is a good file
5668     locking module.
5669 */
5670
5671 /*  The lockf() constants might have been defined in <unistd.h>.
5672     Unfortunately, <unistd.h> causes troubles on some mixed
5673     (BSD/POSIX) systems, such as SunOS 4.1.3.
5674
5675    Further, the lockf() constants aren't POSIX, so they might not be
5676    visible if we're compiling with _POSIX_SOURCE defined.  Thus, we'll
5677    just stick in the SVID values and be done with it.  Sigh.
5678 */
5679
5680 # ifndef F_ULOCK
5681 #  define F_ULOCK       0       /* Unlock a previously locked region */
5682 # endif
5683 # ifndef F_LOCK
5684 #  define F_LOCK        1       /* Lock a region for exclusive use */
5685 # endif
5686 # ifndef F_TLOCK
5687 #  define F_TLOCK       2       /* Test and lock a region for exclusive use */
5688 # endif
5689 # ifndef F_TEST
5690 #  define F_TEST        3       /* Test a region for other processes locks */
5691 # endif
5692
5693 static int
5694 lockf_emulate_flock(int fd, int operation)
5695 {
5696     int i;
5697     int save_errno;
5698     Off_t pos;
5699
5700     /* flock locks entire file so for lockf we need to do the same      */
5701     save_errno = errno;
5702     pos = PerlLIO_lseek(fd, (Off_t)0, SEEK_CUR);    /* get pos to restore later */
5703     if (pos > 0)        /* is seekable and needs to be repositioned     */
5704         if (PerlLIO_lseek(fd, (Off_t)0, SEEK_SET) < 0)
5705             pos = -1;   /* seek failed, so don't seek back afterwards   */
5706     errno = save_errno;
5707
5708     switch (operation) {
5709
5710         /* LOCK_SH - get a shared lock */
5711         case LOCK_SH:
5712         /* LOCK_EX - get an exclusive lock */
5713         case LOCK_EX:
5714             i = lockf (fd, F_LOCK, 0);
5715             break;
5716
5717         /* LOCK_SH|LOCK_NB - get a non-blocking shared lock */
5718         case LOCK_SH|LOCK_NB:
5719         /* LOCK_EX|LOCK_NB - get a non-blocking exclusive lock */
5720         case LOCK_EX|LOCK_NB:
5721             i = lockf (fd, F_TLOCK, 0);
5722             if (i == -1)
5723                 if ((errno == EAGAIN) || (errno == EACCES))
5724                     errno = EWOULDBLOCK;
5725             break;
5726
5727         /* LOCK_UN - unlock (non-blocking is a no-op) */
5728         case LOCK_UN:
5729         case LOCK_UN|LOCK_NB:
5730             i = lockf (fd, F_ULOCK, 0);
5731             break;
5732
5733         /* Default - can't decipher operation */
5734         default:
5735             i = -1;
5736             errno = EINVAL;
5737             break;
5738     }
5739
5740     if (pos > 0)      /* need to restore position of the handle */
5741         PerlLIO_lseek(fd, pos, SEEK_SET);       /* ignore error here    */
5742
5743     return (i);
5744 }
5745
5746 #endif /* LOCKF_EMULATE_FLOCK */