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