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