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