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