Fix worrying typo in handy.h :-s
[p5sagit/p5-mst-13.2.git] / pp_sys.c
1 /*    pp_sys.c
2  *
3  *    Copyright (C) 1995, 1996, 1997, 1998, 1999,
4  *    2000, 2001, 2002, 2003, 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 (void);
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((char*)tmps, (char *)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_SET(PerlProc_pclose(fp));
382         TAINT;          /* "I believe that this is not gratuitous!" */
383     }
384     else {
385         STATUS_NATIVE_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_NULL;
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, (char *)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 (ckWARN(WARN_UNTIE)) {
911                if (mg && SvREFCNT(obj) > 1)
912                   Perl_warner(aTHX_ packWARN(WARN_UNTIE),
913                       "untie attempted while %"UVuf" inner references still exist",
914                        (UV)SvREFCNT(obj) - 1 ) ;
915            }
916         }
917     }
918     sv_unmagic(sv, how) ;
919     RETPUSHYES;
920 }
921
922 PP(pp_tied)
923 {
924     dSP;
925     const MAGIC *mg;
926     SV *sv = POPs;
927     const char how = (SvTYPE(sv) == SVt_PVHV || SvTYPE(sv) == SVt_PVAV)
928                 ? PERL_MAGIC_tied : PERL_MAGIC_tiedscalar;
929
930     if (SvTYPE(sv) == SVt_PVGV && !(sv = (SV *)GvIOp(sv)))
931         RETPUSHUNDEF;
932
933     if ((mg = SvTIED_mg(sv, how))) {
934         SV *osv = SvTIED_obj(sv, mg);
935         if (osv == mg->mg_obj)
936             osv = sv_mortalcopy(osv);
937         PUSHs(osv);
938         RETURN;
939     }
940     RETPUSHUNDEF;
941 }
942
943 PP(pp_dbmopen)
944 {
945     dVAR; dSP;
946     dPOPPOPssrl;
947     HV* stash;
948     GV *gv;
949     SV *sv;
950
951     HV * const hv = (HV*)POPs;
952
953     sv = sv_mortalcopy(&PL_sv_no);
954     sv_setpv(sv, "AnyDBM_File");
955     stash = gv_stashsv(sv, FALSE);
956     if (!stash || !(gv = gv_fetchmethod(stash, "TIEHASH"))) {
957         PUTBACK;
958         require_pv("AnyDBM_File.pm");
959         SPAGAIN;
960         if (!(gv = gv_fetchmethod(stash, "TIEHASH")))
961             DIE(aTHX_ "No dbm on this machine");
962     }
963
964     ENTER;
965     PUSHMARK(SP);
966
967     EXTEND(SP, 5);
968     PUSHs(sv);
969     PUSHs(left);
970     if (SvIV(right))
971         PUSHs(sv_2mortal(newSVuv(O_RDWR|O_CREAT)));
972     else
973         PUSHs(sv_2mortal(newSVuv(O_RDWR)));
974     PUSHs(right);
975     PUTBACK;
976     call_sv((SV*)GvCV(gv), G_SCALAR);
977     SPAGAIN;
978
979     if (!sv_isobject(TOPs)) {
980         SP--;
981         PUSHMARK(SP);
982         PUSHs(sv);
983         PUSHs(left);
984         PUSHs(sv_2mortal(newSVuv(O_RDONLY)));
985         PUSHs(right);
986         PUTBACK;
987         call_sv((SV*)GvCV(gv), G_SCALAR);
988         SPAGAIN;
989     }
990
991     if (sv_isobject(TOPs)) {
992         sv_unmagic((SV *) hv, PERL_MAGIC_tied);
993         sv_magic((SV*)hv, TOPs, PERL_MAGIC_tied, Nullch, 0);
994     }
995     LEAVE;
996     RETURN;
997 }
998
999 PP(pp_dbmclose)
1000 {
1001     return pp_untie();
1002 }
1003
1004 PP(pp_sselect)
1005 {
1006 #ifdef HAS_SELECT
1007     dSP; dTARGET;
1008     register I32 i;
1009     register I32 j;
1010     register char *s;
1011     register SV *sv;
1012     NV value;
1013     I32 maxlen = 0;
1014     I32 nfound;
1015     struct timeval timebuf;
1016     struct timeval *tbuf = &timebuf;
1017     I32 growsize;
1018     char *fd_sets[4];
1019 #if BYTEORDER != 0x1234 && BYTEORDER != 0x12345678
1020         I32 masksize;
1021         I32 offset;
1022         I32 k;
1023
1024 #   if BYTEORDER & 0xf0000
1025 #       define ORDERBYTE (0x88888888 - BYTEORDER)
1026 #   else
1027 #       define ORDERBYTE (0x4444 - BYTEORDER)
1028 #   endif
1029
1030 #endif
1031
1032     SP -= 4;
1033     for (i = 1; i <= 3; i++) {
1034         SV *sv = SP[i];
1035         if (SvOK(sv) && SvREADONLY(sv)) {
1036             if (SvIsCOW(sv))
1037                 sv_force_normal_flags(sv, 0);
1038             if (SvREADONLY(sv))
1039                 DIE(aTHX_ PL_no_modify);
1040         }
1041         if (!SvPOK(sv))
1042             continue;
1043         j = SvCUR(sv);
1044         if (maxlen < j)
1045             maxlen = j;
1046     }
1047
1048 /* little endians can use vecs directly */
1049 #if BYTEORDER != 0x1234 && BYTEORDER != 0x12345678
1050 #  ifdef NFDBITS
1051
1052 #    ifndef NBBY
1053 #     define NBBY 8
1054 #    endif
1055
1056     masksize = NFDBITS / NBBY;
1057 #  else
1058     masksize = sizeof(long);    /* documented int, everyone seems to use long */
1059 #  endif
1060     Zero(&fd_sets[0], 4, char*);
1061 #endif
1062
1063 #  if SELECT_MIN_BITS == 1
1064     growsize = sizeof(fd_set);
1065 #  else
1066 #   if defined(__GLIBC__) && defined(__FD_SETSIZE)
1067 #      undef SELECT_MIN_BITS
1068 #      define SELECT_MIN_BITS __FD_SETSIZE
1069 #   endif
1070     /* If SELECT_MIN_BITS is greater than one we most probably will want
1071      * to align the sizes with SELECT_MIN_BITS/8 because for example
1072      * in many little-endian (Intel, Alpha) systems (Linux, OS/2, Digital
1073      * UNIX, Solaris, NeXT, Darwin) the smallest quantum select() operates
1074      * on (sets/tests/clears bits) is 32 bits.  */
1075     growsize = maxlen + (SELECT_MIN_BITS/8 - (maxlen % (SELECT_MIN_BITS/8)));
1076 #  endif
1077
1078     sv = SP[4];
1079     if (SvOK(sv)) {
1080         value = SvNV(sv);
1081         if (value < 0.0)
1082             value = 0.0;
1083         timebuf.tv_sec = (long)value;
1084         value -= (NV)timebuf.tv_sec;
1085         timebuf.tv_usec = (long)(value * 1000000.0);
1086     }
1087     else
1088         tbuf = Null(struct timeval*);
1089
1090     for (i = 1; i <= 3; i++) {
1091         sv = SP[i];
1092         if (!SvOK(sv)) {
1093             fd_sets[i] = 0;
1094             continue;
1095         }
1096         else if (!SvPOK(sv))
1097             SvPV_force_nolen(sv);       /* force string conversion */
1098         j = SvLEN(sv);
1099         if (j < growsize) {
1100             Sv_Grow(sv, growsize);
1101         }
1102         j = SvCUR(sv);
1103         s = SvPVX(sv) + j;
1104         while (++j <= growsize) {
1105             *s++ = '\0';
1106         }
1107
1108 #if BYTEORDER != 0x1234 && BYTEORDER != 0x12345678
1109         s = SvPVX(sv);
1110         Newx(fd_sets[i], growsize, char);
1111         for (offset = 0; offset < growsize; offset += masksize) {
1112             for (j = 0, k=ORDERBYTE; j < masksize; j++, (k >>= 4))
1113                 fd_sets[i][j+offset] = s[(k % masksize) + offset];
1114         }
1115 #else
1116         fd_sets[i] = SvPVX(sv);
1117 #endif
1118     }
1119
1120 #ifdef PERL_IRIX5_SELECT_TIMEVAL_VOID_CAST
1121     /* Can't make just the (void*) conditional because that would be
1122      * cpp #if within cpp macro, and not all compilers like that. */
1123     nfound = PerlSock_select(
1124         maxlen * 8,
1125         (Select_fd_set_t) fd_sets[1],
1126         (Select_fd_set_t) fd_sets[2],
1127         (Select_fd_set_t) fd_sets[3],
1128         (void*) tbuf); /* Workaround for compiler bug. */
1129 #else
1130     nfound = PerlSock_select(
1131         maxlen * 8,
1132         (Select_fd_set_t) fd_sets[1],
1133         (Select_fd_set_t) fd_sets[2],
1134         (Select_fd_set_t) fd_sets[3],
1135         tbuf);
1136 #endif
1137     for (i = 1; i <= 3; i++) {
1138         if (fd_sets[i]) {
1139             sv = SP[i];
1140 #if BYTEORDER != 0x1234 && BYTEORDER != 0x12345678
1141             s = SvPVX(sv);
1142             for (offset = 0; offset < growsize; offset += masksize) {
1143                 for (j = 0, k=ORDERBYTE; j < masksize; j++, (k >>= 4))
1144                     s[(k % masksize) + offset] = fd_sets[i][j+offset];
1145             }
1146             Safefree(fd_sets[i]);
1147 #endif
1148             SvSETMAGIC(sv);
1149         }
1150     }
1151
1152     if (nfound == -1)
1153         PUSHs(&PL_sv_undef);
1154     else
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 (ckWARN2(WARN_UNOPENED,WARN_CLOSED)
1236                 && (!io || (!IoIFP(io) && IoTYPE(io) != IoTYPE_WRONLY)))
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, (char*)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, (char *)"-", 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             const char *buf;
2691             int aint;
2692             if (SvPOKp(sv)) {
2693                 STRLEN l;
2694                 buf = SvPV_const(sv, l);
2695                 len = l;
2696             }
2697             else {
2698                 aint = (int)SvIV(sv);
2699                 buf = (const char*)&aint;
2700                 len = sizeof(int);
2701             }
2702             if (PerlSock_setsockopt(fd, lvl, optname, buf, len) < 0)
2703                 goto nuts2;
2704             PUSHs(&PL_sv_yes);
2705         }
2706         break;
2707     }
2708     RETURN;
2709
2710 nuts:
2711     if (ckWARN(WARN_CLOSED))
2712         report_evil_fh(gv, io, optype);
2713     SETERRNO(EBADF,SS_IVCHAN);
2714 nuts2:
2715     RETPUSHUNDEF;
2716
2717 #else
2718     DIE(aTHX_ PL_no_sock_func, "setsockopt");
2719 #endif
2720 }
2721
2722 PP(pp_getsockname)
2723 {
2724 #ifdef HAS_SOCKET
2725     return pp_getpeername();
2726 #else
2727     DIE(aTHX_ PL_no_sock_func, "getsockname");
2728 #endif
2729 }
2730
2731 PP(pp_getpeername)
2732 {
2733 #ifdef HAS_SOCKET
2734     dSP;
2735     int optype = PL_op->op_type;
2736     SV *sv;
2737     int fd;
2738     GV *gv = (GV*)POPs;
2739     register IO *io = GvIOn(gv);
2740     Sock_size_t len;
2741
2742     if (!io || !IoIFP(io))
2743         goto nuts;
2744
2745     sv = sv_2mortal(NEWSV(22, 257));
2746     (void)SvPOK_only(sv);
2747     len = 256;
2748     SvCUR_set(sv, len);
2749     *SvEND(sv) ='\0';
2750     fd = PerlIO_fileno(IoIFP(io));
2751     switch (optype) {
2752     case OP_GETSOCKNAME:
2753         if (PerlSock_getsockname(fd, (struct sockaddr *)SvPVX(sv), &len) < 0)
2754             goto nuts2;
2755         break;
2756     case OP_GETPEERNAME:
2757         if (PerlSock_getpeername(fd, (struct sockaddr *)SvPVX(sv), &len) < 0)
2758             goto nuts2;
2759 #if defined(VMS_DO_SOCKETS) && defined (DECCRTL_SOCKETS)
2760         {
2761             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";
2762             /* If the call succeeded, make sure we don't have a zeroed port/addr */
2763             if (((struct sockaddr *)SvPVX_const(sv))->sa_family == AF_INET &&
2764                 !memcmp((char *)SvPVX_const(sv) + sizeof(u_short), nowhere,
2765                         sizeof(u_short) + sizeof(struct in_addr))) {
2766                 goto nuts2;     
2767             }
2768         }
2769 #endif
2770         break;
2771     }
2772 #ifdef BOGUS_GETNAME_RETURN
2773     /* Interactive Unix, getpeername() and getsockname()
2774       does not return valid namelen */
2775     if (len == BOGUS_GETNAME_RETURN)
2776         len = sizeof(struct sockaddr);
2777 #endif
2778     SvCUR_set(sv, len);
2779     *SvEND(sv) ='\0';
2780     PUSHs(sv);
2781     RETURN;
2782
2783 nuts:
2784     if (ckWARN(WARN_CLOSED))
2785         report_evil_fh(gv, io, optype);
2786     SETERRNO(EBADF,SS_IVCHAN);
2787 nuts2:
2788     RETPUSHUNDEF;
2789
2790 #else
2791     DIE(aTHX_ PL_no_sock_func, "getpeername");
2792 #endif
2793 }
2794
2795 /* Stat calls. */
2796
2797 PP(pp_lstat)
2798 {
2799     return pp_stat();
2800 }
2801
2802 PP(pp_stat)
2803 {
2804     dSP;
2805     GV *gv;
2806     I32 gimme;
2807     I32 max = 13;
2808
2809     if (PL_op->op_flags & OPf_REF) {
2810         gv = cGVOP_gv;
2811         if (PL_op->op_type == OP_LSTAT) {
2812             if (gv != PL_defgv) {
2813                 if (ckWARN(WARN_IO))
2814                     Perl_warner(aTHX_ packWARN(WARN_IO),
2815                         "lstat() on filehandle %s", GvENAME(gv));
2816             } else if (PL_laststype != OP_LSTAT)
2817                 Perl_croak(aTHX_ "The stat preceding lstat() wasn't an lstat");
2818         }
2819
2820       do_fstat:
2821         if (gv != PL_defgv) {
2822             PL_laststype = OP_STAT;
2823             PL_statgv = gv;
2824             sv_setpvn(PL_statname, "", 0);
2825             PL_laststatval = (GvIO(gv) && IoIFP(GvIOp(gv))
2826                 ? PerlLIO_fstat(PerlIO_fileno(IoIFP(GvIOn(gv))), &PL_statcache) : -1);
2827         }
2828         if (PL_laststatval < 0) {
2829             if (ckWARN2(WARN_UNOPENED,WARN_CLOSED))
2830                 report_evil_fh(gv, GvIO(gv), PL_op->op_type);
2831             max = 0;
2832         }
2833     }
2834     else {
2835         SV* sv = POPs;
2836         if (SvTYPE(sv) == SVt_PVGV) {
2837             gv = (GV*)sv;
2838             goto do_fstat;
2839         }
2840         else if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVGV) {
2841             gv = (GV*)SvRV(sv);
2842             if (PL_op->op_type == OP_LSTAT && ckWARN(WARN_IO))
2843                 Perl_warner(aTHX_ packWARN(WARN_IO),
2844                         "lstat() on filehandle %s", GvENAME(gv));
2845             goto do_fstat;
2846         }
2847         sv_setpv(PL_statname, SvPV_nolen_const(sv));
2848         PL_statgv = Nullgv;
2849         PL_laststype = PL_op->op_type;
2850         if (PL_op->op_type == OP_LSTAT)
2851             PL_laststatval = PerlLIO_lstat(SvPV_nolen_const(PL_statname), &PL_statcache);
2852         else
2853             PL_laststatval = PerlLIO_stat(SvPV_nolen_const(PL_statname), &PL_statcache);
2854         if (PL_laststatval < 0) {
2855             if (ckWARN(WARN_NEWLINE) && strchr(SvPV_nolen_const(PL_statname), '\n'))
2856                 Perl_warner(aTHX_ packWARN(WARN_NEWLINE), PL_warn_nl, "stat");
2857             max = 0;
2858         }
2859     }
2860
2861     gimme = GIMME_V;
2862     if (gimme != G_ARRAY) {
2863         if (gimme != G_VOID)
2864             XPUSHs(boolSV(max));
2865         RETURN;
2866     }
2867     if (max) {
2868         EXTEND(SP, max);
2869         EXTEND_MORTAL(max);
2870         PUSHs(sv_2mortal(newSViv(PL_statcache.st_dev)));
2871         PUSHs(sv_2mortal(newSViv(PL_statcache.st_ino)));
2872         PUSHs(sv_2mortal(newSVuv(PL_statcache.st_mode)));
2873         PUSHs(sv_2mortal(newSVuv(PL_statcache.st_nlink)));
2874 #if Uid_t_size > IVSIZE
2875         PUSHs(sv_2mortal(newSVnv(PL_statcache.st_uid)));
2876 #else
2877 #   if Uid_t_sign <= 0
2878         PUSHs(sv_2mortal(newSViv(PL_statcache.st_uid)));
2879 #   else
2880         PUSHs(sv_2mortal(newSVuv(PL_statcache.st_uid)));
2881 #   endif
2882 #endif
2883 #if Gid_t_size > IVSIZE
2884         PUSHs(sv_2mortal(newSVnv(PL_statcache.st_gid)));
2885 #else
2886 #   if Gid_t_sign <= 0
2887         PUSHs(sv_2mortal(newSViv(PL_statcache.st_gid)));
2888 #   else
2889         PUSHs(sv_2mortal(newSVuv(PL_statcache.st_gid)));
2890 #   endif
2891 #endif
2892 #ifdef USE_STAT_RDEV
2893         PUSHs(sv_2mortal(newSViv(PL_statcache.st_rdev)));
2894 #else
2895         PUSHs(sv_2mortal(newSVpvn("", 0)));
2896 #endif
2897 #if Off_t_size > IVSIZE
2898         PUSHs(sv_2mortal(newSVnv((NV)PL_statcache.st_size)));
2899 #else
2900         PUSHs(sv_2mortal(newSViv(PL_statcache.st_size)));
2901 #endif
2902 #ifdef BIG_TIME
2903         PUSHs(sv_2mortal(newSVnv(PL_statcache.st_atime)));
2904         PUSHs(sv_2mortal(newSVnv(PL_statcache.st_mtime)));
2905         PUSHs(sv_2mortal(newSVnv(PL_statcache.st_ctime)));
2906 #else
2907         PUSHs(sv_2mortal(newSViv(PL_statcache.st_atime)));
2908         PUSHs(sv_2mortal(newSViv(PL_statcache.st_mtime)));
2909         PUSHs(sv_2mortal(newSViv(PL_statcache.st_ctime)));
2910 #endif
2911 #ifdef USE_STAT_BLOCKS
2912         PUSHs(sv_2mortal(newSVuv(PL_statcache.st_blksize)));
2913         PUSHs(sv_2mortal(newSVuv(PL_statcache.st_blocks)));
2914 #else
2915         PUSHs(sv_2mortal(newSVpvn("", 0)));
2916         PUSHs(sv_2mortal(newSVpvn("", 0)));
2917 #endif
2918     }
2919     RETURN;
2920 }
2921
2922 /* This macro is used by the stacked filetest operators :
2923  * if the previous filetest failed, short-circuit and pass its value.
2924  * Else, discard it from the stack and continue. --rgs
2925  */
2926 #define STACKED_FTEST_CHECK if (PL_op->op_private & OPpFT_STACKED) { \
2927         if (TOPs == &PL_sv_no || TOPs == &PL_sv_undef) { RETURN; } \
2928         else { (void)POPs; PUTBACK; } \
2929     }
2930
2931 PP(pp_ftrread)
2932 {
2933     I32 result;
2934     dSP;
2935     STACKED_FTEST_CHECK;
2936 #if defined(HAS_ACCESS) && defined(R_OK)
2937     if ((PL_op->op_private & OPpFT_ACCESS) && SvPOK(TOPs)) {
2938         result = access(POPpx, R_OK);
2939         if (result == 0)
2940             RETPUSHYES;
2941         if (result < 0)
2942             RETPUSHUNDEF;
2943         RETPUSHNO;
2944     }
2945     else
2946         result = my_stat();
2947 #else
2948     result = my_stat();
2949 #endif
2950     SPAGAIN;
2951     if (result < 0)
2952         RETPUSHUNDEF;
2953     if (cando(S_IRUSR, 0, &PL_statcache))
2954         RETPUSHYES;
2955     RETPUSHNO;
2956 }
2957
2958 PP(pp_ftrwrite)
2959 {
2960     I32 result;
2961     dSP;
2962     STACKED_FTEST_CHECK;
2963 #if defined(HAS_ACCESS) && defined(W_OK)
2964     if ((PL_op->op_private & OPpFT_ACCESS) && SvPOK(TOPs)) {
2965         result = access(POPpx, W_OK);
2966         if (result == 0)
2967             RETPUSHYES;
2968         if (result < 0)
2969             RETPUSHUNDEF;
2970         RETPUSHNO;
2971     }
2972     else
2973         result = my_stat();
2974 #else
2975     result = my_stat();
2976 #endif
2977     SPAGAIN;
2978     if (result < 0)
2979         RETPUSHUNDEF;
2980     if (cando(S_IWUSR, 0, &PL_statcache))
2981         RETPUSHYES;
2982     RETPUSHNO;
2983 }
2984
2985 PP(pp_ftrexec)
2986 {
2987     I32 result;
2988     dSP;
2989     STACKED_FTEST_CHECK;
2990 #if defined(HAS_ACCESS) && defined(X_OK)
2991     if ((PL_op->op_private & OPpFT_ACCESS) && SvPOK(TOPs)) {
2992         result = access(POPpx, X_OK);
2993         if (result == 0)
2994             RETPUSHYES;
2995         if (result < 0)
2996             RETPUSHUNDEF;
2997         RETPUSHNO;
2998     }
2999     else
3000         result = my_stat();
3001 #else
3002     result = my_stat();
3003 #endif
3004     SPAGAIN;
3005     if (result < 0)
3006         RETPUSHUNDEF;
3007     if (cando(S_IXUSR, 0, &PL_statcache))
3008         RETPUSHYES;
3009     RETPUSHNO;
3010 }
3011
3012 PP(pp_fteread)
3013 {
3014     I32 result;
3015     dSP;
3016     STACKED_FTEST_CHECK;
3017 #ifdef PERL_EFF_ACCESS_R_OK
3018     if ((PL_op->op_private & OPpFT_ACCESS) && SvPOK(TOPs)) {
3019         result = PERL_EFF_ACCESS_R_OK(POPpx);
3020         if (result == 0)
3021             RETPUSHYES;
3022         if (result < 0)
3023             RETPUSHUNDEF;
3024         RETPUSHNO;
3025     }
3026     else
3027         result = my_stat();
3028 #else
3029     result = my_stat();
3030 #endif
3031     SPAGAIN;
3032     if (result < 0)
3033         RETPUSHUNDEF;
3034     if (cando(S_IRUSR, 1, &PL_statcache))
3035         RETPUSHYES;
3036     RETPUSHNO;
3037 }
3038
3039 PP(pp_ftewrite)
3040 {
3041     I32 result;
3042     dSP;
3043     STACKED_FTEST_CHECK;
3044 #ifdef PERL_EFF_ACCESS_W_OK
3045     if ((PL_op->op_private & OPpFT_ACCESS) && SvPOK(TOPs)) {
3046         result = PERL_EFF_ACCESS_W_OK(POPpx);
3047         if (result == 0)
3048             RETPUSHYES;
3049         if (result < 0)
3050             RETPUSHUNDEF;
3051         RETPUSHNO;
3052     }
3053     else
3054         result = my_stat();
3055 #else
3056     result = my_stat();
3057 #endif
3058     SPAGAIN;
3059     if (result < 0)
3060         RETPUSHUNDEF;
3061     if (cando(S_IWUSR, 1, &PL_statcache))
3062         RETPUSHYES;
3063     RETPUSHNO;
3064 }
3065
3066 PP(pp_fteexec)
3067 {
3068     I32 result;
3069     dSP;
3070     STACKED_FTEST_CHECK;
3071 #ifdef PERL_EFF_ACCESS_X_OK
3072     if ((PL_op->op_private & OPpFT_ACCESS) && SvPOK(TOPs)) {
3073         result = PERL_EFF_ACCESS_X_OK(POPpx);
3074         if (result == 0)
3075             RETPUSHYES;
3076         if (result < 0)
3077             RETPUSHUNDEF;
3078         RETPUSHNO;
3079     }
3080     else
3081         result = my_stat();
3082 #else
3083     result = my_stat();
3084 #endif
3085     SPAGAIN;
3086     if (result < 0)
3087         RETPUSHUNDEF;
3088     if (cando(S_IXUSR, 1, &PL_statcache))
3089         RETPUSHYES;
3090     RETPUSHNO;
3091 }
3092
3093 PP(pp_ftis)
3094 {
3095     I32 result;
3096     dSP;
3097     STACKED_FTEST_CHECK;
3098     result = my_stat();
3099     SPAGAIN;
3100     if (result < 0)
3101         RETPUSHUNDEF;
3102     RETPUSHYES;
3103 }
3104
3105 PP(pp_fteowned)
3106 {
3107     return pp_ftrowned();
3108 }
3109
3110 PP(pp_ftrowned)
3111 {
3112     I32 result;
3113     dSP;
3114     STACKED_FTEST_CHECK;
3115     result = my_stat();
3116     SPAGAIN;
3117     if (result < 0)
3118         RETPUSHUNDEF;
3119     if (PL_statcache.st_uid == (PL_op->op_type == OP_FTEOWNED ?
3120                                 PL_euid : PL_uid) )
3121         RETPUSHYES;
3122     RETPUSHNO;
3123 }
3124
3125 PP(pp_ftzero)
3126 {
3127     I32 result;
3128     dSP;
3129     STACKED_FTEST_CHECK;
3130     result = my_stat();
3131     SPAGAIN;
3132     if (result < 0)
3133         RETPUSHUNDEF;
3134     if (PL_statcache.st_size == 0)
3135         RETPUSHYES;
3136     RETPUSHNO;
3137 }
3138
3139 PP(pp_ftsize)
3140 {
3141     I32 result;
3142     dSP; dTARGET;
3143     STACKED_FTEST_CHECK;
3144     result = my_stat();
3145     SPAGAIN;
3146     if (result < 0)
3147         RETPUSHUNDEF;
3148 #if Off_t_size > IVSIZE
3149     PUSHn(PL_statcache.st_size);
3150 #else
3151     PUSHi(PL_statcache.st_size);
3152 #endif
3153     RETURN;
3154 }
3155
3156 PP(pp_ftmtime)
3157 {
3158     I32 result;
3159     dSP; dTARGET;
3160     STACKED_FTEST_CHECK;
3161     result = my_stat();
3162     SPAGAIN;
3163     if (result < 0)
3164         RETPUSHUNDEF;
3165     PUSHn( (((NV)PL_basetime - PL_statcache.st_mtime)) / 86400.0 );
3166     RETURN;
3167 }
3168
3169 PP(pp_ftatime)
3170 {
3171     I32 result;
3172     dSP; dTARGET;
3173     STACKED_FTEST_CHECK;
3174     result = my_stat();
3175     SPAGAIN;
3176     if (result < 0)
3177         RETPUSHUNDEF;
3178     PUSHn( (((NV)PL_basetime - PL_statcache.st_atime)) / 86400.0 );
3179     RETURN;
3180 }
3181
3182 PP(pp_ftctime)
3183 {
3184     I32 result;
3185     dSP; dTARGET;
3186     STACKED_FTEST_CHECK;
3187     result = my_stat();
3188     SPAGAIN;
3189     if (result < 0)
3190         RETPUSHUNDEF;
3191     PUSHn( (((NV)PL_basetime - PL_statcache.st_ctime)) / 86400.0 );
3192     RETURN;
3193 }
3194
3195 PP(pp_ftsock)
3196 {
3197     I32 result;
3198     dSP;
3199     STACKED_FTEST_CHECK;
3200     result = my_stat();
3201     SPAGAIN;
3202     if (result < 0)
3203         RETPUSHUNDEF;
3204     if (S_ISSOCK(PL_statcache.st_mode))
3205         RETPUSHYES;
3206     RETPUSHNO;
3207 }
3208
3209 PP(pp_ftchr)
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_ISCHR(PL_statcache.st_mode))
3219         RETPUSHYES;
3220     RETPUSHNO;
3221 }
3222
3223 PP(pp_ftblk)
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_ISBLK(PL_statcache.st_mode))
3233         RETPUSHYES;
3234     RETPUSHNO;
3235 }
3236
3237 PP(pp_ftfile)
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_ISREG(PL_statcache.st_mode))
3247         RETPUSHYES;
3248     RETPUSHNO;
3249 }
3250
3251 PP(pp_ftdir)
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_ISDIR(PL_statcache.st_mode))
3261         RETPUSHYES;
3262     RETPUSHNO;
3263 }
3264
3265 PP(pp_ftpipe)
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_ISFIFO(PL_statcache.st_mode))
3275         RETPUSHYES;
3276     RETPUSHNO;
3277 }
3278
3279 PP(pp_ftlink)
3280 {
3281     I32 result = my_lstat();
3282     dSP;
3283     if (result < 0)
3284         RETPUSHUNDEF;
3285     if (S_ISLNK(PL_statcache.st_mode))
3286         RETPUSHYES;
3287     RETPUSHNO;
3288 }
3289
3290 PP(pp_ftsuid)
3291 {
3292     dSP;
3293 #ifdef S_ISUID
3294     I32 result;
3295     STACKED_FTEST_CHECK;
3296     result = my_stat();
3297     SPAGAIN;
3298     if (result < 0)
3299         RETPUSHUNDEF;
3300     if (PL_statcache.st_mode & S_ISUID)
3301         RETPUSHYES;
3302 #endif
3303     RETPUSHNO;
3304 }
3305
3306 PP(pp_ftsgid)
3307 {
3308     dSP;
3309 #ifdef S_ISGID
3310     I32 result;
3311     STACKED_FTEST_CHECK;
3312     result = my_stat();
3313     SPAGAIN;
3314     if (result < 0)
3315         RETPUSHUNDEF;
3316     if (PL_statcache.st_mode & S_ISGID)
3317         RETPUSHYES;
3318 #endif
3319     RETPUSHNO;
3320 }
3321
3322 PP(pp_ftsvtx)
3323 {
3324     dSP;
3325 #ifdef S_ISVTX
3326     I32 result;
3327     STACKED_FTEST_CHECK;
3328     result = my_stat();
3329     SPAGAIN;
3330     if (result < 0)
3331         RETPUSHUNDEF;
3332     if (PL_statcache.st_mode & S_ISVTX)
3333         RETPUSHYES;
3334 #endif
3335     RETPUSHNO;
3336 }
3337
3338 PP(pp_fttty)
3339 {
3340     dSP;
3341     int fd;
3342     GV *gv;
3343     SV *tmpsv = Nullsv;
3344
3345     STACKED_FTEST_CHECK;
3346
3347     if (PL_op->op_flags & OPf_REF)
3348         gv = cGVOP_gv;
3349     else if (isGV(TOPs))
3350         gv = (GV*)POPs;
3351     else if (SvROK(TOPs) && isGV(SvRV(TOPs)))
3352         gv = (GV*)SvRV(POPs);
3353     else
3354         gv = gv_fetchsv(tmpsv = POPs, FALSE, SVt_PVIO);
3355
3356     if (GvIO(gv) && IoIFP(GvIOp(gv)))
3357         fd = PerlIO_fileno(IoIFP(GvIOp(gv)));
3358     else if (tmpsv && SvOK(tmpsv)) {
3359         const char *tmps = SvPV_nolen_const(tmpsv);
3360         if (isDIGIT(*tmps))
3361             fd = atoi(tmps);
3362         else 
3363             RETPUSHUNDEF;
3364     }
3365     else
3366         RETPUSHUNDEF;
3367     if (PerlLIO_isatty(fd))
3368         RETPUSHYES;
3369     RETPUSHNO;
3370 }
3371
3372 #if defined(atarist) /* this will work with atariST. Configure will
3373                         make guesses for other systems. */
3374 # define FILE_base(f) ((f)->_base)
3375 # define FILE_ptr(f) ((f)->_ptr)
3376 # define FILE_cnt(f) ((f)->_cnt)
3377 # define FILE_bufsiz(f) ((f)->_cnt + ((f)->_ptr - (f)->_base))
3378 #endif
3379
3380 PP(pp_fttext)
3381 {
3382     dSP;
3383     I32 i;
3384     I32 len;
3385     I32 odd = 0;
3386     STDCHAR tbuf[512];
3387     register STDCHAR *s;
3388     register IO *io;
3389     register SV *sv;
3390     GV *gv;
3391     PerlIO *fp;
3392
3393     STACKED_FTEST_CHECK;
3394
3395     if (PL_op->op_flags & OPf_REF)
3396         gv = cGVOP_gv;
3397     else if (isGV(TOPs))
3398         gv = (GV*)POPs;
3399     else if (SvROK(TOPs) && isGV(SvRV(TOPs)))
3400         gv = (GV*)SvRV(POPs);
3401     else
3402         gv = Nullgv;
3403
3404     if (gv) {
3405         EXTEND(SP, 1);
3406         if (gv == PL_defgv) {
3407             if (PL_statgv)
3408                 io = GvIO(PL_statgv);
3409             else {
3410                 sv = PL_statname;
3411                 goto really_filename;
3412             }
3413         }
3414         else {
3415             PL_statgv = gv;
3416             PL_laststatval = -1;
3417             sv_setpvn(PL_statname, "", 0);
3418             io = GvIO(PL_statgv);
3419         }
3420         if (io && IoIFP(io)) {
3421             if (! PerlIO_has_base(IoIFP(io)))
3422                 DIE(aTHX_ "-T and -B not implemented on filehandles");
3423             PL_laststatval = PerlLIO_fstat(PerlIO_fileno(IoIFP(io)), &PL_statcache);
3424             if (PL_laststatval < 0)
3425                 RETPUSHUNDEF;
3426             if (S_ISDIR(PL_statcache.st_mode)) { /* handle NFS glitch */
3427                 if (PL_op->op_type == OP_FTTEXT)
3428                     RETPUSHNO;
3429                 else
3430                     RETPUSHYES;
3431             }
3432             if (PerlIO_get_cnt(IoIFP(io)) <= 0) {
3433                 i = PerlIO_getc(IoIFP(io));
3434                 if (i != EOF)
3435                     (void)PerlIO_ungetc(IoIFP(io),i);
3436             }
3437             if (PerlIO_get_cnt(IoIFP(io)) <= 0) /* null file is anything */
3438                 RETPUSHYES;
3439             len = PerlIO_get_bufsiz(IoIFP(io));
3440             s = (STDCHAR *) PerlIO_get_base(IoIFP(io));
3441             /* sfio can have large buffers - limit to 512 */
3442             if (len > 512)
3443                 len = 512;
3444         }
3445         else {
3446             if (ckWARN2(WARN_UNOPENED,WARN_CLOSED)) {
3447                 gv = cGVOP_gv;
3448                 report_evil_fh(gv, GvIO(gv), PL_op->op_type);
3449             }
3450             SETERRNO(EBADF,RMS_IFI);
3451             RETPUSHUNDEF;
3452         }
3453     }
3454     else {
3455         sv = POPs;
3456       really_filename:
3457         PL_statgv = Nullgv;
3458         PL_laststype = OP_STAT;
3459         sv_setpv(PL_statname, SvPV_nolen_const(sv));
3460         if (!(fp = PerlIO_open(SvPVX_const(PL_statname), "r"))) {
3461             if (ckWARN(WARN_NEWLINE) && strchr(SvPV_nolen_const(PL_statname),
3462                                                '\n'))
3463                 Perl_warner(aTHX_ packWARN(WARN_NEWLINE), PL_warn_nl, "open");
3464             RETPUSHUNDEF;
3465         }
3466         PL_laststatval = PerlLIO_fstat(PerlIO_fileno(fp), &PL_statcache);
3467         if (PL_laststatval < 0) {
3468             (void)PerlIO_close(fp);
3469             RETPUSHUNDEF;
3470         }
3471         PerlIO_binmode(aTHX_ fp, '<', O_BINARY, Nullch);
3472         len = PerlIO_read(fp, tbuf, sizeof(tbuf));
3473         (void)PerlIO_close(fp);
3474         if (len <= 0) {
3475             if (S_ISDIR(PL_statcache.st_mode) && PL_op->op_type == OP_FTTEXT)
3476                 RETPUSHNO;              /* special case NFS directories */
3477             RETPUSHYES;         /* null file is anything */
3478         }
3479         s = tbuf;
3480     }
3481
3482     /* now scan s to look for textiness */
3483     /*   XXX ASCII dependent code */
3484
3485 #if defined(DOSISH) || defined(USEMYBINMODE)
3486     /* ignore trailing ^Z on short files */
3487     if (len && len < sizeof(tbuf) && tbuf[len-1] == 26)
3488         --len;
3489 #endif
3490
3491     for (i = 0; i < len; i++, s++) {
3492         if (!*s) {                      /* null never allowed in text */
3493             odd += len;
3494             break;
3495         }
3496 #ifdef EBCDIC
3497         else if (!(isPRINT(*s) || isSPACE(*s)))
3498             odd++;
3499 #else
3500         else if (*s & 128) {
3501 #ifdef USE_LOCALE
3502             if (IN_LOCALE_RUNTIME && isALPHA_LC(*s))
3503                 continue;
3504 #endif
3505             /* utf8 characters don't count as odd */
3506             if (UTF8_IS_START(*s)) {
3507                 int ulen = UTF8SKIP(s);
3508                 if (ulen < len - i) {
3509                     int j;
3510                     for (j = 1; j < ulen; j++) {
3511                         if (!UTF8_IS_CONTINUATION(s[j]))
3512                             goto not_utf8;
3513                     }
3514                     --ulen;     /* loop does extra increment */
3515                     s += ulen;
3516                     i += ulen;
3517                     continue;
3518                 }
3519             }
3520           not_utf8:
3521             odd++;
3522         }
3523         else if (*s < 32 &&
3524           *s != '\n' && *s != '\r' && *s != '\b' &&
3525           *s != '\t' && *s != '\f' && *s != 27)
3526             odd++;
3527 #endif
3528     }
3529
3530     if ((odd * 3 > len) == (PL_op->op_type == OP_FTTEXT)) /* allow 1/3 odd */
3531         RETPUSHNO;
3532     else
3533         RETPUSHYES;
3534 }
3535
3536 PP(pp_ftbinary)
3537 {
3538     return pp_fttext();
3539 }
3540
3541 /* File calls. */
3542
3543 PP(pp_chdir)
3544 {
3545     dSP; dTARGET;
3546     const char *tmps;
3547     SV **svp;
3548
3549     if( MAXARG == 1 )
3550         tmps = POPpconstx;
3551     else
3552         tmps = 0;
3553
3554     if( !tmps || !*tmps ) {
3555         if (    (svp = hv_fetch(GvHVn(PL_envgv), "HOME", 4, FALSE))
3556              || (svp = hv_fetch(GvHVn(PL_envgv), "LOGDIR", 6, FALSE))
3557 #ifdef VMS
3558              || (svp = hv_fetch(GvHVn(PL_envgv), "SYS$LOGIN", 9, FALSE))
3559 #endif
3560            )
3561         {
3562             if( MAXARG == 1 )
3563                 deprecate("chdir('') or chdir(undef) as chdir()");
3564             tmps = SvPV_nolen_const(*svp);
3565         }
3566         else {
3567             PUSHi(0);
3568             TAINT_PROPER("chdir");
3569             RETURN;
3570         }
3571     }
3572
3573     TAINT_PROPER("chdir");
3574     PUSHi( PerlDir_chdir(tmps) >= 0 );
3575 #ifdef VMS
3576     /* Clear the DEFAULT element of ENV so we'll get the new value
3577      * in the future. */
3578     hv_delete(GvHVn(PL_envgv),"DEFAULT",7,G_DISCARD);
3579 #endif
3580     RETURN;
3581 }
3582
3583 PP(pp_chown)
3584 {
3585 #ifdef HAS_CHOWN
3586     dSP; dMARK; dTARGET;
3587     I32 value = (I32)apply(PL_op->op_type, MARK, SP);
3588
3589     SP = MARK;
3590     PUSHi(value);
3591     RETURN;
3592 #else
3593     DIE(aTHX_ PL_no_func, "chown");
3594 #endif
3595 }
3596
3597 PP(pp_chroot)
3598 {
3599 #ifdef HAS_CHROOT
3600     dSP; dTARGET;
3601     char *tmps = POPpx;
3602     TAINT_PROPER("chroot");
3603     PUSHi( chroot(tmps) >= 0 );
3604     RETURN;
3605 #else
3606     DIE(aTHX_ PL_no_func, "chroot");
3607 #endif
3608 }
3609
3610 PP(pp_unlink)
3611 {
3612     dSP; dMARK; dTARGET;
3613     I32 value;
3614     value = (I32)apply(PL_op->op_type, MARK, SP);
3615     SP = MARK;
3616     PUSHi(value);
3617     RETURN;
3618 }
3619
3620 PP(pp_chmod)
3621 {
3622     dSP; dMARK; dTARGET;
3623     I32 value;
3624     value = (I32)apply(PL_op->op_type, MARK, SP);
3625     SP = MARK;
3626     PUSHi(value);
3627     RETURN;
3628 }
3629
3630 PP(pp_utime)
3631 {
3632     dSP; dMARK; dTARGET;
3633     I32 value;
3634     value = (I32)apply(PL_op->op_type, MARK, SP);
3635     SP = MARK;
3636     PUSHi(value);
3637     RETURN;
3638 }
3639
3640 PP(pp_rename)
3641 {
3642     dSP; dTARGET;
3643     int anum;
3644     const char *tmps2 = POPpconstx;
3645     const char *tmps = SvPV_nolen_const(TOPs);
3646     TAINT_PROPER("rename");
3647 #ifdef HAS_RENAME
3648     anum = PerlLIO_rename(tmps, tmps2);
3649 #else
3650     if (!(anum = PerlLIO_stat(tmps, &PL_statbuf))) {
3651         if (same_dirent(tmps2, tmps))   /* can always rename to same name */
3652             anum = 1;
3653         else {
3654             if (PL_euid || PerlLIO_stat(tmps2, &PL_statbuf) < 0 || !S_ISDIR(PL_statbuf.st_mode))
3655                 (void)UNLINK(tmps2);
3656             if (!(anum = link(tmps, tmps2)))
3657                 anum = UNLINK(tmps);
3658         }
3659     }
3660 #endif
3661     SETi( anum >= 0 );
3662     RETURN;
3663 }
3664
3665 PP(pp_link)
3666 {
3667 #ifdef HAS_LINK
3668     dSP; dTARGET;
3669     const char *tmps2 = POPpconstx;
3670     const char *tmps = SvPV_nolen_const(TOPs);
3671     TAINT_PROPER("link");
3672     SETi( PerlLIO_link(tmps, tmps2) >= 0 );
3673     RETURN;
3674 #else
3675     DIE(aTHX_ PL_no_func, "link");
3676 #endif
3677 }
3678
3679 PP(pp_symlink)
3680 {
3681 #ifdef HAS_SYMLINK
3682     dSP; dTARGET;
3683     const char *tmps2 = POPpconstx;
3684     const char *tmps = SvPV_nolen_const(TOPs);
3685     TAINT_PROPER("symlink");
3686     SETi( symlink(tmps, tmps2) >= 0 );
3687     RETURN;
3688 #else
3689     DIE(aTHX_ PL_no_func, "symlink");
3690 #endif
3691 }
3692
3693 PP(pp_readlink)
3694 {
3695     dSP;
3696 #ifdef HAS_SYMLINK
3697     dTARGET;
3698     const char *tmps;
3699     char buf[MAXPATHLEN];
3700     int len;
3701
3702 #ifndef INCOMPLETE_TAINTS
3703     TAINT;
3704 #endif
3705     tmps = POPpconstx;
3706     len = readlink(tmps, buf, sizeof(buf) - 1);
3707     EXTEND(SP, 1);
3708     if (len < 0)
3709         RETPUSHUNDEF;
3710     PUSHp(buf, len);
3711     RETURN;
3712 #else
3713     EXTEND(SP, 1);
3714     RETSETUNDEF;                /* just pretend it's a normal file */
3715 #endif
3716 }
3717
3718 #if !defined(HAS_MKDIR) || !defined(HAS_RMDIR)
3719 STATIC int
3720 S_dooneliner(pTHX_ const char *cmd, const char *filename)
3721 {
3722     char * const save_filename = filename;
3723     char *cmdline;
3724     char *s;
3725     PerlIO *myfp;
3726     int anum = 1;
3727
3728     Newx(cmdline, strlen(cmd) + (strlen(filename) * 2) + 10, char);
3729     strcpy(cmdline, cmd);
3730     strcat(cmdline, " ");
3731     for (s = cmdline + strlen(cmdline); *filename; ) {
3732         *s++ = '\\';
3733         *s++ = *filename++;
3734     }
3735     strcpy(s, " 2>&1");
3736     myfp = PerlProc_popen(cmdline, "r");
3737     Safefree(cmdline);
3738
3739     if (myfp) {
3740         SV *tmpsv = sv_newmortal();
3741         /* Need to save/restore 'PL_rs' ?? */
3742         s = sv_gets(tmpsv, myfp, 0);
3743         (void)PerlProc_pclose(myfp);
3744         if (s != Nullch) {
3745             int e;
3746             for (e = 1;
3747 #ifdef HAS_SYS_ERRLIST
3748                  e <= sys_nerr
3749 #endif
3750                  ; e++)
3751             {
3752                 /* you don't see this */
3753                 char *errmsg =
3754 #ifdef HAS_SYS_ERRLIST
3755                     sys_errlist[e]
3756 #else
3757                     strerror(e)
3758 #endif
3759                     ;
3760                 if (!errmsg)
3761                     break;
3762                 if (instr(s, errmsg)) {
3763                     SETERRNO(e,0);
3764                     return 0;
3765                 }
3766             }
3767             SETERRNO(0,0);
3768 #ifndef EACCES
3769 #define EACCES EPERM
3770 #endif
3771             if (instr(s, "cannot make"))
3772                 SETERRNO(EEXIST,RMS_FEX);
3773             else if (instr(s, "existing file"))
3774                 SETERRNO(EEXIST,RMS_FEX);
3775             else if (instr(s, "ile exists"))
3776                 SETERRNO(EEXIST,RMS_FEX);
3777             else if (instr(s, "non-exist"))
3778                 SETERRNO(ENOENT,RMS_FNF);
3779             else if (instr(s, "does not exist"))
3780                 SETERRNO(ENOENT,RMS_FNF);
3781             else if (instr(s, "not empty"))
3782                 SETERRNO(EBUSY,SS_DEVOFFLINE);
3783             else if (instr(s, "cannot access"))
3784                 SETERRNO(EACCES,RMS_PRV);
3785             else
3786                 SETERRNO(EPERM,RMS_PRV);
3787             return 0;
3788         }
3789         else {  /* some mkdirs return no failure indication */
3790             anum = (PerlLIO_stat(save_filename, &PL_statbuf) >= 0);
3791             if (PL_op->op_type == OP_RMDIR)
3792                 anum = !anum;
3793             if (anum)
3794                 SETERRNO(0,0);
3795             else
3796                 SETERRNO(EACCES,RMS_PRV);       /* a guess */
3797         }
3798         return anum;
3799     }
3800     else
3801         return 0;
3802 }
3803 #endif
3804
3805 /* This macro removes trailing slashes from a directory name.
3806  * Different operating and file systems take differently to
3807  * trailing slashes.  According to POSIX 1003.1 1996 Edition
3808  * any number of trailing slashes should be allowed.
3809  * Thusly we snip them away so that even non-conforming
3810  * systems are happy.
3811  * We should probably do this "filtering" for all
3812  * the functions that expect (potentially) directory names:
3813  * -d, chdir(), chmod(), chown(), chroot(), fcntl()?,
3814  * (mkdir()), opendir(), rename(), rmdir(), stat(). --jhi */
3815
3816 #define TRIMSLASHES(tmps,len,copy) (tmps) = SvPV_const(TOPs, (len)); \
3817     if ((len) > 1 && (tmps)[(len)-1] == '/') { \
3818         do { \
3819             (len)--; \
3820         } while ((len) > 1 && (tmps)[(len)-1] == '/'); \
3821         (tmps) = savepvn((tmps), (len)); \
3822         (copy) = TRUE; \
3823     }
3824
3825 PP(pp_mkdir)
3826 {
3827     dSP; dTARGET;
3828     int mode;
3829 #ifndef HAS_MKDIR
3830     int oldumask;
3831 #endif
3832     STRLEN len;
3833     const char *tmps;
3834     bool copy = FALSE;
3835
3836     if (MAXARG > 1)
3837         mode = POPi;
3838     else
3839         mode = 0777;
3840
3841     TRIMSLASHES(tmps,len,copy);
3842
3843     TAINT_PROPER("mkdir");
3844 #ifdef HAS_MKDIR
3845     SETi( PerlDir_mkdir(tmps, mode) >= 0 );
3846 #else
3847     SETi( dooneliner("mkdir", tmps) );
3848     oldumask = PerlLIO_umask(0);
3849     PerlLIO_umask(oldumask);
3850     PerlLIO_chmod(tmps, (mode & ~oldumask) & 0777);
3851 #endif
3852     if (copy)
3853         Safefree(tmps);
3854     RETURN;
3855 }
3856
3857 PP(pp_rmdir)
3858 {
3859     dSP; dTARGET;
3860     STRLEN len;
3861     const char *tmps;
3862     bool copy = FALSE;
3863
3864     TRIMSLASHES(tmps,len,copy);
3865     TAINT_PROPER("rmdir");
3866 #ifdef HAS_RMDIR
3867     SETi( PerlDir_rmdir(tmps) >= 0 );
3868 #else
3869     SETi( dooneliner("rmdir", tmps) );
3870 #endif
3871     if (copy)
3872         Safefree(tmps);
3873     RETURN;
3874 }
3875
3876 /* Directory calls. */
3877
3878 PP(pp_open_dir)
3879 {
3880 #if defined(Direntry_t) && defined(HAS_READDIR)
3881     dSP;
3882     const char *dirname = POPpconstx;
3883     GV *gv = (GV*)POPs;
3884     register IO *io = GvIOn(gv);
3885
3886     if (!io)
3887         goto nope;
3888
3889     if (IoDIRP(io))
3890         PerlDir_close(IoDIRP(io));
3891     if (!(IoDIRP(io) = PerlDir_open(dirname)))
3892         goto nope;
3893
3894     RETPUSHYES;
3895 nope:
3896     if (!errno)
3897         SETERRNO(EBADF,RMS_DIR);
3898     RETPUSHUNDEF;
3899 #else
3900     DIE(aTHX_ PL_no_dir_func, "opendir");
3901 #endif
3902 }
3903
3904 PP(pp_readdir)
3905 {
3906 #if !defined(Direntry_t) || !defined(HAS_READDIR)
3907     DIE(aTHX_ PL_no_dir_func, "readdir");
3908 #else
3909 #if !defined(I_DIRENT) && !defined(VMS)
3910     Direntry_t *readdir (DIR *);
3911 #endif
3912     dSP;
3913
3914     SV *sv;
3915     const I32 gimme = GIMME;
3916     GV *gv = (GV *)POPs;
3917     register Direntry_t *dp;
3918     register IO *io = GvIOn(gv);
3919
3920     if (!io || !IoDIRP(io))
3921         goto nope;
3922
3923     do {
3924         dp = (Direntry_t *)PerlDir_read(IoDIRP(io));
3925         if (!dp)
3926             break;
3927 #ifdef DIRNAMLEN
3928         sv = newSVpvn(dp->d_name, dp->d_namlen);
3929 #else
3930         sv = newSVpv(dp->d_name, 0);
3931 #endif
3932 #ifndef INCOMPLETE_TAINTS
3933         if (!(IoFLAGS(io) & IOf_UNTAINT))
3934             SvTAINTED_on(sv);
3935 #endif
3936         XPUSHs(sv_2mortal(sv));
3937     }
3938     while (gimme == G_ARRAY);
3939
3940     if (!dp && gimme != G_ARRAY)
3941         goto nope;
3942
3943     RETURN;
3944
3945 nope:
3946     if (!errno)
3947         SETERRNO(EBADF,RMS_ISI);
3948     if (GIMME == G_ARRAY)
3949         RETURN;
3950     else
3951         RETPUSHUNDEF;
3952 #endif
3953 }
3954
3955 PP(pp_telldir)
3956 {
3957 #if defined(HAS_TELLDIR) || defined(telldir)
3958     dVAR; dSP; dTARGET;
3959  /* XXX does _anyone_ need this? --AD 2/20/1998 */
3960  /* XXX netbsd still seemed to.
3961     XXX HAS_TELLDIR_PROTO is new style, NEED_TELLDIR_PROTO is old style.
3962     --JHI 1999-Feb-02 */
3963 # if !defined(HAS_TELLDIR_PROTO) || defined(NEED_TELLDIR_PROTO)
3964     long telldir (DIR *);
3965 # endif
3966     GV *gv = (GV*)POPs;
3967     register IO *io = GvIOn(gv);
3968
3969     if (!io || !IoDIRP(io))
3970         goto nope;
3971
3972     PUSHi( PerlDir_tell(IoDIRP(io)) );
3973     RETURN;
3974 nope:
3975     if (!errno)
3976         SETERRNO(EBADF,RMS_ISI);
3977     RETPUSHUNDEF;
3978 #else
3979     DIE(aTHX_ PL_no_dir_func, "telldir");
3980 #endif
3981 }
3982
3983 PP(pp_seekdir)
3984 {
3985 #if defined(HAS_SEEKDIR) || defined(seekdir)
3986     dSP;
3987     long along = POPl;
3988     GV *gv = (GV*)POPs;
3989     register IO *io = GvIOn(gv);
3990
3991     if (!io || !IoDIRP(io))
3992         goto nope;
3993
3994     (void)PerlDir_seek(IoDIRP(io), along);
3995
3996     RETPUSHYES;
3997 nope:
3998     if (!errno)
3999         SETERRNO(EBADF,RMS_ISI);
4000     RETPUSHUNDEF;
4001 #else
4002     DIE(aTHX_ PL_no_dir_func, "seekdir");
4003 #endif
4004 }
4005
4006 PP(pp_rewinddir)
4007 {
4008 #if defined(HAS_REWINDDIR) || defined(rewinddir)
4009     dSP;
4010     GV *gv = (GV*)POPs;
4011     register IO *io = GvIOn(gv);
4012
4013     if (!io || !IoDIRP(io))
4014         goto nope;
4015
4016     (void)PerlDir_rewind(IoDIRP(io));
4017     RETPUSHYES;
4018 nope:
4019     if (!errno)
4020         SETERRNO(EBADF,RMS_ISI);
4021     RETPUSHUNDEF;
4022 #else
4023     DIE(aTHX_ PL_no_dir_func, "rewinddir");
4024 #endif
4025 }
4026
4027 PP(pp_closedir)
4028 {
4029 #if defined(Direntry_t) && defined(HAS_READDIR)
4030     dSP;
4031     GV *gv = (GV*)POPs;
4032     register IO *io = GvIOn(gv);
4033
4034     if (!io || !IoDIRP(io))
4035         goto nope;
4036
4037 #ifdef VOID_CLOSEDIR
4038     PerlDir_close(IoDIRP(io));
4039 #else
4040     if (PerlDir_close(IoDIRP(io)) < 0) {
4041         IoDIRP(io) = 0; /* Don't try to close again--coredumps on SysV */
4042         goto nope;
4043     }
4044 #endif
4045     IoDIRP(io) = 0;
4046
4047     RETPUSHYES;
4048 nope:
4049     if (!errno)
4050         SETERRNO(EBADF,RMS_IFI);
4051     RETPUSHUNDEF;
4052 #else
4053     DIE(aTHX_ PL_no_dir_func, "closedir");
4054 #endif
4055 }
4056
4057 /* Process control. */
4058
4059 PP(pp_fork)
4060 {
4061 #ifdef HAS_FORK
4062     dSP; dTARGET;
4063     Pid_t childpid;
4064     GV *tmpgv;
4065
4066     EXTEND(SP, 1);
4067     PERL_FLUSHALL_FOR_CHILD;
4068     childpid = PerlProc_fork();
4069     if (childpid < 0)
4070         RETSETUNDEF;
4071     if (!childpid) {
4072         if ((tmpgv = gv_fetchpv("$", TRUE, SVt_PV))) {
4073             SvREADONLY_off(GvSV(tmpgv));
4074             sv_setiv(GvSV(tmpgv), (IV)PerlProc_getpid());
4075             SvREADONLY_on(GvSV(tmpgv));
4076         }
4077 #ifdef THREADS_HAVE_PIDS
4078         PL_ppid = (IV)getppid();
4079 #endif
4080         hv_clear(PL_pidstatus); /* no kids, so don't wait for 'em */
4081     }
4082     PUSHi(childpid);
4083     RETURN;
4084 #else
4085 #  if defined(USE_ITHREADS) && defined(PERL_IMPLICIT_SYS)
4086     dSP; dTARGET;
4087     Pid_t childpid;
4088
4089     EXTEND(SP, 1);
4090     PERL_FLUSHALL_FOR_CHILD;
4091     childpid = PerlProc_fork();
4092     if (childpid == -1)
4093         RETSETUNDEF;
4094     PUSHi(childpid);
4095     RETURN;
4096 #  else
4097     DIE(aTHX_ PL_no_func, "fork");
4098 #  endif
4099 #endif
4100 }
4101
4102 PP(pp_wait)
4103 {
4104 #if (!defined(DOSISH) || defined(OS2) || defined(WIN32)) && !defined(MACOS_TRADITIONAL)
4105     dSP; dTARGET;
4106     Pid_t childpid;
4107     int argflags;
4108
4109     if (PL_signals & PERL_SIGNALS_UNSAFE_FLAG)
4110         childpid = wait4pid(-1, &argflags, 0);
4111     else {
4112         while ((childpid = wait4pid(-1, &argflags, 0)) == -1 &&
4113                errno == EINTR) {
4114           PERL_ASYNC_CHECK();
4115         }
4116     }
4117 #  if defined(USE_ITHREADS) && defined(PERL_IMPLICIT_SYS)
4118     /* 0 and -1 are both error returns (the former applies to WNOHANG case) */
4119     STATUS_NATIVE_SET((childpid && childpid != -1) ? argflags : -1);
4120 #  else
4121     STATUS_NATIVE_SET((childpid > 0) ? argflags : -1);
4122 #  endif
4123     XPUSHi(childpid);
4124     RETURN;
4125 #else
4126     DIE(aTHX_ PL_no_func, "wait");
4127 #endif
4128 }
4129
4130 PP(pp_waitpid)
4131 {
4132 #if (!defined(DOSISH) || defined(OS2) || defined(WIN32)) && !defined(MACOS_TRADITIONAL)
4133     dSP; dTARGET;
4134     Pid_t pid;
4135     Pid_t result;
4136     int optype;
4137     int argflags;
4138
4139     optype = POPi;
4140     pid = TOPi;
4141     if (PL_signals & PERL_SIGNALS_UNSAFE_FLAG)
4142         result = wait4pid(pid, &argflags, optype);
4143     else {
4144         while ((result = wait4pid(pid, &argflags, optype)) == -1 &&
4145                errno == EINTR) {
4146           PERL_ASYNC_CHECK();
4147         }
4148     }
4149 #  if defined(USE_ITHREADS) && defined(PERL_IMPLICIT_SYS)
4150     /* 0 and -1 are both error returns (the former applies to WNOHANG case) */
4151     STATUS_NATIVE_SET((result && result != -1) ? argflags : -1);
4152 #  else
4153     STATUS_NATIVE_SET((result > 0) ? argflags : -1);
4154 #  endif
4155     SETi(result);
4156     RETURN;
4157 #else
4158     DIE(aTHX_ PL_no_func, "waitpid");
4159 #endif
4160 }
4161
4162 PP(pp_system)
4163 {
4164     dSP; dMARK; dORIGMARK; dTARGET;
4165     I32 value;
4166     int result;
4167
4168     if (PL_tainting) {
4169         TAINT_ENV();
4170         while (++MARK <= SP) {
4171             (void)SvPV_nolen_const(*MARK);      /* stringify for taint check */
4172             if (PL_tainted)
4173                 break;
4174         }
4175         MARK = ORIGMARK;
4176         TAINT_PROPER("system");
4177     }
4178     PERL_FLUSHALL_FOR_CHILD;
4179 #if (defined(HAS_FORK) || defined(AMIGAOS)) && !defined(VMS) && !defined(OS2) || defined(PERL_MICRO)
4180     {
4181         Pid_t childpid;
4182         int pp[2];
4183         I32 did_pipes = 0;
4184
4185         if (PerlProc_pipe(pp) >= 0)
4186             did_pipes = 1;
4187         while ((childpid = PerlProc_fork()) == -1) {
4188             if (errno != EAGAIN) {
4189                 value = -1;
4190                 SP = ORIGMARK;
4191                 PUSHi(value);
4192                 if (did_pipes) {
4193                     PerlLIO_close(pp[0]);
4194                     PerlLIO_close(pp[1]);
4195                 }
4196                 RETURN;
4197             }
4198             sleep(5);
4199         }
4200         if (childpid > 0) {
4201             Sigsave_t ihand,qhand; /* place to save signals during system() */
4202             int status;
4203
4204             if (did_pipes)
4205                 PerlLIO_close(pp[1]);
4206 #ifndef PERL_MICRO
4207             rsignal_save(SIGINT, SIG_IGN, &ihand);
4208             rsignal_save(SIGQUIT, SIG_IGN, &qhand);
4209 #endif
4210             do {
4211                 result = wait4pid(childpid, &status, 0);
4212             } while (result == -1 && errno == EINTR);
4213 #ifndef PERL_MICRO
4214             (void)rsignal_restore(SIGINT, &ihand);
4215             (void)rsignal_restore(SIGQUIT, &qhand);
4216 #endif
4217             STATUS_NATIVE_SET(result == -1 ? -1 : status);
4218             do_execfree();      /* free any memory child malloced on fork */
4219             SP = ORIGMARK;
4220             if (did_pipes) {
4221                 int errkid;
4222                 int n = 0, n1;
4223
4224                 while (n < sizeof(int)) {
4225                     n1 = PerlLIO_read(pp[0],
4226                                       (void*)(((char*)&errkid)+n),
4227                                       (sizeof(int)) - n);
4228                     if (n1 <= 0)
4229                         break;
4230                     n += n1;
4231                 }
4232                 PerlLIO_close(pp[0]);
4233                 if (n) {                        /* Error */
4234                     if (n != sizeof(int))
4235                         DIE(aTHX_ "panic: kid popen errno read");
4236                     errno = errkid;             /* Propagate errno from kid */
4237                     STATUS_CURRENT = -1;
4238                 }
4239             }
4240             PUSHi(STATUS_CURRENT);
4241             RETURN;
4242         }
4243         if (did_pipes) {
4244             PerlLIO_close(pp[0]);
4245 #if defined(HAS_FCNTL) && defined(F_SETFD)
4246             fcntl(pp[1], F_SETFD, FD_CLOEXEC);
4247 #endif
4248         }
4249         if (PL_op->op_flags & OPf_STACKED) {
4250             SV *really = *++MARK;
4251             value = (I32)do_aexec5(really, MARK, SP, pp[1], did_pipes);
4252         }
4253         else if (SP - MARK != 1)
4254             value = (I32)do_aexec5(Nullsv, MARK, SP, pp[1], did_pipes);
4255         else {
4256             value = (I32)do_exec3(SvPVx_nolen(sv_mortalcopy(*SP)), pp[1], did_pipes);
4257         }
4258         PerlProc__exit(-1);
4259     }
4260 #else /* ! FORK or VMS or OS/2 */
4261     PL_statusvalue = 0;
4262     result = 0;
4263     if (PL_op->op_flags & OPf_STACKED) {
4264         SV *really = *++MARK;
4265 #  if defined(WIN32) || defined(OS2) || defined(SYMBIAN)
4266         value = (I32)do_aspawn(really, MARK, SP);
4267 #  else
4268         value = (I32)do_aspawn(really, (void **)MARK, (void **)SP);
4269 #  endif
4270     }
4271     else if (SP - MARK != 1) {
4272 #  if defined(WIN32) || defined(OS2) || defined(SYMBIAN)
4273         value = (I32)do_aspawn(Nullsv, MARK, SP);
4274 #  else
4275         value = (I32)do_aspawn(Nullsv, (void **)MARK, (void **)SP);
4276 #  endif
4277     }
4278     else {
4279         value = (I32)do_spawn(SvPVx_nolen(sv_mortalcopy(*SP)));
4280     }
4281     if (PL_statusvalue == -1)   /* hint that value must be returned as is */
4282         result = 1;
4283     STATUS_NATIVE_SET(value);
4284     do_execfree();
4285     SP = ORIGMARK;
4286     PUSHi(result ? value : STATUS_CURRENT);
4287 #endif /* !FORK or VMS */
4288     RETURN;
4289 }
4290
4291 PP(pp_exec)
4292 {
4293     dSP; dMARK; dORIGMARK; dTARGET;
4294     I32 value;
4295
4296     if (PL_tainting) {
4297         TAINT_ENV();
4298         while (++MARK <= SP) {
4299             (void)SvPV_nolen_const(*MARK);      /* stringify for taint check */
4300             if (PL_tainted)
4301                 break;
4302         }
4303         MARK = ORIGMARK;
4304         TAINT_PROPER("exec");
4305     }
4306     PERL_FLUSHALL_FOR_CHILD;
4307     if (PL_op->op_flags & OPf_STACKED) {
4308         SV *really = *++MARK;
4309         value = (I32)do_aexec(really, MARK, SP);
4310     }
4311     else if (SP - MARK != 1)
4312 #ifdef VMS
4313         value = (I32)vms_do_aexec(Nullsv, MARK, SP);
4314 #else
4315 #  ifdef __OPEN_VM
4316         {
4317            (void ) do_aspawn(Nullsv, MARK, SP);
4318            value = 0;
4319         }
4320 #  else
4321         value = (I32)do_aexec(Nullsv, MARK, SP);
4322 #  endif
4323 #endif
4324     else {
4325 #ifdef VMS
4326         value = (I32)vms_do_exec(SvPVx_nolen(sv_mortalcopy(*SP)));
4327 #else
4328 #  ifdef __OPEN_VM
4329         (void) do_spawn(SvPVx_nolen(sv_mortalcopy(*SP)));
4330         value = 0;
4331 #  else
4332         value = (I32)do_exec(SvPVx_nolen(sv_mortalcopy(*SP)));
4333 #  endif
4334 #endif
4335     }
4336
4337     SP = ORIGMARK;
4338     PUSHi(value);
4339     RETURN;
4340 }
4341
4342 PP(pp_kill)
4343 {
4344 #ifdef HAS_KILL
4345     dSP; dMARK; dTARGET;
4346     I32 value;
4347     value = (I32)apply(PL_op->op_type, MARK, SP);
4348     SP = MARK;
4349     PUSHi(value);
4350     RETURN;
4351 #else
4352     DIE(aTHX_ PL_no_func, "kill");
4353 #endif
4354 }
4355
4356 PP(pp_getppid)
4357 {
4358 #ifdef HAS_GETPPID
4359     dSP; dTARGET;
4360 #   ifdef THREADS_HAVE_PIDS
4361     if (PL_ppid != 1 && getppid() == 1)
4362         /* maybe the parent process has died. Refresh ppid cache */
4363         PL_ppid = 1;
4364     XPUSHi( PL_ppid );
4365 #   else
4366     XPUSHi( getppid() );
4367 #   endif
4368     RETURN;
4369 #else
4370     DIE(aTHX_ PL_no_func, "getppid");
4371 #endif
4372 }
4373
4374 PP(pp_getpgrp)
4375 {
4376 #ifdef HAS_GETPGRP
4377     dSP; dTARGET;
4378     Pid_t pid;
4379     Pid_t pgrp;
4380
4381     if (MAXARG < 1)
4382         pid = 0;
4383     else
4384         pid = SvIVx(POPs);
4385 #ifdef BSD_GETPGRP
4386     pgrp = (I32)BSD_GETPGRP(pid);
4387 #else
4388     if (pid != 0 && pid != PerlProc_getpid())
4389         DIE(aTHX_ "POSIX getpgrp can't take an argument");
4390     pgrp = getpgrp();
4391 #endif
4392     XPUSHi(pgrp);
4393     RETURN;
4394 #else
4395     DIE(aTHX_ PL_no_func, "getpgrp()");
4396 #endif
4397 }
4398
4399 PP(pp_setpgrp)
4400 {
4401 #ifdef HAS_SETPGRP
4402     dSP; dTARGET;
4403     Pid_t pgrp;
4404     Pid_t pid;
4405     if (MAXARG < 2) {
4406         pgrp = 0;
4407         pid = 0;
4408     }
4409     else {
4410         pgrp = POPi;
4411         pid = TOPi;
4412     }
4413
4414     TAINT_PROPER("setpgrp");
4415 #ifdef BSD_SETPGRP
4416     SETi( BSD_SETPGRP(pid, pgrp) >= 0 );
4417 #else
4418     if ((pgrp != 0 && pgrp != PerlProc_getpid())
4419         || (pid != 0 && pid != PerlProc_getpid()))
4420     {
4421         DIE(aTHX_ "setpgrp can't take arguments");
4422     }
4423     SETi( setpgrp() >= 0 );
4424 #endif /* USE_BSDPGRP */
4425     RETURN;
4426 #else
4427     DIE(aTHX_ PL_no_func, "setpgrp()");
4428 #endif
4429 }
4430
4431 PP(pp_getpriority)
4432 {
4433 #ifdef HAS_GETPRIORITY
4434     dSP; dTARGET;
4435     int who = POPi;
4436     int which = TOPi;
4437     SETi( getpriority(which, who) );
4438     RETURN;
4439 #else
4440     DIE(aTHX_ PL_no_func, "getpriority()");
4441 #endif
4442 }
4443
4444 PP(pp_setpriority)
4445 {
4446 #ifdef HAS_SETPRIORITY
4447     dSP; dTARGET;
4448     int niceval = POPi;
4449     int who = POPi;
4450     int which = TOPi;
4451     TAINT_PROPER("setpriority");
4452     SETi( setpriority(which, who, niceval) >= 0 );
4453     RETURN;
4454 #else
4455     DIE(aTHX_ PL_no_func, "setpriority()");
4456 #endif
4457 }
4458
4459 /* Time calls. */
4460
4461 PP(pp_time)
4462 {
4463     dSP; dTARGET;
4464 #ifdef BIG_TIME
4465     XPUSHn( time(Null(Time_t*)) );
4466 #else
4467     XPUSHi( time(Null(Time_t*)) );
4468 #endif
4469     RETURN;
4470 }
4471
4472 PP(pp_tms)
4473 {
4474 #ifdef HAS_TIMES
4475     dSP;
4476     EXTEND(SP, 4);
4477 #ifndef VMS
4478     (void)PerlProc_times(&PL_timesbuf);
4479 #else
4480     (void)PerlProc_times((tbuffer_t *)&PL_timesbuf);  /* time.h uses different name for */
4481                                                    /* struct tms, though same data   */
4482                                                    /* is returned.                   */
4483 #endif
4484
4485     PUSHs(sv_2mortal(newSVnv(((NV)PL_timesbuf.tms_utime)/(NV)PL_clocktick)));
4486     if (GIMME == G_ARRAY) {
4487         PUSHs(sv_2mortal(newSVnv(((NV)PL_timesbuf.tms_stime)/(NV)PL_clocktick)));
4488         PUSHs(sv_2mortal(newSVnv(((NV)PL_timesbuf.tms_cutime)/(NV)PL_clocktick)));
4489         PUSHs(sv_2mortal(newSVnv(((NV)PL_timesbuf.tms_cstime)/(NV)PL_clocktick)));
4490     }
4491     RETURN;
4492 #else
4493 #   ifdef PERL_MICRO
4494     dSP;
4495     PUSHs(sv_2mortal(newSVnv((NV)0.0)));
4496     EXTEND(SP, 4);
4497     if (GIMME == G_ARRAY) {
4498          PUSHs(sv_2mortal(newSVnv((NV)0.0)));
4499          PUSHs(sv_2mortal(newSVnv((NV)0.0)));
4500          PUSHs(sv_2mortal(newSVnv((NV)0.0)));
4501     }
4502     RETURN;
4503 #   else
4504     DIE(aTHX_ "times not implemented");
4505 #   endif
4506 #endif /* HAS_TIMES */
4507 }
4508
4509 PP(pp_localtime)
4510 {
4511     return pp_gmtime();
4512 }
4513
4514 #ifdef LOCALTIME_EDGECASE_BROKEN
4515 static struct tm *S_my_localtime (pTHX_ Time_t *tp)
4516 {
4517     auto time_t     T;
4518     auto struct tm *P;
4519
4520     /* No workarounds in the valid range */
4521     if (!tp || *tp < 0x7fff573f || *tp >= 0x80000000)
4522         return (localtime (tp));
4523
4524     /* This edge case is to workaround the undefined behaviour, where the
4525      * TIMEZONE makes the time go beyond the defined range.
4526      * gmtime (0x7fffffff) => 2038-01-19 03:14:07
4527      * If there is a negative offset in TZ, like MET-1METDST, some broken
4528      * implementations of localtime () (like AIX 5.2) barf with bogus
4529      * return values:
4530      * 0x7fffffff gmtime               2038-01-19 03:14:07
4531      * 0x7fffffff localtime            1901-12-13 21:45:51
4532      * 0x7fffffff mylocaltime          2038-01-19 04:14:07
4533      * 0x3c19137f gmtime               2001-12-13 20:45:51
4534      * 0x3c19137f localtime            2001-12-13 21:45:51
4535      * 0x3c19137f mylocaltime          2001-12-13 21:45:51
4536      * Given that legal timezones are typically between GMT-12 and GMT+12
4537      * we turn back the clock 23 hours before calling the localtime
4538      * function, and add those to the return value. This will never cause
4539      * day wrapping problems, since the edge case is Jan *19*
4540      */
4541     T = *tp - 82800; /* 23 hour. allows up to GMT-23 */
4542     P = localtime (&T);
4543     P->tm_hour += 23;
4544     if (P->tm_hour >= 24) {
4545         P->tm_hour -= 24;
4546         P->tm_mday++;
4547     }
4548     return (P);
4549 } /* S_my_localtime */
4550 #endif
4551
4552 PP(pp_gmtime)
4553 {
4554     dSP;
4555     Time_t when;
4556     const struct tm *tmbuf;
4557     static const char * const dayname[] =
4558         {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
4559     static const char * const monname[] =
4560         {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
4561          "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
4562
4563     if (MAXARG < 1)
4564         (void)time(&when);
4565     else
4566 #ifdef BIG_TIME
4567         when = (Time_t)SvNVx(POPs);
4568 #else
4569         when = (Time_t)SvIVx(POPs);
4570 #endif
4571
4572     if (PL_op->op_type == OP_LOCALTIME)
4573 #ifdef LOCALTIME_EDGECASE_BROKEN
4574         tmbuf = S_my_localtime(aTHX_ &when);
4575 #else
4576         tmbuf = localtime(&when);
4577 #endif
4578     else
4579         tmbuf = gmtime(&when);
4580
4581     if (GIMME != G_ARRAY) {
4582         SV *tsv;
4583         EXTEND(SP, 1);
4584         EXTEND_MORTAL(1);
4585         if (!tmbuf)
4586             RETPUSHUNDEF;
4587         tsv = Perl_newSVpvf(aTHX_ "%s %s %2d %02d:%02d:%02d %d",
4588                             dayname[tmbuf->tm_wday],
4589                             monname[tmbuf->tm_mon],
4590                             tmbuf->tm_mday,
4591                             tmbuf->tm_hour,
4592                             tmbuf->tm_min,
4593                             tmbuf->tm_sec,
4594                             tmbuf->tm_year + 1900);
4595         PUSHs(sv_2mortal(tsv));
4596     }
4597     else if (tmbuf) {
4598         EXTEND(SP, 9);
4599         EXTEND_MORTAL(9);
4600         PUSHs(sv_2mortal(newSViv(tmbuf->tm_sec)));
4601         PUSHs(sv_2mortal(newSViv(tmbuf->tm_min)));
4602         PUSHs(sv_2mortal(newSViv(tmbuf->tm_hour)));
4603         PUSHs(sv_2mortal(newSViv(tmbuf->tm_mday)));
4604         PUSHs(sv_2mortal(newSViv(tmbuf->tm_mon)));
4605         PUSHs(sv_2mortal(newSViv(tmbuf->tm_year)));
4606         PUSHs(sv_2mortal(newSViv(tmbuf->tm_wday)));
4607         PUSHs(sv_2mortal(newSViv(tmbuf->tm_yday)));
4608         PUSHs(sv_2mortal(newSViv(tmbuf->tm_isdst)));
4609     }
4610     RETURN;
4611 }
4612
4613 PP(pp_alarm)
4614 {
4615 #ifdef HAS_ALARM
4616     dSP; dTARGET;
4617     int anum;
4618     anum = POPi;
4619     anum = alarm((unsigned int)anum);
4620     EXTEND(SP, 1);
4621     if (anum < 0)
4622         RETPUSHUNDEF;
4623     PUSHi(anum);
4624     RETURN;
4625 #else
4626     DIE(aTHX_ PL_no_func, "alarm");
4627 #endif
4628 }
4629
4630 PP(pp_sleep)
4631 {
4632     dSP; dTARGET;
4633     I32 duration;
4634     Time_t lasttime;
4635     Time_t when;
4636
4637     (void)time(&lasttime);
4638     if (MAXARG < 1)
4639         PerlProc_pause();
4640     else {
4641         duration = POPi;
4642         PerlProc_sleep((unsigned int)duration);
4643     }
4644     (void)time(&when);
4645     XPUSHi(when - lasttime);
4646     RETURN;
4647 }
4648
4649 /* Shared memory. */
4650
4651 PP(pp_shmget)
4652 {
4653     return pp_semget();
4654 }
4655
4656 PP(pp_shmctl)
4657 {
4658     return pp_semctl();
4659 }
4660
4661 PP(pp_shmread)
4662 {
4663     return pp_shmwrite();
4664 }
4665
4666 PP(pp_shmwrite)
4667 {
4668 #if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
4669     dSP; dMARK; dTARGET;
4670     I32 value = (I32)(do_shmio(PL_op->op_type, MARK, SP) >= 0);
4671     SP = MARK;
4672     PUSHi(value);
4673     RETURN;
4674 #else
4675     return pp_semget();
4676 #endif
4677 }
4678
4679 /* Message passing. */
4680
4681 PP(pp_msgget)
4682 {
4683     return pp_semget();
4684 }
4685
4686 PP(pp_msgctl)
4687 {
4688     return pp_semctl();
4689 }
4690
4691 PP(pp_msgsnd)
4692 {
4693 #if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
4694     dSP; dMARK; dTARGET;
4695     I32 value = (I32)(do_msgsnd(MARK, SP) >= 0);
4696     SP = MARK;
4697     PUSHi(value);
4698     RETURN;
4699 #else
4700     return pp_semget();
4701 #endif
4702 }
4703
4704 PP(pp_msgrcv)
4705 {
4706 #if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
4707     dSP; dMARK; dTARGET;
4708     I32 value = (I32)(do_msgrcv(MARK, SP) >= 0);
4709     SP = MARK;
4710     PUSHi(value);
4711     RETURN;
4712 #else
4713     return pp_semget();
4714 #endif
4715 }
4716
4717 /* Semaphores. */
4718
4719 PP(pp_semget)
4720 {
4721 #if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
4722     dSP; dMARK; dTARGET;
4723     int anum = do_ipcget(PL_op->op_type, MARK, SP);
4724     SP = MARK;
4725     if (anum == -1)
4726         RETPUSHUNDEF;
4727     PUSHi(anum);
4728     RETURN;
4729 #else
4730     DIE(aTHX_ "System V IPC is not implemented on this machine");
4731 #endif
4732 }
4733
4734 PP(pp_semctl)
4735 {
4736 #if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
4737     dSP; dMARK; dTARGET;
4738     int anum = do_ipcctl(PL_op->op_type, MARK, SP);
4739     SP = MARK;
4740     if (anum == -1)
4741         RETSETUNDEF;
4742     if (anum != 0) {
4743         PUSHi(anum);
4744     }
4745     else {
4746         PUSHp(zero_but_true, ZBTLEN);
4747     }
4748     RETURN;
4749 #else
4750     return pp_semget();
4751 #endif
4752 }
4753
4754 PP(pp_semop)
4755 {
4756 #if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
4757     dSP; dMARK; dTARGET;
4758     I32 value = (I32)(do_semop(MARK, SP) >= 0);
4759     SP = MARK;
4760     PUSHi(value);
4761     RETURN;
4762 #else
4763     return pp_semget();
4764 #endif
4765 }
4766
4767 /* Get system info. */
4768
4769 PP(pp_ghbyname)
4770 {
4771 #ifdef HAS_GETHOSTBYNAME
4772     return pp_ghostent();
4773 #else
4774     DIE(aTHX_ PL_no_sock_func, "gethostbyname");
4775 #endif
4776 }
4777
4778 PP(pp_ghbyaddr)
4779 {
4780 #ifdef HAS_GETHOSTBYADDR
4781     return pp_ghostent();
4782 #else
4783     DIE(aTHX_ PL_no_sock_func, "gethostbyaddr");
4784 #endif
4785 }
4786
4787 PP(pp_ghostent)
4788 {
4789 #if defined(HAS_GETHOSTBYNAME) || defined(HAS_GETHOSTBYADDR) || defined(HAS_GETHOSTENT)
4790     dSP;
4791     I32 which = PL_op->op_type;
4792     register char **elem;
4793     register SV *sv;
4794 #ifndef HAS_GETHOST_PROTOS /* XXX Do we need individual probes? */
4795     struct hostent *gethostbyaddr(Netdb_host_t, Netdb_hlen_t, int);
4796     struct hostent *gethostbyname(Netdb_name_t);
4797     struct hostent *gethostent(void);
4798 #endif
4799     struct hostent *hent;
4800     unsigned long len;
4801
4802     EXTEND(SP, 10);
4803     if (which == OP_GHBYNAME) {
4804 #ifdef HAS_GETHOSTBYNAME
4805         char* name = POPpbytex;
4806         hent = PerlSock_gethostbyname(name);
4807 #else
4808         DIE(aTHX_ PL_no_sock_func, "gethostbyname");
4809 #endif
4810     }
4811     else if (which == OP_GHBYADDR) {
4812 #ifdef HAS_GETHOSTBYADDR
4813         int addrtype = POPi;
4814         SV *addrsv = POPs;
4815         STRLEN addrlen;
4816         Netdb_host_t addr = (Netdb_host_t) SvPVbyte(addrsv, addrlen);
4817
4818         hent = PerlSock_gethostbyaddr(addr, (Netdb_hlen_t) addrlen, addrtype);
4819 #else
4820         DIE(aTHX_ PL_no_sock_func, "gethostbyaddr");
4821 #endif
4822     }
4823     else
4824 #ifdef HAS_GETHOSTENT
4825         hent = PerlSock_gethostent();
4826 #else
4827         DIE(aTHX_ PL_no_sock_func, "gethostent");
4828 #endif
4829
4830 #ifdef HOST_NOT_FOUND
4831         if (!hent) {
4832 #ifdef USE_REENTRANT_API
4833 #   ifdef USE_GETHOSTENT_ERRNO
4834             h_errno = PL_reentrant_buffer->_gethostent_errno;
4835 #   endif
4836 #endif
4837             STATUS_NATIVE_SET(h_errno);
4838         }
4839 #endif
4840
4841     if (GIMME != G_ARRAY) {
4842         PUSHs(sv = sv_newmortal());
4843         if (hent) {
4844             if (which == OP_GHBYNAME) {
4845                 if (hent->h_addr)
4846                     sv_setpvn(sv, hent->h_addr, hent->h_length);
4847             }
4848             else
4849                 sv_setpv(sv, (char*)hent->h_name);
4850         }
4851         RETURN;
4852     }
4853
4854     if (hent) {
4855         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
4856         sv_setpv(sv, (char*)hent->h_name);
4857         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
4858         for (elem = hent->h_aliases; elem && *elem; elem++) {
4859             sv_catpv(sv, *elem);
4860             if (elem[1])
4861                 sv_catpvn(sv, " ", 1);
4862         }
4863         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
4864         sv_setiv(sv, (IV)hent->h_addrtype);
4865         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
4866         len = hent->h_length;
4867         sv_setiv(sv, (IV)len);
4868 #ifdef h_addr
4869         for (elem = hent->h_addr_list; elem && *elem; elem++) {
4870             XPUSHs(sv = sv_mortalcopy(&PL_sv_no));
4871             sv_setpvn(sv, *elem, len);
4872         }
4873 #else
4874         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
4875         if (hent->h_addr)
4876             sv_setpvn(sv, hent->h_addr, len);
4877 #endif /* h_addr */
4878     }
4879     RETURN;
4880 #else
4881     DIE(aTHX_ PL_no_sock_func, "gethostent");
4882 #endif
4883 }
4884
4885 PP(pp_gnbyname)
4886 {
4887 #ifdef HAS_GETNETBYNAME
4888     return pp_gnetent();
4889 #else
4890     DIE(aTHX_ PL_no_sock_func, "getnetbyname");
4891 #endif
4892 }
4893
4894 PP(pp_gnbyaddr)
4895 {
4896 #ifdef HAS_GETNETBYADDR
4897     return pp_gnetent();
4898 #else
4899     DIE(aTHX_ PL_no_sock_func, "getnetbyaddr");
4900 #endif
4901 }
4902
4903 PP(pp_gnetent)
4904 {
4905 #if defined(HAS_GETNETBYNAME) || defined(HAS_GETNETBYADDR) || defined(HAS_GETNETENT)
4906     dSP;
4907     I32 which = PL_op->op_type;
4908     register char **elem;
4909     register SV *sv;
4910 #ifndef HAS_GETNET_PROTOS /* XXX Do we need individual probes? */
4911     struct netent *getnetbyaddr(Netdb_net_t, int);
4912     struct netent *getnetbyname(Netdb_name_t);
4913     struct netent *getnetent(void);
4914 #endif
4915     struct netent *nent;
4916
4917     if (which == OP_GNBYNAME){
4918 #ifdef HAS_GETNETBYNAME
4919         char *name = POPpbytex;
4920         nent = PerlSock_getnetbyname(name);
4921 #else
4922         DIE(aTHX_ PL_no_sock_func, "getnetbyname");
4923 #endif
4924     }
4925     else if (which == OP_GNBYADDR) {
4926 #ifdef HAS_GETNETBYADDR
4927         int addrtype = POPi;
4928         Netdb_net_t addr = (Netdb_net_t) (U32)POPu;
4929         nent = PerlSock_getnetbyaddr(addr, addrtype);
4930 #else
4931         DIE(aTHX_ PL_no_sock_func, "getnetbyaddr");
4932 #endif
4933     }
4934     else
4935 #ifdef HAS_GETNETENT
4936         nent = PerlSock_getnetent();
4937 #else
4938         DIE(aTHX_ PL_no_sock_func, "getnetent");
4939 #endif
4940
4941 #ifdef HOST_NOT_FOUND
4942         if (!nent) {
4943 #ifdef USE_REENTRANT_API
4944 #   ifdef USE_GETNETENT_ERRNO
4945              h_errno = PL_reentrant_buffer->_getnetent_errno;
4946 #   endif
4947 #endif
4948             STATUS_NATIVE_SET(h_errno);
4949         }
4950 #endif
4951
4952     EXTEND(SP, 4);
4953     if (GIMME != G_ARRAY) {
4954         PUSHs(sv = sv_newmortal());
4955         if (nent) {
4956             if (which == OP_GNBYNAME)
4957                 sv_setiv(sv, (IV)nent->n_net);
4958             else
4959                 sv_setpv(sv, nent->n_name);
4960         }
4961         RETURN;
4962     }
4963
4964     if (nent) {
4965         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
4966         sv_setpv(sv, nent->n_name);
4967         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
4968         for (elem = nent->n_aliases; elem && *elem; elem++) {
4969             sv_catpv(sv, *elem);
4970             if (elem[1])
4971                 sv_catpvn(sv, " ", 1);
4972         }
4973         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
4974         sv_setiv(sv, (IV)nent->n_addrtype);
4975         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
4976         sv_setiv(sv, (IV)nent->n_net);
4977     }
4978
4979     RETURN;
4980 #else
4981     DIE(aTHX_ PL_no_sock_func, "getnetent");
4982 #endif
4983 }
4984
4985 PP(pp_gpbyname)
4986 {
4987 #ifdef HAS_GETPROTOBYNAME
4988     return pp_gprotoent();
4989 #else
4990     DIE(aTHX_ PL_no_sock_func, "getprotobyname");
4991 #endif
4992 }
4993
4994 PP(pp_gpbynumber)
4995 {
4996 #ifdef HAS_GETPROTOBYNUMBER
4997     return pp_gprotoent();
4998 #else
4999     DIE(aTHX_ PL_no_sock_func, "getprotobynumber");
5000 #endif
5001 }
5002
5003 PP(pp_gprotoent)
5004 {
5005 #if defined(HAS_GETPROTOBYNAME) || defined(HAS_GETPROTOBYNUMBER) || defined(HAS_GETPROTOENT)
5006     dSP;
5007     I32 which = PL_op->op_type;
5008     register char **elem;
5009     register SV *sv;
5010 #ifndef HAS_GETPROTO_PROTOS /* XXX Do we need individual probes? */
5011     struct protoent *getprotobyname(Netdb_name_t);
5012     struct protoent *getprotobynumber(int);
5013     struct protoent *getprotoent(void);
5014 #endif
5015     struct protoent *pent;
5016
5017     if (which == OP_GPBYNAME) {
5018 #ifdef HAS_GETPROTOBYNAME
5019         char* name = POPpbytex;
5020         pent = PerlSock_getprotobyname(name);
5021 #else
5022         DIE(aTHX_ PL_no_sock_func, "getprotobyname");
5023 #endif
5024     }
5025     else if (which == OP_GPBYNUMBER) {
5026 #ifdef HAS_GETPROTOBYNUMBER
5027         int number = POPi;
5028         pent = PerlSock_getprotobynumber(number);
5029 #else
5030         DIE(aTHX_ PL_no_sock_func, "getprotobynumber");
5031 #endif
5032     }
5033     else
5034 #ifdef HAS_GETPROTOENT
5035         pent = PerlSock_getprotoent();
5036 #else
5037         DIE(aTHX_ PL_no_sock_func, "getprotoent");
5038 #endif
5039
5040     EXTEND(SP, 3);
5041     if (GIMME != G_ARRAY) {
5042         PUSHs(sv = sv_newmortal());
5043         if (pent) {
5044             if (which == OP_GPBYNAME)
5045                 sv_setiv(sv, (IV)pent->p_proto);
5046             else
5047                 sv_setpv(sv, pent->p_name);
5048         }
5049         RETURN;
5050     }
5051
5052     if (pent) {
5053         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
5054         sv_setpv(sv, pent->p_name);
5055         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
5056         for (elem = pent->p_aliases; elem && *elem; elem++) {
5057             sv_catpv(sv, *elem);
5058             if (elem[1])
5059                 sv_catpvn(sv, " ", 1);
5060         }
5061         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
5062         sv_setiv(sv, (IV)pent->p_proto);
5063     }
5064
5065     RETURN;
5066 #else
5067     DIE(aTHX_ PL_no_sock_func, "getprotoent");
5068 #endif
5069 }
5070
5071 PP(pp_gsbyname)
5072 {
5073 #ifdef HAS_GETSERVBYNAME
5074     return pp_gservent();
5075 #else
5076     DIE(aTHX_ PL_no_sock_func, "getservbyname");
5077 #endif
5078 }
5079
5080 PP(pp_gsbyport)
5081 {
5082 #ifdef HAS_GETSERVBYPORT
5083     return pp_gservent();
5084 #else
5085     DIE(aTHX_ PL_no_sock_func, "getservbyport");
5086 #endif
5087 }
5088
5089 PP(pp_gservent)
5090 {
5091 #if defined(HAS_GETSERVBYNAME) || defined(HAS_GETSERVBYPORT) || defined(HAS_GETSERVENT)
5092     dSP;
5093     I32 which = PL_op->op_type;
5094     register char **elem;
5095     register SV *sv;
5096 #ifndef HAS_GETSERV_PROTOS /* XXX Do we need individual probes? */
5097     struct servent *getservbyname(Netdb_name_t, Netdb_name_t);
5098     struct servent *getservbyport(int, Netdb_name_t);
5099     struct servent *getservent(void);
5100 #endif
5101     struct servent *sent;
5102
5103     if (which == OP_GSBYNAME) {
5104 #ifdef HAS_GETSERVBYNAME
5105         char *proto = POPpbytex;
5106         char *name = POPpbytex;
5107
5108         if (proto && !*proto)
5109             proto = Nullch;
5110
5111         sent = PerlSock_getservbyname(name, proto);
5112 #else
5113         DIE(aTHX_ PL_no_sock_func, "getservbyname");
5114 #endif
5115     }
5116     else if (which == OP_GSBYPORT) {
5117 #ifdef HAS_GETSERVBYPORT
5118         char *proto = POPpbytex;
5119         unsigned short port = (unsigned short)POPu;
5120
5121         if (proto && !*proto)
5122             proto = Nullch;
5123
5124 #ifdef HAS_HTONS
5125         port = PerlSock_htons(port);
5126 #endif
5127         sent = PerlSock_getservbyport(port, proto);
5128 #else
5129         DIE(aTHX_ PL_no_sock_func, "getservbyport");
5130 #endif
5131     }
5132     else
5133 #ifdef HAS_GETSERVENT
5134         sent = PerlSock_getservent();
5135 #else
5136         DIE(aTHX_ PL_no_sock_func, "getservent");
5137 #endif
5138
5139     EXTEND(SP, 4);
5140     if (GIMME != G_ARRAY) {
5141         PUSHs(sv = sv_newmortal());
5142         if (sent) {
5143             if (which == OP_GSBYNAME) {
5144 #ifdef HAS_NTOHS
5145                 sv_setiv(sv, (IV)PerlSock_ntohs(sent->s_port));
5146 #else
5147                 sv_setiv(sv, (IV)(sent->s_port));
5148 #endif
5149             }
5150             else
5151                 sv_setpv(sv, sent->s_name);
5152         }
5153         RETURN;
5154     }
5155
5156     if (sent) {
5157         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
5158         sv_setpv(sv, sent->s_name);
5159         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
5160         for (elem = sent->s_aliases; elem && *elem; elem++) {
5161             sv_catpv(sv, *elem);
5162             if (elem[1])
5163                 sv_catpvn(sv, " ", 1);
5164         }
5165         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
5166 #ifdef HAS_NTOHS
5167         sv_setiv(sv, (IV)PerlSock_ntohs(sent->s_port));
5168 #else
5169         sv_setiv(sv, (IV)(sent->s_port));
5170 #endif
5171         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
5172         sv_setpv(sv, sent->s_proto);
5173     }
5174
5175     RETURN;
5176 #else
5177     DIE(aTHX_ PL_no_sock_func, "getservent");
5178 #endif
5179 }
5180
5181 PP(pp_shostent)
5182 {
5183 #ifdef HAS_SETHOSTENT
5184     dSP;
5185     PerlSock_sethostent(TOPi);
5186     RETSETYES;
5187 #else
5188     DIE(aTHX_ PL_no_sock_func, "sethostent");
5189 #endif
5190 }
5191
5192 PP(pp_snetent)
5193 {
5194 #ifdef HAS_SETNETENT
5195     dSP;
5196     PerlSock_setnetent(TOPi);
5197     RETSETYES;
5198 #else
5199     DIE(aTHX_ PL_no_sock_func, "setnetent");
5200 #endif
5201 }
5202
5203 PP(pp_sprotoent)
5204 {
5205 #ifdef HAS_SETPROTOENT
5206     dSP;
5207     PerlSock_setprotoent(TOPi);
5208     RETSETYES;
5209 #else
5210     DIE(aTHX_ PL_no_sock_func, "setprotoent");
5211 #endif
5212 }
5213
5214 PP(pp_sservent)
5215 {
5216 #ifdef HAS_SETSERVENT
5217     dSP;
5218     PerlSock_setservent(TOPi);
5219     RETSETYES;
5220 #else
5221     DIE(aTHX_ PL_no_sock_func, "setservent");
5222 #endif
5223 }
5224
5225 PP(pp_ehostent)
5226 {
5227 #ifdef HAS_ENDHOSTENT
5228     dSP;
5229     PerlSock_endhostent();
5230     EXTEND(SP,1);
5231     RETPUSHYES;
5232 #else
5233     DIE(aTHX_ PL_no_sock_func, "endhostent");
5234 #endif
5235 }
5236
5237 PP(pp_enetent)
5238 {
5239 #ifdef HAS_ENDNETENT
5240     dSP;
5241     PerlSock_endnetent();
5242     EXTEND(SP,1);
5243     RETPUSHYES;
5244 #else
5245     DIE(aTHX_ PL_no_sock_func, "endnetent");
5246 #endif
5247 }
5248
5249 PP(pp_eprotoent)
5250 {
5251 #ifdef HAS_ENDPROTOENT
5252     dSP;
5253     PerlSock_endprotoent();
5254     EXTEND(SP,1);
5255     RETPUSHYES;
5256 #else
5257     DIE(aTHX_ PL_no_sock_func, "endprotoent");
5258 #endif
5259 }
5260
5261 PP(pp_eservent)
5262 {
5263 #ifdef HAS_ENDSERVENT
5264     dSP;
5265     PerlSock_endservent();
5266     EXTEND(SP,1);
5267     RETPUSHYES;
5268 #else
5269     DIE(aTHX_ PL_no_sock_func, "endservent");
5270 #endif
5271 }
5272
5273 PP(pp_gpwnam)
5274 {
5275 #ifdef HAS_PASSWD
5276     return pp_gpwent();
5277 #else
5278     DIE(aTHX_ PL_no_func, "getpwnam");
5279 #endif
5280 }
5281
5282 PP(pp_gpwuid)
5283 {
5284 #ifdef HAS_PASSWD
5285     return pp_gpwent();
5286 #else
5287     DIE(aTHX_ PL_no_func, "getpwuid");
5288 #endif
5289 }
5290
5291 PP(pp_gpwent)
5292 {
5293 #ifdef HAS_PASSWD
5294     dSP;
5295     I32 which = PL_op->op_type;
5296     register SV *sv;
5297     struct passwd *pwent  = NULL;
5298     /*
5299      * We currently support only the SysV getsp* shadow password interface.
5300      * The interface is declared in <shadow.h> and often one needs to link
5301      * with -lsecurity or some such.
5302      * This interface is used at least by Solaris, HP-UX, IRIX, and Linux.
5303      * (and SCO?)
5304      *
5305      * AIX getpwnam() is clever enough to return the encrypted password
5306      * only if the caller (euid?) is root.
5307      *
5308      * There are at least three other shadow password APIs.  Many platforms
5309      * seem to contain more than one interface for accessing the shadow
5310      * password databases, possibly for compatibility reasons.
5311      * The getsp*() is by far he simplest one, the other two interfaces
5312      * are much more complicated, but also very similar to each other.
5313      *
5314      * <sys/types.h>
5315      * <sys/security.h>
5316      * <prot.h>
5317      * struct pr_passwd *getprpw*();
5318      * The password is in
5319      * char getprpw*(...).ufld.fd_encrypt[]
5320      * Mention HAS_GETPRPWNAM here so that Configure probes for it.
5321      *
5322      * <sys/types.h>
5323      * <sys/security.h>
5324      * <prot.h>
5325      * struct es_passwd *getespw*();
5326      * The password is in
5327      * char *(getespw*(...).ufld.fd_encrypt)
5328      * Mention HAS_GETESPWNAM here so that Configure probes for it.
5329      *
5330      * <userpw.h> (AIX)
5331      * struct userpw *getuserpw();
5332      * The password is in
5333      * char *(getuserpw(...)).spw_upw_passwd
5334      * (but the de facto standard getpwnam() should work okay)
5335      *
5336      * Mention I_PROT here so that Configure probes for it.
5337      *
5338      * In HP-UX for getprpw*() the manual page claims that one should include
5339      * <hpsecurity.h> instead of <sys/security.h>, but that is not needed
5340      * if one includes <shadow.h> as that includes <hpsecurity.h>,
5341      * and pp_sys.c already includes <shadow.h> if there is such.
5342      *
5343      * Note that <sys/security.h> is already probed for, but currently
5344      * it is only included in special cases.
5345      *
5346      * In Digital UNIX/Tru64 if using the getespw*() (which seems to be
5347      * be preferred interface, even though also the getprpw*() interface
5348      * is available) one needs to link with -lsecurity -ldb -laud -lm.
5349      * One also needs to call set_auth_parameters() in main() before
5350      * doing anything else, whether one is using getespw*() or getprpw*().
5351      *
5352      * Note that accessing the shadow databases can be magnitudes
5353      * slower than accessing the standard databases.
5354      *
5355      * --jhi
5356      */
5357
5358 #   if defined(__CYGWIN__) && defined(USE_REENTRANT_API)
5359     /* Cygwin 1.5.3-1 has buggy getpwnam_r() and getpwuid_r():
5360      * the pw_comment is left uninitialized. */
5361     PL_reentrant_buffer->_pwent_struct.pw_comment = NULL;
5362 #   endif
5363
5364     switch (which) {
5365     case OP_GPWNAM:
5366       {
5367         char* name = POPpbytex;
5368         pwent  = getpwnam(name);
5369       }
5370       break;
5371     case OP_GPWUID:
5372       {
5373         Uid_t uid = POPi;
5374         pwent = getpwuid(uid);
5375       }
5376         break;
5377     case OP_GPWENT:
5378 #   ifdef HAS_GETPWENT
5379         pwent  = getpwent();
5380 #ifdef POSIX_BC   /* In some cases pw_passwd has invalid addresses */
5381         if (pwent) pwent = getpwnam(pwent->pw_name);
5382 #endif
5383 #   else
5384         DIE(aTHX_ PL_no_func, "getpwent");
5385 #   endif
5386         break;
5387     }
5388
5389     EXTEND(SP, 10);
5390     if (GIMME != G_ARRAY) {
5391         PUSHs(sv = sv_newmortal());
5392         if (pwent) {
5393             if (which == OP_GPWNAM)
5394 #   if Uid_t_sign <= 0
5395                 sv_setiv(sv, (IV)pwent->pw_uid);
5396 #   else
5397                 sv_setuv(sv, (UV)pwent->pw_uid);
5398 #   endif
5399             else
5400                 sv_setpv(sv, pwent->pw_name);
5401         }
5402         RETURN;
5403     }
5404
5405     if (pwent) {
5406         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
5407         sv_setpv(sv, pwent->pw_name);
5408
5409         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
5410         SvPOK_off(sv);
5411         /* If we have getspnam(), we try to dig up the shadow
5412          * password.  If we are underprivileged, the shadow
5413          * interface will set the errno to EACCES or similar,
5414          * and return a null pointer.  If this happens, we will
5415          * use the dummy password (usually "*" or "x") from the
5416          * standard password database.
5417          *
5418          * In theory we could skip the shadow call completely
5419          * if euid != 0 but in practice we cannot know which
5420          * security measures are guarding the shadow databases
5421          * on a random platform.
5422          *
5423          * Resist the urge to use additional shadow interfaces.
5424          * Divert the urge to writing an extension instead.
5425          *
5426          * --jhi */
5427         /* Some AIX setups falsely(?) detect some getspnam(), which
5428          * has a different API than the Solaris/IRIX one. */
5429 #   if defined(HAS_GETSPNAM) && !defined(_AIX)
5430         {
5431             struct spwd *spwent;
5432             int saverrno; /* Save and restore errno so that
5433                            * underprivileged attempts seem
5434                            * to have never made the unsccessful
5435                            * attempt to retrieve the shadow password. */
5436
5437             saverrno = errno;
5438             spwent = getspnam(pwent->pw_name);
5439             errno = saverrno;
5440             if (spwent && spwent->sp_pwdp)
5441                 sv_setpv(sv, spwent->sp_pwdp);
5442         }
5443 #   endif
5444 #   ifdef PWPASSWD
5445         if (!SvPOK(sv)) /* Use the standard password, then. */
5446             sv_setpv(sv, pwent->pw_passwd);
5447 #   endif
5448
5449 #   ifndef INCOMPLETE_TAINTS
5450         /* passwd is tainted because user himself can diddle with it.
5451          * admittedly not much and in a very limited way, but nevertheless. */
5452         SvTAINTED_on(sv);
5453 #   endif
5454
5455         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
5456 #   if Uid_t_sign <= 0
5457         sv_setiv(sv, (IV)pwent->pw_uid);
5458 #   else
5459         sv_setuv(sv, (UV)pwent->pw_uid);
5460 #   endif
5461
5462         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
5463 #   if Uid_t_sign <= 0
5464         sv_setiv(sv, (IV)pwent->pw_gid);
5465 #   else
5466         sv_setuv(sv, (UV)pwent->pw_gid);
5467 #   endif
5468         /* pw_change, pw_quota, and pw_age are mutually exclusive--
5469          * because of the poor interface of the Perl getpw*(),
5470          * not because there's some standard/convention saying so.
5471          * A better interface would have been to return a hash,
5472          * but we are accursed by our history, alas. --jhi.  */
5473         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
5474 #   ifdef PWCHANGE
5475         sv_setiv(sv, (IV)pwent->pw_change);
5476 #   else
5477 #       ifdef PWQUOTA
5478         sv_setiv(sv, (IV)pwent->pw_quota);
5479 #       else
5480 #           ifdef PWAGE
5481         sv_setpv(sv, pwent->pw_age);
5482 #           endif
5483 #       endif
5484 #   endif
5485
5486         /* pw_class and pw_comment are mutually exclusive--.
5487          * see the above note for pw_change, pw_quota, and pw_age. */
5488         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
5489 #   ifdef PWCLASS
5490         sv_setpv(sv, pwent->pw_class);
5491 #   else
5492 #       ifdef PWCOMMENT
5493         sv_setpv(sv, pwent->pw_comment);
5494 #       endif
5495 #   endif
5496
5497         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
5498 #   ifdef PWGECOS
5499         sv_setpv(sv, pwent->pw_gecos);
5500 #   endif
5501 #   ifndef INCOMPLETE_TAINTS
5502         /* pw_gecos is tainted because user himself can diddle with it. */
5503         SvTAINTED_on(sv);
5504 #   endif
5505
5506         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
5507         sv_setpv(sv, pwent->pw_dir);
5508
5509         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
5510         sv_setpv(sv, pwent->pw_shell);
5511 #   ifndef INCOMPLETE_TAINTS
5512         /* pw_shell is tainted because user himself can diddle with it. */
5513         SvTAINTED_on(sv);
5514 #   endif
5515
5516 #   ifdef PWEXPIRE
5517         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
5518         sv_setiv(sv, (IV)pwent->pw_expire);
5519 #   endif
5520     }
5521     RETURN;
5522 #else
5523     DIE(aTHX_ PL_no_func, "getpwent");
5524 #endif
5525 }
5526
5527 PP(pp_spwent)
5528 {
5529 #if defined(HAS_PASSWD) && defined(HAS_SETPWENT)
5530     dSP;
5531     setpwent();
5532     RETPUSHYES;
5533 #else
5534     DIE(aTHX_ PL_no_func, "setpwent");
5535 #endif
5536 }
5537
5538 PP(pp_epwent)
5539 {
5540 #if defined(HAS_PASSWD) && defined(HAS_ENDPWENT)
5541     dSP;
5542     endpwent();
5543     RETPUSHYES;
5544 #else
5545     DIE(aTHX_ PL_no_func, "endpwent");
5546 #endif
5547 }
5548
5549 PP(pp_ggrnam)
5550 {
5551 #ifdef HAS_GROUP
5552     return pp_ggrent();
5553 #else
5554     DIE(aTHX_ PL_no_func, "getgrnam");
5555 #endif
5556 }
5557
5558 PP(pp_ggrgid)
5559 {
5560 #ifdef HAS_GROUP
5561     return pp_ggrent();
5562 #else
5563     DIE(aTHX_ PL_no_func, "getgrgid");
5564 #endif
5565 }
5566
5567 PP(pp_ggrent)
5568 {
5569 #ifdef HAS_GROUP
5570     dSP;
5571     I32 which = PL_op->op_type;
5572     register char **elem;
5573     register SV *sv;
5574     struct group *grent;
5575
5576     if (which == OP_GGRNAM) {
5577         char* name = POPpbytex;
5578         grent = (struct group *)getgrnam(name);
5579     }
5580     else if (which == OP_GGRGID) {
5581         Gid_t gid = POPi;
5582         grent = (struct group *)getgrgid(gid);
5583     }
5584     else
5585 #ifdef HAS_GETGRENT
5586         grent = (struct group *)getgrent();
5587 #else
5588         DIE(aTHX_ PL_no_func, "getgrent");
5589 #endif
5590
5591     EXTEND(SP, 4);
5592     if (GIMME != G_ARRAY) {
5593         PUSHs(sv = sv_newmortal());
5594         if (grent) {
5595             if (which == OP_GGRNAM)
5596                 sv_setiv(sv, (IV)grent->gr_gid);
5597             else
5598                 sv_setpv(sv, grent->gr_name);
5599         }
5600         RETURN;
5601     }
5602
5603     if (grent) {
5604         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
5605         sv_setpv(sv, grent->gr_name);
5606
5607         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
5608 #ifdef GRPASSWD
5609         sv_setpv(sv, grent->gr_passwd);
5610 #endif
5611
5612         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
5613         sv_setiv(sv, (IV)grent->gr_gid);
5614
5615 #if !(defined(_CRAYMPP) && defined(USE_REENTRANT_API))
5616         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
5617         /* In UNICOS/mk (_CRAYMPP) the multithreading
5618          * versions (getgrnam_r, getgrgid_r)
5619          * seem to return an illegal pointer
5620          * as the group members list, gr_mem.
5621          * getgrent() doesn't even have a _r version
5622          * but the gr_mem is poisonous anyway.
5623          * So yes, you cannot get the list of group
5624          * members if building multithreaded in UNICOS/mk. */
5625         for (elem = grent->gr_mem; elem && *elem; elem++) {
5626             sv_catpv(sv, *elem);
5627             if (elem[1])
5628                 sv_catpvn(sv, " ", 1);
5629         }
5630 #endif
5631     }
5632
5633     RETURN;
5634 #else
5635     DIE(aTHX_ PL_no_func, "getgrent");
5636 #endif
5637 }
5638
5639 PP(pp_sgrent)
5640 {
5641 #if defined(HAS_GROUP) && defined(HAS_SETGRENT)
5642     dSP;
5643     setgrent();
5644     RETPUSHYES;
5645 #else
5646     DIE(aTHX_ PL_no_func, "setgrent");
5647 #endif
5648 }
5649
5650 PP(pp_egrent)
5651 {
5652 #if defined(HAS_GROUP) && defined(HAS_ENDGRENT)
5653     dSP;
5654     endgrent();
5655     RETPUSHYES;
5656 #else
5657     DIE(aTHX_ PL_no_func, "endgrent");
5658 #endif
5659 }
5660
5661 PP(pp_getlogin)
5662 {
5663 #ifdef HAS_GETLOGIN
5664     dSP; dTARGET;
5665     char *tmps;
5666     EXTEND(SP, 1);
5667     if (!(tmps = PerlProc_getlogin()))
5668         RETPUSHUNDEF;
5669     PUSHp(tmps, strlen(tmps));
5670     RETURN;
5671 #else
5672     DIE(aTHX_ PL_no_func, "getlogin");
5673 #endif
5674 }
5675
5676 /* Miscellaneous. */
5677
5678 PP(pp_syscall)
5679 {
5680 #ifdef HAS_SYSCALL
5681     dSP; dMARK; dORIGMARK; dTARGET;
5682     register I32 items = SP - MARK;
5683     unsigned long a[20];
5684     register I32 i = 0;
5685     I32 retval = -1;
5686
5687     if (PL_tainting) {
5688         while (++MARK <= SP) {
5689             if (SvTAINTED(*MARK)) {
5690                 TAINT;
5691                 break;
5692             }
5693         }
5694         MARK = ORIGMARK;
5695         TAINT_PROPER("syscall");
5696     }
5697
5698     /* This probably won't work on machines where sizeof(long) != sizeof(int)
5699      * or where sizeof(long) != sizeof(char*).  But such machines will
5700      * not likely have syscall implemented either, so who cares?
5701      */
5702     while (++MARK <= SP) {
5703         if (SvNIOK(*MARK) || !i)
5704             a[i++] = SvIV(*MARK);
5705         else if (*MARK == &PL_sv_undef)
5706             a[i++] = 0;
5707         else
5708             a[i++] = (unsigned long)SvPV_force_nolen(*MARK);
5709         if (i > 15)
5710             break;
5711     }
5712     switch (items) {
5713     default:
5714         DIE(aTHX_ "Too many args to syscall");
5715     case 0:
5716         DIE(aTHX_ "Too few args to syscall");
5717     case 1:
5718         retval = syscall(a[0]);
5719         break;
5720     case 2:
5721         retval = syscall(a[0],a[1]);
5722         break;
5723     case 3:
5724         retval = syscall(a[0],a[1],a[2]);
5725         break;
5726     case 4:
5727         retval = syscall(a[0],a[1],a[2],a[3]);
5728         break;
5729     case 5:
5730         retval = syscall(a[0],a[1],a[2],a[3],a[4]);
5731         break;
5732     case 6:
5733         retval = syscall(a[0],a[1],a[2],a[3],a[4],a[5]);
5734         break;
5735     case 7:
5736         retval = syscall(a[0],a[1],a[2],a[3],a[4],a[5],a[6]);
5737         break;
5738     case 8:
5739         retval = syscall(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7]);
5740         break;
5741 #ifdef atarist
5742     case 9:
5743         retval = syscall(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8]);
5744         break;
5745     case 10:
5746         retval = syscall(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9]);
5747         break;
5748     case 11:
5749         retval = syscall(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9],
5750           a[10]);
5751         break;
5752     case 12:
5753         retval = syscall(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9],
5754           a[10],a[11]);
5755         break;
5756     case 13:
5757         retval = syscall(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9],
5758           a[10],a[11],a[12]);
5759         break;
5760     case 14:
5761         retval = syscall(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9],
5762           a[10],a[11],a[12],a[13]);
5763         break;
5764 #endif /* atarist */
5765     }
5766     SP = ORIGMARK;
5767     PUSHi(retval);
5768     RETURN;
5769 #else
5770     DIE(aTHX_ PL_no_func, "syscall");
5771 #endif
5772 }
5773
5774 #ifdef FCNTL_EMULATE_FLOCK
5775
5776 /*  XXX Emulate flock() with fcntl().
5777     What's really needed is a good file locking module.
5778 */
5779
5780 static int
5781 fcntl_emulate_flock(int fd, int operation)
5782 {
5783     struct flock flock;
5784
5785     switch (operation & ~LOCK_NB) {
5786     case LOCK_SH:
5787         flock.l_type = F_RDLCK;
5788         break;
5789     case LOCK_EX:
5790         flock.l_type = F_WRLCK;
5791         break;
5792     case LOCK_UN:
5793         flock.l_type = F_UNLCK;
5794         break;
5795     default:
5796         errno = EINVAL;
5797         return -1;
5798     }
5799     flock.l_whence = SEEK_SET;
5800     flock.l_start = flock.l_len = (Off_t)0;
5801
5802     return fcntl(fd, (operation & LOCK_NB) ? F_SETLK : F_SETLKW, &flock);
5803 }
5804
5805 #endif /* FCNTL_EMULATE_FLOCK */
5806
5807 #ifdef LOCKF_EMULATE_FLOCK
5808
5809 /*  XXX Emulate flock() with lockf().  This is just to increase
5810     portability of scripts.  The calls are not completely
5811     interchangeable.  What's really needed is a good file
5812     locking module.
5813 */
5814
5815 /*  The lockf() constants might have been defined in <unistd.h>.
5816     Unfortunately, <unistd.h> causes troubles on some mixed
5817     (BSD/POSIX) systems, such as SunOS 4.1.3.
5818
5819    Further, the lockf() constants aren't POSIX, so they might not be
5820    visible if we're compiling with _POSIX_SOURCE defined.  Thus, we'll
5821    just stick in the SVID values and be done with it.  Sigh.
5822 */
5823
5824 # ifndef F_ULOCK
5825 #  define F_ULOCK       0       /* Unlock a previously locked region */
5826 # endif
5827 # ifndef F_LOCK
5828 #  define F_LOCK        1       /* Lock a region for exclusive use */
5829 # endif
5830 # ifndef F_TLOCK
5831 #  define F_TLOCK       2       /* Test and lock a region for exclusive use */
5832 # endif
5833 # ifndef F_TEST
5834 #  define F_TEST        3       /* Test a region for other processes locks */
5835 # endif
5836
5837 static int
5838 lockf_emulate_flock(int fd, int operation)
5839 {
5840     int i;
5841     int save_errno;
5842     Off_t pos;
5843
5844     /* flock locks entire file so for lockf we need to do the same      */
5845     save_errno = errno;
5846     pos = PerlLIO_lseek(fd, (Off_t)0, SEEK_CUR);    /* get pos to restore later */
5847     if (pos > 0)        /* is seekable and needs to be repositioned     */
5848         if (PerlLIO_lseek(fd, (Off_t)0, SEEK_SET) < 0)
5849             pos = -1;   /* seek failed, so don't seek back afterwards   */
5850     errno = save_errno;
5851
5852     switch (operation) {
5853
5854         /* LOCK_SH - get a shared lock */
5855         case LOCK_SH:
5856         /* LOCK_EX - get an exclusive lock */
5857         case LOCK_EX:
5858             i = lockf (fd, F_LOCK, 0);
5859             break;
5860
5861         /* LOCK_SH|LOCK_NB - get a non-blocking shared lock */
5862         case LOCK_SH|LOCK_NB:
5863         /* LOCK_EX|LOCK_NB - get a non-blocking exclusive lock */
5864         case LOCK_EX|LOCK_NB:
5865             i = lockf (fd, F_TLOCK, 0);
5866             if (i == -1)
5867                 if ((errno == EAGAIN) || (errno == EACCES))
5868                     errno = EWOULDBLOCK;
5869             break;
5870
5871         /* LOCK_UN - unlock (non-blocking is a no-op) */
5872         case LOCK_UN:
5873         case LOCK_UN|LOCK_NB:
5874             i = lockf (fd, F_ULOCK, 0);
5875             break;
5876
5877         /* Default - can't decipher operation */
5878         default:
5879             i = -1;
5880             errno = EINVAL;
5881             break;
5882     }
5883
5884     if (pos > 0)      /* need to restore position of the handle */
5885         PerlLIO_lseek(fd, pos, SEEK_SET);       /* ignore error here    */
5886
5887     return (i);
5888 }
5889
5890 #endif /* LOCKF_EMULATE_FLOCK */
5891
5892 /*
5893  * Local variables:
5894  * c-indentation-style: bsd
5895  * c-basic-offset: 4
5896  * indent-tabs-mode: t
5897  * End:
5898  *
5899  * ex: set ts=8 sts=4 sw=4 noet:
5900  */