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