This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
d16cd7e5f18dad681c7446f671e9fdeb8cb99ad2
[perl5.git] / pp_sys.c
1 /*    pp_sys.c
2  *
3  *    Copyright (c) 1991-1997, 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 #include "perl.h"
19
20 /* XXX If this causes problems, set i_unistd=undef in the hint file.  */
21 #ifdef I_UNISTD
22 # include <unistd.h>
23 #endif
24
25 #ifdef HAS_SYSCALL   
26 #ifdef __cplusplus              
27 extern "C" int syscall(unsigned long,...);
28 #endif
29 #endif
30
31 #ifdef I_SYS_WAIT
32 # include <sys/wait.h>
33 #endif
34
35 #ifdef I_SYS_RESOURCE
36 # include <sys/resource.h>
37 #endif
38
39 #if defined(HAS_SOCKET) && !defined(VMS) /* VMS handles sockets via vmsish.h */
40 # include <sys/socket.h>
41 # ifdef I_NETDB
42 #  include <netdb.h>
43 # endif
44 # ifndef ENOTSOCK
45 #  ifdef I_NET_ERRNO
46 #   include <net/errno.h>
47 #  endif
48 # endif
49 #endif
50
51 #ifdef HAS_SELECT
52 #ifdef I_SYS_SELECT
53 #include <sys/select.h>
54 #endif
55 #endif
56
57 /* XXX Configure test needed.
58    h_errno might not be a simple 'int', especially for multi-threaded
59    applications.  HOST_NOT_FOUND is typically defined in <netdb.h>.
60 */
61 #if defined(HOST_NOT_FOUND) && !defined(h_errno)
62 extern int h_errno;
63 #endif
64
65 #ifdef HAS_PASSWD
66 # ifdef I_PWD
67 #  include <pwd.h>
68 # else
69     struct passwd *getpwnam _((char *));
70     struct passwd *getpwuid _((Uid_t));
71 # endif
72 # ifdef HAS_GETPWENT
73   struct passwd *getpwent _((void));
74 # endif
75 #endif
76
77 #ifdef HAS_GROUP
78 # ifdef I_GRP
79 #  include <grp.h>
80 # else
81     struct group *getgrnam _((char *));
82     struct group *getgrgid _((Gid_t));
83 # endif
84 # ifdef HAS_GETGRENT
85     struct group *getgrent _((void));
86 # endif
87 #endif
88
89 #ifdef I_UTIME
90 #  if defined(_MSC_VER) || defined(__MINGW32__)
91 #    include <sys/utime.h>
92 #  else
93 #    include <utime.h>
94 #  endif
95 #endif
96 #ifdef I_FCNTL
97 #include <fcntl.h>
98 #endif
99 #ifdef I_SYS_FILE
100 #include <sys/file.h>
101 #endif
102
103 /* Put this after #includes because fork and vfork prototypes may conflict. */
104 #ifndef HAS_VFORK
105 #   define vfork fork
106 #endif
107
108 /* Put this after #includes because <unistd.h> defines _XOPEN_*. */
109 #ifndef Sock_size_t
110 #  if _XOPEN_VERSION >= 5 || defined(_XOPEN_SOURCE_EXTENDED) || defined(__GLIBC__)
111 #    define Sock_size_t Size_t
112 #  else
113 #    define Sock_size_t int
114 #  endif
115 #endif
116
117 #if !defined(HAS_MKDIR) || !defined(HAS_RMDIR)
118 static int dooneliner _((char *cmd, char *filename));
119 #endif
120
121 #ifdef HAS_CHSIZE
122 # ifdef my_chsize  /* Probably #defined to Perl_my_chsize in embed.h */
123 #   undef my_chsize
124 # endif
125 # define my_chsize PerlLIO_chsize
126 #endif
127
128 #ifdef HAS_FLOCK
129 #  define FLOCK flock
130 #else /* no flock() */
131
132    /* fcntl.h might not have been included, even if it exists, because
133       the current Configure only sets I_FCNTL if it's needed to pick up
134       the *_OK constants.  Make sure it has been included before testing
135       the fcntl() locking constants. */
136 #  if defined(HAS_FCNTL) && !defined(I_FCNTL)
137 #    include <fcntl.h>
138 #  endif
139
140 #  if defined(HAS_FCNTL) && defined(F_SETLK) && defined (F_SETLKW)
141 #    define FLOCK fcntl_emulate_flock
142 #    define FCNTL_EMULATE_FLOCK
143 #  else /* no flock() or fcntl(F_SETLK,...) */
144 #    ifdef HAS_LOCKF
145 #      define FLOCK lockf_emulate_flock
146 #      define LOCKF_EMULATE_FLOCK
147 #    endif /* lockf */
148 #  endif /* no flock() or fcntl(F_SETLK,...) */
149
150 #  ifdef FLOCK
151      static int FLOCK _((int, int));
152
153     /*
154      * These are the flock() constants.  Since this sytems doesn't have
155      * flock(), the values of the constants are probably not available.
156      */
157 #    ifndef LOCK_SH
158 #      define LOCK_SH 1
159 #    endif
160 #    ifndef LOCK_EX
161 #      define LOCK_EX 2
162 #    endif
163 #    ifndef LOCK_NB
164 #      define LOCK_NB 4
165 #    endif
166 #    ifndef LOCK_UN
167 #      define LOCK_UN 8
168 #    endif
169 #  endif /* emulating flock() */
170
171 #endif /* no flock() */
172
173 #ifndef MAXPATHLEN
174 #  ifdef PATH_MAX
175 #    define MAXPATHLEN PATH_MAX
176 #  else
177 #    define MAXPATHLEN 1024
178 #  endif
179 #endif
180
181 #define ZBTLEN 10
182 static char zero_but_true[ZBTLEN + 1] = "0 but true";
183
184 /* Pushy I/O. */
185
186 PP(pp_backtick)
187 {
188     djSP; dTARGET;
189     PerlIO *fp;
190     char *tmps = POPp;
191     I32 gimme = GIMME_V;
192
193     TAINT_PROPER("``");
194     fp = PerlProc_popen(tmps, "r");
195     if (fp) {
196         if (gimme == G_VOID) {
197             char tmpbuf[256];
198             while (PerlIO_read(fp, tmpbuf, sizeof tmpbuf) > 0)
199                 /*SUPPRESS 530*/
200                 ;
201         }
202         else if (gimme == G_SCALAR) {
203             sv_setpv(TARG, ""); /* note that this preserves previous buffer */
204             while (sv_gets(TARG, fp, SvCUR(TARG)) != Nullch)
205                 /*SUPPRESS 530*/
206                 ;
207             XPUSHs(TARG);
208             SvTAINTED_on(TARG);
209         }
210         else {
211             SV *sv;
212
213             for (;;) {
214                 sv = NEWSV(56, 79);
215                 if (sv_gets(sv, fp, 0) == Nullch) {
216                     SvREFCNT_dec(sv);
217                     break;
218                 }
219                 XPUSHs(sv_2mortal(sv));
220                 if (SvLEN(sv) - SvCUR(sv) > 20) {
221                     SvLEN_set(sv, SvCUR(sv)+1);
222                     Renew(SvPVX(sv), SvLEN(sv), char);
223                 }
224                 SvTAINTED_on(sv);
225             }
226         }
227         STATUS_NATIVE_SET(PerlProc_pclose(fp));
228         TAINT;          /* "I believe that this is not gratuitous!" */
229     }
230     else {
231         STATUS_NATIVE_SET(-1);
232         if (gimme == G_SCALAR)
233             RETPUSHUNDEF;
234     }
235
236     RETURN;
237 }
238
239 PP(pp_glob)
240 {
241     OP *result;
242     ENTER;
243
244 #ifndef VMS
245     if (PL_tainting) {
246         /*
247          * The external globbing program may use things we can't control,
248          * so for security reasons we must assume the worst.
249          */
250         TAINT;
251         taint_proper(no_security, "glob");
252     }
253 #endif /* !VMS */
254
255     SAVESPTR(PL_last_in_gv);    /* We don't want this to be permanent. */
256     PL_last_in_gv = (GV*)*PL_stack_sp--;
257
258     SAVESPTR(PL_rs);            /* This is not permanent, either. */
259     PL_rs = sv_2mortal(newSVpv("", 1));
260 #ifndef DOSISH
261 #ifndef CSH
262     *SvPVX(PL_rs) = '\n';
263 #endif  /* !CSH */
264 #endif  /* !DOSISH */
265
266     result = do_readline();
267     LEAVE;
268     return result;
269 }
270
271 #if 0           /* XXX never used! */
272 PP(pp_indread)
273 {
274     PL_last_in_gv = gv_fetchpv(SvPVx(GvSV((GV*)(*PL_stack_sp--)), PL_na), TRUE,SVt_PVIO);
275     return do_readline();
276 }
277 #endif
278
279 PP(pp_rcatline)
280 {
281     PL_last_in_gv = cGVOP->op_gv;
282     return do_readline();
283 }
284
285 PP(pp_warn)
286 {
287     djSP; dMARK;
288     char *tmps;
289     if (SP - MARK != 1) {
290         dTARGET;
291         do_join(TARG, &PL_sv_no, MARK, SP);
292         tmps = SvPV(TARG, PL_na);
293         SP = MARK + 1;
294     }
295     else {
296         tmps = SvPV(TOPs, PL_na);
297     }
298     if (!tmps || !*tmps) {
299         SV *error = ERRSV;
300         (void)SvUPGRADE(error, SVt_PV);
301         if (SvPOK(error) && SvCUR(error))
302             sv_catpv(error, "\t...caught");
303         tmps = SvPV(error, PL_na);
304     }
305     if (!tmps || !*tmps)
306         tmps = "Warning: something's wrong";
307     warn("%s", tmps);
308     RETSETYES;
309 }
310
311 PP(pp_die)
312 {
313     djSP; dMARK;
314     char *tmps;
315     SV *tmpsv = Nullsv;
316     char *pat = "%s";
317     if (SP - MARK != 1) {
318         dTARGET;
319         do_join(TARG, &PL_sv_no, MARK, SP);
320         tmps = SvPV(TARG, PL_na);
321         SP = MARK + 1;
322     }
323     else {
324         tmpsv = TOPs;
325         tmps = SvROK(tmpsv) ? Nullch : SvPV(tmpsv, PL_na);
326     }
327     if (!tmps || !*tmps) {
328         SV *error = ERRSV;
329         (void)SvUPGRADE(error, SVt_PV);
330         if(tmpsv ? SvROK(tmpsv) : SvROK(error)) {
331             if(tmpsv)
332                 SvSetSV(error,tmpsv);
333             else if(sv_isobject(error)) {
334                 HV *stash = SvSTASH(SvRV(error));
335                 GV *gv = gv_fetchmethod(stash, "PROPAGATE");
336                 if (gv) {
337                     SV *file = sv_2mortal(newSVsv(GvSV(PL_curcop->cop_filegv)));
338                     SV *line = sv_2mortal(newSViv(PL_curcop->cop_line));
339                     EXTEND(SP, 3);
340                     PUSHMARK(SP);
341                     PUSHs(error);
342                     PUSHs(file);
343                     PUSHs(line);
344                     PUTBACK;
345                     perl_call_sv((SV*)GvCV(gv),
346                                  G_SCALAR|G_EVAL|G_KEEPERR);
347                     sv_setsv(error,*PL_stack_sp--);
348                 }
349             }
350             pat = Nullch;
351         }
352         else {
353             if (SvPOK(error) && SvCUR(error))
354                 sv_catpv(error, "\t...propagated");
355             tmps = SvPV(error, PL_na);
356         }
357     }
358     if (!tmps || !*tmps)
359         tmps = "Died";
360     DIE(pat, tmps);
361 }
362
363 /* I/O. */
364
365 PP(pp_open)
366 {
367     djSP; dTARGET;
368     GV *gv;
369     SV *sv;
370     char *tmps;
371     STRLEN len;
372
373     if (MAXARG > 1)
374         sv = POPs;
375     if (!isGV(TOPs))
376         DIE(no_usym, "filehandle");
377     if (MAXARG <= 1)
378         sv = GvSV(TOPs);
379     gv = (GV*)POPs;
380     if (!isGV(gv))
381         DIE(no_usym, "filehandle");
382     if (GvIOp(gv))
383         IoFLAGS(GvIOp(gv)) &= ~IOf_UNTAINT;
384     tmps = SvPV(sv, len);
385     if (do_open(gv, tmps, len, FALSE, 0, 0, Nullfp))
386         PUSHi( (I32)PL_forkprocess );
387     else if (PL_forkprocess == 0)               /* we are a new child */
388         PUSHi(0);
389     else
390         RETPUSHUNDEF;
391     RETURN;
392 }
393
394 PP(pp_close)
395 {
396     djSP;
397     GV *gv;
398     MAGIC *mg;
399
400     if (MAXARG == 0)
401         gv = PL_defoutgv;
402     else
403         gv = (GV*)POPs;
404
405     if (SvRMAGICAL(gv) && (mg = mg_find((SV*)gv, 'q'))) {
406         PUSHMARK(SP);
407         XPUSHs(mg->mg_obj);
408         PUTBACK;
409         ENTER;
410         perl_call_method("CLOSE", G_SCALAR);
411         LEAVE;
412         SPAGAIN;
413         RETURN;
414     }
415     EXTEND(SP, 1);
416     PUSHs(boolSV(do_close(gv, TRUE)));
417     RETURN;
418 }
419
420 PP(pp_pipe_op)
421 {
422     djSP;
423 #ifdef HAS_PIPE
424     GV *rgv;
425     GV *wgv;
426     register IO *rstio;
427     register IO *wstio;
428     int fd[2];
429
430     wgv = (GV*)POPs;
431     rgv = (GV*)POPs;
432
433     if (!rgv || !wgv)
434         goto badexit;
435
436     if (SvTYPE(rgv) != SVt_PVGV || SvTYPE(wgv) != SVt_PVGV)
437         DIE(no_usym, "filehandle");
438     rstio = GvIOn(rgv);
439     wstio = GvIOn(wgv);
440
441     if (IoIFP(rstio))
442         do_close(rgv, FALSE);
443     if (IoIFP(wstio))
444         do_close(wgv, FALSE);
445
446     if (PerlProc_pipe(fd) < 0)
447         goto badexit;
448
449     IoIFP(rstio) = PerlIO_fdopen(fd[0], "r");
450     IoOFP(wstio) = PerlIO_fdopen(fd[1], "w");
451     IoIFP(wstio) = IoOFP(wstio);
452     IoTYPE(rstio) = '<';
453     IoTYPE(wstio) = '>';
454
455     if (!IoIFP(rstio) || !IoOFP(wstio)) {
456         if (IoIFP(rstio)) PerlIO_close(IoIFP(rstio));
457         else PerlLIO_close(fd[0]);
458         if (IoOFP(wstio)) PerlIO_close(IoOFP(wstio));
459         else PerlLIO_close(fd[1]);
460         goto badexit;
461     }
462
463     RETPUSHYES;
464
465 badexit:
466     RETPUSHUNDEF;
467 #else
468     DIE(no_func, "pipe");
469 #endif
470 }
471
472 PP(pp_fileno)
473 {
474     djSP; dTARGET;
475     GV *gv;
476     IO *io;
477     PerlIO *fp;
478     if (MAXARG < 1)
479         RETPUSHUNDEF;
480     gv = (GV*)POPs;
481     if (!gv || !(io = GvIO(gv)) || !(fp = IoIFP(io)))
482         RETPUSHUNDEF;
483     PUSHi(PerlIO_fileno(fp));
484     RETURN;
485 }
486
487 PP(pp_umask)
488 {
489     djSP; dTARGET;
490     int anum;
491
492 #ifdef HAS_UMASK
493     if (MAXARG < 1) {
494         anum = PerlLIO_umask(0);
495         (void)PerlLIO_umask(anum);
496     }
497     else
498         anum = PerlLIO_umask(POPi);
499     TAINT_PROPER("umask");
500     XPUSHi(anum);
501 #else
502     /* Only DIE if trying to restrict permissions on `user' (self).
503      * Otherwise it's harmless and more useful to just return undef
504      * since 'group' and 'other' concepts probably don't exist here. */
505     if (MAXARG >= 1 && (POPi & 0700))
506         DIE("umask not implemented");
507     XPUSHs(&PL_sv_undef);
508 #endif
509     RETURN;
510 }
511
512 PP(pp_binmode)
513 {
514     djSP;
515     GV *gv;
516     IO *io;
517     PerlIO *fp;
518
519     if (MAXARG < 1)
520         RETPUSHUNDEF;
521
522     gv = (GV*)POPs;
523
524     EXTEND(SP, 1);
525     if (!(io = GvIO(gv)) || !(fp = IoIFP(io)))
526         RETPUSHUNDEF;
527
528     if (do_binmode(fp,IoTYPE(io),TRUE)) 
529         RETPUSHYES;
530     else
531         RETPUSHUNDEF;
532 }
533
534
535 PP(pp_tie)
536 {
537     djSP;
538     dMARK;
539     SV *varsv;
540     HV* stash;
541     GV *gv;
542     SV *sv;
543     I32 markoff = MARK - PL_stack_base;
544     char *methname;
545     int how = 'P';
546     U32 items;
547
548     varsv = *++MARK;
549     switch(SvTYPE(varsv)) {
550         case SVt_PVHV:
551             methname = "TIEHASH";
552             break;
553         case SVt_PVAV:
554             methname = "TIEARRAY";
555             break;
556         case SVt_PVGV:
557             methname = "TIEHANDLE";
558             how = 'q';
559             break;
560         default:
561             methname = "TIESCALAR";
562             how = 'q';
563             break;
564     }
565     items = SP - MARK++;
566     if (sv_isobject(*MARK)) {
567         ENTER;
568         PUSHSTACKi(PERLSI_MAGIC);
569         PUSHMARK(SP);
570         EXTEND(SP,items);
571         while (items--)
572             PUSHs(*MARK++);
573         PUTBACK;
574         perl_call_method(methname, G_SCALAR);
575     } 
576     else {
577         /* Not clear why we don't call perl_call_method here too.
578          * perhaps to get different error message ?
579          */
580         stash = gv_stashsv(*MARK, FALSE);
581         if (!stash || !(gv = gv_fetchmethod(stash, methname))) {
582             DIE("Can't locate object method \"%s\" via package \"%s\"",
583                  methname, SvPV(*MARK,PL_na));                   
584         }
585         ENTER;
586         PUSHSTACKi(PERLSI_MAGIC);
587         PUSHMARK(SP);
588         EXTEND(SP,items);
589         while (items--)
590             PUSHs(*MARK++);
591         PUTBACK;
592         perl_call_sv((SV*)GvCV(gv), G_SCALAR);
593     }
594     SPAGAIN;
595
596     sv = TOPs;
597     POPSTACK;
598     if (sv_isobject(sv)) {
599         sv_unmagic(varsv, how);            
600         sv_magic(varsv, sv, how, Nullch, 0);
601     }
602     LEAVE;
603     SP = PL_stack_base + markoff;
604     PUSHs(sv);
605     RETURN;
606 }
607
608 PP(pp_untie)
609 {
610     djSP;
611     SV * sv ;
612
613     sv = POPs;
614
615     if (PL_dowarn) {
616         MAGIC * mg ;
617         if (SvMAGICAL(sv)) {
618             if (SvTYPE(sv) == SVt_PVHV || SvTYPE(sv) == SVt_PVAV)
619                 mg = mg_find(sv, 'P') ;
620             else
621                 mg = mg_find(sv, 'q') ;
622     
623             if (mg && SvREFCNT(SvRV(mg->mg_obj)) > 1)  
624                 warn("untie attempted while %lu inner references still exist",
625                         (unsigned long)SvREFCNT(SvRV(mg->mg_obj)) - 1 ) ;
626         }
627     }
628  
629     if (SvTYPE(sv) == SVt_PVHV || SvTYPE(sv) == SVt_PVAV)
630         sv_unmagic(sv, 'P');
631     else
632         sv_unmagic(sv, 'q');
633     RETPUSHYES;
634 }
635
636 PP(pp_tied)
637 {
638     djSP;
639     SV * sv ;
640     MAGIC * mg ;
641
642     sv = POPs;
643     if (SvMAGICAL(sv)) {
644         if (SvTYPE(sv) == SVt_PVHV || SvTYPE(sv) == SVt_PVAV)
645             mg = mg_find(sv, 'P') ;
646         else
647             mg = mg_find(sv, 'q') ;
648
649         if (mg)  {
650             PUSHs(sv_2mortal(newSVsv(mg->mg_obj))) ; 
651             RETURN ;
652         }
653     }
654     RETPUSHUNDEF;
655 }
656
657 PP(pp_dbmopen)
658 {
659     djSP;
660     HV *hv;
661     dPOPPOPssrl;
662     HV* stash;
663     GV *gv;
664     SV *sv;
665
666     hv = (HV*)POPs;
667
668     sv = sv_mortalcopy(&PL_sv_no);
669     sv_setpv(sv, "AnyDBM_File");
670     stash = gv_stashsv(sv, FALSE);
671     if (!stash || !(gv = gv_fetchmethod(stash, "TIEHASH"))) {
672         PUTBACK;
673         perl_require_pv("AnyDBM_File.pm");
674         SPAGAIN;
675         if (!(gv = gv_fetchmethod(stash, "TIEHASH")))
676             DIE("No dbm on this machine");
677     }
678
679     ENTER;
680     PUSHMARK(SP);
681
682     EXTEND(SP, 5);
683     PUSHs(sv);
684     PUSHs(left);
685     if (SvIV(right))
686         PUSHs(sv_2mortal(newSViv(O_RDWR|O_CREAT)));
687     else
688         PUSHs(sv_2mortal(newSViv(O_RDWR)));
689     PUSHs(right);
690     PUTBACK;
691     perl_call_sv((SV*)GvCV(gv), G_SCALAR);
692     SPAGAIN;
693
694     if (!sv_isobject(TOPs)) {
695         SP--;
696         PUSHMARK(SP);
697         PUSHs(sv);
698         PUSHs(left);
699         PUSHs(sv_2mortal(newSViv(O_RDONLY)));
700         PUSHs(right);
701         PUTBACK;
702         perl_call_sv((SV*)GvCV(gv), G_SCALAR);
703         SPAGAIN;
704     }
705
706     if (sv_isobject(TOPs)) {
707         sv_unmagic((SV *) hv, 'P');            
708         sv_magic((SV*)hv, TOPs, 'P', Nullch, 0);
709     }
710     LEAVE;
711     RETURN;
712 }
713
714 PP(pp_dbmclose)
715 {
716     return pp_untie(ARGS);
717 }
718
719 PP(pp_sselect)
720 {
721     djSP; dTARGET;
722 #ifdef HAS_SELECT
723     register I32 i;
724     register I32 j;
725     register char *s;
726     register SV *sv;
727     double value;
728     I32 maxlen = 0;
729     I32 nfound;
730     struct timeval timebuf;
731     struct timeval *tbuf = &timebuf;
732     I32 growsize;
733     char *fd_sets[4];
734 #if BYTEORDER != 0x1234 && BYTEORDER != 0x12345678
735         I32 masksize;
736         I32 offset;
737         I32 k;
738
739 #   if BYTEORDER & 0xf0000
740 #       define ORDERBYTE (0x88888888 - BYTEORDER)
741 #   else
742 #       define ORDERBYTE (0x4444 - BYTEORDER)
743 #   endif
744
745 #endif
746
747     SP -= 4;
748     for (i = 1; i <= 3; i++) {
749         if (!SvPOK(SP[i]))
750             continue;
751         j = SvCUR(SP[i]);
752         if (maxlen < j)
753             maxlen = j;
754     }
755
756 #if BYTEORDER == 0x1234 || BYTEORDER == 0x12345678
757 /* XXX Configure test needed. */
758 #if defined(__linux__) || defined(OS2) || defined(NeXT) || defined(__osf__)
759     growsize = sizeof(fd_set);
760 #else
761     growsize = maxlen;          /* little endians can use vecs directly */
762 #endif
763 #else
764 #ifdef NFDBITS
765
766 #ifndef NBBY
767 #define NBBY 8
768 #endif
769
770     masksize = NFDBITS / NBBY;
771 #else
772     masksize = sizeof(long);    /* documented int, everyone seems to use long */
773 #endif
774     growsize = maxlen + (masksize - (maxlen % masksize));
775     Zero(&fd_sets[0], 4, char*);
776 #endif
777
778     sv = SP[4];
779     if (SvOK(sv)) {
780         value = SvNV(sv);
781         if (value < 0.0)
782             value = 0.0;
783         timebuf.tv_sec = (long)value;
784         value -= (double)timebuf.tv_sec;
785         timebuf.tv_usec = (long)(value * 1000000.0);
786     }
787     else
788         tbuf = Null(struct timeval*);
789
790     for (i = 1; i <= 3; i++) {
791         sv = SP[i];
792         if (!SvOK(sv)) {
793             fd_sets[i] = 0;
794             continue;
795         }
796         else if (!SvPOK(sv))
797             SvPV_force(sv,PL_na);       /* force string conversion */
798         j = SvLEN(sv);
799         if (j < growsize) {
800             Sv_Grow(sv, growsize);
801         }
802         j = SvCUR(sv);
803         s = SvPVX(sv) + j;
804         while (++j <= growsize) {
805             *s++ = '\0';
806         }
807
808 #if BYTEORDER != 0x1234 && BYTEORDER != 0x12345678
809         s = SvPVX(sv);
810         New(403, fd_sets[i], growsize, char);
811         for (offset = 0; offset < growsize; offset += masksize) {
812             for (j = 0, k=ORDERBYTE; j < masksize; j++, (k >>= 4))
813                 fd_sets[i][j+offset] = s[(k % masksize) + offset];
814         }
815 #else
816         fd_sets[i] = SvPVX(sv);
817 #endif
818     }
819
820     nfound = PerlSock_select(
821         maxlen * 8,
822         (Select_fd_set_t) fd_sets[1],
823         (Select_fd_set_t) fd_sets[2],
824         (Select_fd_set_t) fd_sets[3],
825         tbuf);
826     for (i = 1; i <= 3; i++) {
827         if (fd_sets[i]) {
828             sv = SP[i];
829 #if BYTEORDER != 0x1234 && BYTEORDER != 0x12345678
830             s = SvPVX(sv);
831             for (offset = 0; offset < growsize; offset += masksize) {
832                 for (j = 0, k=ORDERBYTE; j < masksize; j++, (k >>= 4))
833                     s[(k % masksize) + offset] = fd_sets[i][j+offset];
834             }
835             Safefree(fd_sets[i]);
836 #endif
837             SvSETMAGIC(sv);
838         }
839     }
840
841     PUSHi(nfound);
842     if (GIMME == G_ARRAY && tbuf) {
843         value = (double)(timebuf.tv_sec) +
844                 (double)(timebuf.tv_usec) / 1000000.0;
845         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
846         sv_setnv(sv, value);
847     }
848     RETURN;
849 #else
850     DIE("select not implemented");
851 #endif
852 }
853
854 void
855 setdefout(GV *gv)
856 {
857     dTHR;
858     if (gv)
859         (void)SvREFCNT_inc(gv);
860     if (PL_defoutgv)
861         SvREFCNT_dec(PL_defoutgv);
862     PL_defoutgv = gv;
863 }
864
865 PP(pp_select)
866 {
867     djSP; dTARGET;
868     GV *newdefout, *egv;
869     HV *hv;
870
871     newdefout = (PL_op->op_private > 0) ? ((GV *) POPs) : (GV *) NULL;
872
873     egv = GvEGV(PL_defoutgv);
874     if (!egv)
875         egv = PL_defoutgv;
876     hv = GvSTASH(egv);
877     if (! hv)
878         XPUSHs(&PL_sv_undef);
879     else {
880         GV **gvp = (GV**)hv_fetch(hv, GvNAME(egv), GvNAMELEN(egv), FALSE);
881         if (gvp && *gvp == egv) {
882             gv_efullname3(TARG, PL_defoutgv, Nullch);
883             XPUSHTARG;
884         }
885         else {
886             XPUSHs(sv_2mortal(newRV((SV*)egv)));
887         }
888     }
889
890     if (newdefout) {
891         if (!GvIO(newdefout))
892             gv_IOadd(newdefout);
893         setdefout(newdefout);
894     }
895
896     RETURN;
897 }
898
899 PP(pp_getc)
900 {
901     djSP; dTARGET;
902     GV *gv;
903     MAGIC *mg;
904
905     if (MAXARG <= 0)
906         gv = PL_stdingv;
907     else
908         gv = (GV*)POPs;
909     if (!gv)
910         gv = PL_argvgv;
911
912     if (SvRMAGICAL(gv) && (mg = mg_find((SV*)gv, 'q'))) {
913         I32 gimme = GIMME_V;
914         PUSHMARK(SP);
915         XPUSHs(mg->mg_obj);
916         PUTBACK;
917         ENTER;
918         perl_call_method("GETC", gimme);
919         LEAVE;
920         SPAGAIN;
921         if (gimme == G_SCALAR)
922             SvSetMagicSV_nosteal(TARG, TOPs);
923         RETURN;
924     }
925     if (!gv || do_eof(gv)) /* make sure we have fp with something */
926         RETPUSHUNDEF;
927     TAINT;
928     sv_setpv(TARG, " ");
929     *SvPVX(TARG) = PerlIO_getc(IoIFP(GvIOp(gv))); /* should never be EOF */
930     PUSHTARG;
931     RETURN;
932 }
933
934 PP(pp_read)
935 {
936     return pp_sysread(ARGS);
937 }
938
939 STATIC OP *
940 doform(CV *cv, GV *gv, OP *retop)
941 {
942     dTHR;
943     register PERL_CONTEXT *cx;
944     I32 gimme = GIMME_V;
945     AV* padlist = CvPADLIST(cv);
946     SV** svp = AvARRAY(padlist);
947
948     ENTER;
949     SAVETMPS;
950
951     push_return(retop);
952     PUSHBLOCK(cx, CXt_SUB, PL_stack_sp);
953     PUSHFORMAT(cx);
954     SAVESPTR(PL_curpad);
955     PL_curpad = AvARRAY((AV*)svp[1]);
956
957     setdefout(gv);          /* locally select filehandle so $% et al work */
958     return CvSTART(cv);
959 }
960
961 PP(pp_enterwrite)
962 {
963     djSP;
964     register GV *gv;
965     register IO *io;
966     GV *fgv;
967     CV *cv;
968
969     if (MAXARG == 0)
970         gv = PL_defoutgv;
971     else {
972         gv = (GV*)POPs;
973         if (!gv)
974             gv = PL_defoutgv;
975     }
976     EXTEND(SP, 1);
977     io = GvIO(gv);
978     if (!io) {
979         RETPUSHNO;
980     }
981     if (IoFMT_GV(io))
982         fgv = IoFMT_GV(io);
983     else
984         fgv = gv;
985
986     cv = GvFORM(fgv);
987     if (!cv) {
988         if (fgv) {
989             SV *tmpsv = sv_newmortal();
990             gv_efullname3(tmpsv, fgv, Nullch);
991             DIE("Undefined format \"%s\" called",SvPVX(tmpsv));
992         }
993         DIE("Not a format reference");
994     }
995     if (CvCLONE(cv))
996         cv = (CV*)sv_2mortal((SV*)cv_clone(cv));
997
998     IoFLAGS(io) &= ~IOf_DIDTOP;
999     return doform(cv,gv,PL_op->op_next);
1000 }
1001
1002 PP(pp_leavewrite)
1003 {
1004     djSP;
1005     GV *gv = cxstack[cxstack_ix].blk_sub.gv;
1006     register IO *io = GvIOp(gv);
1007     PerlIO *ofp = IoOFP(io);
1008     PerlIO *fp;
1009     SV **newsp;
1010     I32 gimme;
1011     register PERL_CONTEXT *cx;
1012
1013     DEBUG_f(PerlIO_printf(Perl_debug_log, "left=%ld, todo=%ld\n",
1014           (long)IoLINES_LEFT(io), (long)FmLINES(PL_formtarget)));
1015     if (IoLINES_LEFT(io) < FmLINES(PL_formtarget) &&
1016         PL_formtarget != PL_toptarget)
1017     {
1018         GV *fgv;
1019         CV *cv;
1020         if (!IoTOP_GV(io)) {
1021             GV *topgv;
1022             SV *topname;
1023
1024             if (!IoTOP_NAME(io)) {
1025                 if (!IoFMT_NAME(io))
1026                     IoFMT_NAME(io) = savepv(GvNAME(gv));
1027                 topname = sv_2mortal(newSVpvf("%s_TOP", IoFMT_NAME(io)));
1028                 topgv = gv_fetchpv(SvPVX(topname), FALSE, SVt_PVFM);
1029                 if ((topgv && GvFORM(topgv)) ||
1030                   !gv_fetchpv("top",FALSE,SVt_PVFM))
1031                     IoTOP_NAME(io) = savepv(SvPVX(topname));
1032                 else
1033                     IoTOP_NAME(io) = savepv("top");
1034             }
1035             topgv = gv_fetchpv(IoTOP_NAME(io),FALSE, SVt_PVFM);
1036             if (!topgv || !GvFORM(topgv)) {
1037                 IoLINES_LEFT(io) = 100000000;
1038                 goto forget_top;
1039             }
1040             IoTOP_GV(io) = topgv;
1041         }
1042         if (IoFLAGS(io) & IOf_DIDTOP) { /* Oh dear.  It still doesn't fit. */
1043             I32 lines = IoLINES_LEFT(io);
1044             char *s = SvPVX(PL_formtarget);
1045             if (lines <= 0)             /* Yow, header didn't even fit!!! */
1046                 goto forget_top;
1047             while (lines-- > 0) {
1048                 s = strchr(s, '\n');
1049                 if (!s)
1050                     break;
1051                 s++;
1052             }
1053             if (s) {
1054                 PerlIO_write(ofp, SvPVX(PL_formtarget), s - SvPVX(PL_formtarget));
1055                 sv_chop(PL_formtarget, s);
1056                 FmLINES(PL_formtarget) -= IoLINES_LEFT(io);
1057             }
1058         }
1059         if (IoLINES_LEFT(io) >= 0 && IoPAGE(io) > 0)
1060             PerlIO_write(ofp, SvPVX(PL_formfeed), SvCUR(PL_formfeed));
1061         IoLINES_LEFT(io) = IoPAGE_LEN(io);
1062         IoPAGE(io)++;
1063         PL_formtarget = PL_toptarget;
1064         IoFLAGS(io) |= IOf_DIDTOP;
1065         fgv = IoTOP_GV(io);
1066         if (!fgv)
1067             DIE("bad top format reference");
1068         cv = GvFORM(fgv);
1069         if (!cv) {
1070             SV *tmpsv = sv_newmortal();
1071             gv_efullname3(tmpsv, fgv, Nullch);
1072             DIE("Undefined top format \"%s\" called",SvPVX(tmpsv));
1073         }
1074         if (CvCLONE(cv))
1075             cv = (CV*)sv_2mortal((SV*)cv_clone(cv));
1076         return doform(cv,gv,PL_op);
1077     }
1078
1079   forget_top:
1080     POPBLOCK(cx,PL_curpm);
1081     POPFORMAT(cx);
1082     LEAVE;
1083
1084     fp = IoOFP(io);
1085     if (!fp) {
1086         if (PL_dowarn) {
1087             if (IoIFP(io))
1088                 warn("Filehandle only opened for input");
1089             else
1090                 warn("Write on closed filehandle");
1091         }
1092         PUSHs(&PL_sv_no);
1093     }
1094     else {
1095         if ((IoLINES_LEFT(io) -= FmLINES(PL_formtarget)) < 0) {
1096             if (PL_dowarn)
1097                 warn("page overflow");
1098         }
1099         if (!PerlIO_write(ofp, SvPVX(PL_formtarget), SvCUR(PL_formtarget)) ||
1100                 PerlIO_error(fp))
1101             PUSHs(&PL_sv_no);
1102         else {
1103             FmLINES(PL_formtarget) = 0;
1104             SvCUR_set(PL_formtarget, 0);
1105             *SvEND(PL_formtarget) = '\0';
1106             if (IoFLAGS(io) & IOf_FLUSH)
1107                 (void)PerlIO_flush(fp);
1108             PUSHs(&PL_sv_yes);
1109         }
1110     }
1111     PL_formtarget = PL_bodytarget;
1112     PUTBACK;
1113     return pop_return();
1114 }
1115
1116 PP(pp_prtf)
1117 {
1118     djSP; dMARK; dORIGMARK;
1119     GV *gv;
1120     IO *io;
1121     PerlIO *fp;
1122     SV *sv;
1123     MAGIC *mg;
1124
1125     if (PL_op->op_flags & OPf_STACKED)
1126         gv = (GV*)*++MARK;
1127     else
1128         gv = PL_defoutgv;
1129
1130     if (SvRMAGICAL(gv) && (mg = mg_find((SV*)gv, 'q'))) {
1131         if (MARK == ORIGMARK) {
1132             MEXTEND(SP, 1);
1133             ++MARK;
1134             Move(MARK, MARK + 1, (SP - MARK) + 1, SV*);
1135             ++SP;
1136         }
1137         PUSHMARK(MARK - 1);
1138         *MARK = mg->mg_obj;
1139         PUTBACK;
1140         ENTER;
1141         perl_call_method("PRINTF", G_SCALAR);
1142         LEAVE;
1143         SPAGAIN;
1144         MARK = ORIGMARK + 1;
1145         *MARK = *SP;
1146         SP = MARK;
1147         RETURN;
1148     }
1149
1150     sv = NEWSV(0,0);
1151     if (!(io = GvIO(gv))) {
1152         if (PL_dowarn) {
1153             gv_fullname3(sv, gv, Nullch);
1154             warn("Filehandle %s never opened", SvPV(sv,PL_na));
1155         }
1156         SETERRNO(EBADF,RMS$_IFI);
1157         goto just_say_no;
1158     }
1159     else if (!(fp = IoOFP(io))) {
1160         if (PL_dowarn)  {
1161             gv_fullname3(sv, gv, Nullch);
1162             if (IoIFP(io))
1163                 warn("Filehandle %s opened only for input", SvPV(sv,PL_na));
1164             else
1165                 warn("printf on closed filehandle %s", SvPV(sv,PL_na));
1166         }
1167         SETERRNO(EBADF,IoIFP(io)?RMS$_FAC:RMS$_IFI);
1168         goto just_say_no;
1169     }
1170     else {
1171 #ifdef USE_LOCALE_NUMERIC
1172         if (PL_op->op_private & OPpLOCALE)
1173             SET_NUMERIC_LOCAL();
1174         else
1175             SET_NUMERIC_STANDARD();
1176 #endif
1177         do_sprintf(sv, SP - MARK, MARK + 1);
1178         if (!do_print(sv, fp))
1179             goto just_say_no;
1180
1181         if (IoFLAGS(io) & IOf_FLUSH)
1182             if (PerlIO_flush(fp) == EOF)
1183                 goto just_say_no;
1184     }
1185     SvREFCNT_dec(sv);
1186     SP = ORIGMARK;
1187     PUSHs(&PL_sv_yes);
1188     RETURN;
1189
1190   just_say_no:
1191     SvREFCNT_dec(sv);
1192     SP = ORIGMARK;
1193     PUSHs(&PL_sv_undef);
1194     RETURN;
1195 }
1196
1197 PP(pp_sysopen)
1198 {
1199     djSP;
1200     GV *gv;
1201     SV *sv;
1202     char *tmps;
1203     STRLEN len;
1204     int mode, perm;
1205
1206     if (MAXARG > 3)
1207         perm = POPi;
1208     else
1209         perm = 0666;
1210     mode = POPi;
1211     sv = POPs;
1212     gv = (GV *)POPs;
1213
1214     tmps = SvPV(sv, len);
1215     if (do_open(gv, tmps, len, TRUE, mode, perm, Nullfp)) {
1216         IoLINES(GvIOp(gv)) = 0;
1217         PUSHs(&PL_sv_yes);
1218     }
1219     else {
1220         PUSHs(&PL_sv_undef);
1221     }
1222     RETURN;
1223 }
1224
1225 PP(pp_sysread)
1226 {
1227     djSP; dMARK; dORIGMARK; dTARGET;
1228     int offset;
1229     GV *gv;
1230     IO *io;
1231     char *buffer;
1232     SSize_t length;
1233     Sock_size_t bufsize;
1234     SV *bufsv;
1235     STRLEN blen;
1236     MAGIC *mg;
1237
1238     gv = (GV*)*++MARK;
1239     if ((PL_op->op_type == OP_READ || PL_op->op_type == OP_SYSREAD) &&
1240         SvRMAGICAL(gv) && (mg = mg_find((SV*)gv, 'q')))
1241     {
1242         SV *sv;
1243         
1244         PUSHMARK(MARK-1);
1245         *MARK = mg->mg_obj;
1246         ENTER;
1247         perl_call_method("READ", G_SCALAR);
1248         LEAVE;
1249         SPAGAIN;
1250         sv = POPs;
1251         SP = ORIGMARK;
1252         PUSHs(sv);
1253         RETURN;
1254     }
1255
1256     if (!gv)
1257         goto say_undef;
1258     bufsv = *++MARK;
1259     if (! SvOK(bufsv))
1260         sv_setpvn(bufsv, "", 0);
1261     buffer = SvPV_force(bufsv, blen);
1262     length = SvIVx(*++MARK);
1263     if (length < 0)
1264         DIE("Negative length");
1265     SETERRNO(0,0);
1266     if (MARK < SP)
1267         offset = SvIVx(*++MARK);
1268     else
1269         offset = 0;
1270     io = GvIO(gv);
1271     if (!io || !IoIFP(io))
1272         goto say_undef;
1273 #ifdef HAS_SOCKET
1274     if (PL_op->op_type == OP_RECV) {
1275         char namebuf[MAXPATHLEN];
1276 #if (defined(VMS_DO_SOCKETS) && defined(DECCRTL_SOCKETS)) || defined(MPE)
1277         bufsize = sizeof (struct sockaddr_in);
1278 #else
1279         bufsize = sizeof namebuf;
1280 #endif
1281         buffer = SvGROW(bufsv, length+1);
1282         /* 'offset' means 'flags' here */
1283         length = PerlSock_recvfrom(PerlIO_fileno(IoIFP(io)), buffer, length, offset,
1284                           (struct sockaddr *)namebuf, &bufsize);
1285         if (length < 0)
1286             RETPUSHUNDEF;
1287         SvCUR_set(bufsv, length);
1288         *SvEND(bufsv) = '\0';
1289         (void)SvPOK_only(bufsv);
1290         SvSETMAGIC(bufsv);
1291         /* This should not be marked tainted if the fp is marked clean */
1292         if (!(IoFLAGS(io) & IOf_UNTAINT))
1293             SvTAINTED_on(bufsv);
1294         SP = ORIGMARK;
1295         sv_setpvn(TARG, namebuf, bufsize);
1296         PUSHs(TARG);
1297         RETURN;
1298     }
1299 #else
1300     if (PL_op->op_type == OP_RECV)
1301         DIE(no_sock_func, "recv");
1302 #endif
1303     if (offset < 0) {
1304         if (-offset > blen)
1305             DIE("Offset outside string");
1306         offset += blen;
1307     }
1308     bufsize = SvCUR(bufsv);
1309     buffer = SvGROW(bufsv, length+offset+1);
1310     if (offset > bufsize) { /* Zero any newly allocated space */
1311         Zero(buffer+bufsize, offset-bufsize, char);
1312     }
1313     if (PL_op->op_type == OP_SYSREAD) {
1314         length = PerlLIO_read(PerlIO_fileno(IoIFP(io)), buffer+offset, length);
1315     }
1316     else
1317 #ifdef HAS_SOCKET__bad_code_maybe
1318     if (IoTYPE(io) == 's') {
1319         char namebuf[MAXPATHLEN];
1320 #if defined(VMS_DO_SOCKETS) && defined(DECCRTL_SOCKETS)
1321         bufsize = sizeof (struct sockaddr_in);
1322 #else
1323         bufsize = sizeof namebuf;
1324 #endif
1325         length = PerlSock_recvfrom(PerlIO_fileno(IoIFP(io)), buffer+offset, length, 0,
1326                           (struct sockaddr *)namebuf, &bufsize);
1327     }
1328     else
1329 #endif
1330     {
1331         length = PerlIO_read(IoIFP(io), buffer+offset, length);
1332         /* fread() returns 0 on both error and EOF */
1333         if (length == 0 && PerlIO_error(IoIFP(io)))
1334             length = -1;
1335     }
1336     if (length < 0)
1337         goto say_undef;
1338     SvCUR_set(bufsv, length+offset);
1339     *SvEND(bufsv) = '\0';
1340     (void)SvPOK_only(bufsv);
1341     SvSETMAGIC(bufsv);
1342     /* This should not be marked tainted if the fp is marked clean */
1343     if (!(IoFLAGS(io) & IOf_UNTAINT))
1344         SvTAINTED_on(bufsv);
1345     SP = ORIGMARK;
1346     PUSHi(length);
1347     RETURN;
1348
1349   say_undef:
1350     SP = ORIGMARK;
1351     RETPUSHUNDEF;
1352 }
1353
1354 PP(pp_syswrite)
1355 {
1356     return pp_send(ARGS);
1357 }
1358
1359 PP(pp_send)
1360 {
1361     djSP; dMARK; dORIGMARK; dTARGET;
1362     GV *gv;
1363     IO *io;
1364     int offset;
1365     SV *bufsv;
1366     char *buffer;
1367     int length;
1368     STRLEN blen;
1369     MAGIC *mg;
1370
1371     gv = (GV*)*++MARK;
1372     if (PL_op->op_type == OP_SYSWRITE &&
1373         SvRMAGICAL(gv) && (mg = mg_find((SV*)gv, 'q')))
1374     {
1375         SV *sv;
1376         
1377         PUSHMARK(MARK-1);
1378         *MARK = mg->mg_obj;
1379         ENTER;
1380         perl_call_method("WRITE", G_SCALAR);
1381         LEAVE;
1382         SPAGAIN;
1383         sv = POPs;
1384         SP = ORIGMARK;
1385         PUSHs(sv);
1386         RETURN;
1387     }
1388     if (!gv)
1389         goto say_undef;
1390     bufsv = *++MARK;
1391     buffer = SvPV(bufsv, blen);
1392     length = SvIVx(*++MARK);
1393     if (length < 0)
1394         DIE("Negative length");
1395     SETERRNO(0,0);
1396     io = GvIO(gv);
1397     if (!io || !IoIFP(io)) {
1398         length = -1;
1399         if (PL_dowarn) {
1400             if (PL_op->op_type == OP_SYSWRITE)
1401                 warn("Syswrite on closed filehandle");
1402             else
1403                 warn("Send on closed socket");
1404         }
1405     }
1406     else if (PL_op->op_type == OP_SYSWRITE) {
1407         if (MARK < SP) {
1408             offset = SvIVx(*++MARK);
1409             if (offset < 0) {
1410                 if (-offset > blen)
1411                     DIE("Offset outside string");
1412                 offset += blen;
1413             } else if (offset >= blen && blen > 0)
1414                 DIE("Offset outside string");
1415         } else
1416             offset = 0;
1417         if (length > blen - offset)
1418             length = blen - offset;
1419         length = PerlLIO_write(PerlIO_fileno(IoIFP(io)), buffer+offset, length);
1420     }
1421 #ifdef HAS_SOCKET
1422     else if (SP > MARK) {
1423         char *sockbuf;
1424         STRLEN mlen;
1425         sockbuf = SvPVx(*++MARK, mlen);
1426         length = PerlSock_sendto(PerlIO_fileno(IoIFP(io)), buffer, blen, length,
1427                                 (struct sockaddr *)sockbuf, mlen);
1428     }
1429     else
1430         length = PerlSock_send(PerlIO_fileno(IoIFP(io)), buffer, blen, length);
1431
1432 #else
1433     else
1434         DIE(no_sock_func, "send");
1435 #endif
1436     if (length < 0)
1437         goto say_undef;
1438     SP = ORIGMARK;
1439     PUSHi(length);
1440     RETURN;
1441
1442   say_undef:
1443     SP = ORIGMARK;
1444     RETPUSHUNDEF;
1445 }
1446
1447 PP(pp_recv)
1448 {
1449     return pp_sysread(ARGS);
1450 }
1451
1452 PP(pp_eof)
1453 {
1454     djSP;
1455     GV *gv;
1456
1457     if (MAXARG <= 0)
1458         gv = PL_last_in_gv;
1459     else
1460         gv = PL_last_in_gv = (GV*)POPs;
1461     PUSHs(boolSV(!gv || do_eof(gv)));
1462     RETURN;
1463 }
1464
1465 PP(pp_tell)
1466 {
1467     djSP; dTARGET;
1468     GV *gv;
1469
1470     if (MAXARG <= 0)
1471         gv = PL_last_in_gv;
1472     else
1473         gv = PL_last_in_gv = (GV*)POPs;
1474     PUSHi( do_tell(gv) );
1475     RETURN;
1476 }
1477
1478 PP(pp_seek)
1479 {
1480     return pp_sysseek(ARGS);
1481 }
1482
1483 PP(pp_sysseek)
1484 {
1485     djSP;
1486     GV *gv;
1487     int whence = POPi;
1488     long offset = POPl;
1489
1490     gv = PL_last_in_gv = (GV*)POPs;
1491     if (PL_op->op_type == OP_SEEK)
1492         PUSHs(boolSV(do_seek(gv, offset, whence)));
1493     else {
1494         long n = do_sysseek(gv, offset, whence);
1495         PUSHs((n < 0) ? &PL_sv_undef
1496               : sv_2mortal(n ? newSViv((IV)n)
1497                            : newSVpv(zero_but_true, ZBTLEN)));
1498     }
1499     RETURN;
1500 }
1501
1502 PP(pp_truncate)
1503 {
1504     djSP;
1505     Off_t len = (Off_t)POPn;
1506     int result = 1;
1507     GV *tmpgv;
1508
1509     SETERRNO(0,0);
1510 #if defined(HAS_TRUNCATE) || defined(HAS_CHSIZE) || defined(F_FREESP)
1511     if (PL_op->op_flags & OPf_SPECIAL) {
1512         tmpgv = gv_fetchpv(POPp, FALSE, SVt_PVIO);
1513     do_ftruncate:
1514         TAINT_PROPER("truncate");
1515         if (!GvIO(tmpgv) || !IoIFP(GvIOp(tmpgv)) ||
1516 #ifdef HAS_TRUNCATE
1517           ftruncate(PerlIO_fileno(IoIFP(GvIOn(tmpgv))), len) < 0)
1518 #else 
1519           my_chsize(PerlIO_fileno(IoIFP(GvIOn(tmpgv))), len) < 0)
1520 #endif
1521             result = 0;
1522     }
1523     else {
1524         SV *sv = POPs;
1525         char *name;
1526
1527         if (SvTYPE(sv) == SVt_PVGV) {
1528             tmpgv = (GV*)sv;            /* *main::FRED for example */
1529             goto do_ftruncate;
1530         }
1531         else if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVGV) {
1532             tmpgv = (GV*) SvRV(sv);     /* \*main::FRED for example */
1533             goto do_ftruncate;
1534         }
1535
1536         name = SvPV(sv, PL_na);
1537         TAINT_PROPER("truncate");
1538 #ifdef HAS_TRUNCATE
1539         if (truncate(name, len) < 0)
1540             result = 0;
1541 #else
1542         {
1543             int tmpfd;
1544             if ((tmpfd = PerlLIO_open(name, O_RDWR)) < 0)
1545                 result = 0;
1546             else {
1547                 if (my_chsize(tmpfd, len) < 0)
1548                     result = 0;
1549                 PerlLIO_close(tmpfd);
1550             }
1551         }
1552 #endif
1553     }
1554
1555     if (result)
1556         RETPUSHYES;
1557     if (!errno)
1558         SETERRNO(EBADF,RMS$_IFI);
1559     RETPUSHUNDEF;
1560 #else
1561     DIE("truncate not implemented");
1562 #endif
1563 }
1564
1565 PP(pp_fcntl)
1566 {
1567     return pp_ioctl(ARGS);
1568 }
1569
1570 PP(pp_ioctl)
1571 {
1572     djSP; dTARGET;
1573     SV *argsv = POPs;
1574     unsigned int func = U_I(POPn);
1575     int optype = PL_op->op_type;
1576     char *s;
1577     IV retval;
1578     GV *gv = (GV*)POPs;
1579     IO *io = GvIOn(gv);
1580
1581     if (!io || !argsv || !IoIFP(io)) {
1582         SETERRNO(EBADF,RMS$_IFI);       /* well, sort of... */
1583         RETPUSHUNDEF;
1584     }
1585
1586     if (SvPOK(argsv) || !SvNIOK(argsv)) {
1587         STRLEN len;
1588         STRLEN need;
1589         s = SvPV_force(argsv, len);
1590         need = IOCPARM_LEN(func);
1591         if (len < need) {
1592             s = Sv_Grow(argsv, need + 1);
1593             SvCUR_set(argsv, need);
1594         }
1595
1596         s[SvCUR(argsv)] = 17;   /* a little sanity check here */
1597     }
1598     else {
1599         retval = SvIV(argsv);
1600         s = (char*)retval;              /* ouch */
1601     }
1602
1603     TAINT_PROPER(optype == OP_IOCTL ? "ioctl" : "fcntl");
1604
1605     if (optype == OP_IOCTL)
1606 #ifdef HAS_IOCTL
1607         retval = PerlLIO_ioctl(PerlIO_fileno(IoIFP(io)), func, s);
1608 #else
1609         DIE("ioctl is not implemented");
1610 #endif
1611     else
1612 #ifdef HAS_FCNTL
1613 #if defined(OS2) && defined(__EMX__)
1614         retval = fcntl(PerlIO_fileno(IoIFP(io)), func, (int)s);
1615 #else
1616         retval = fcntl(PerlIO_fileno(IoIFP(io)), func, s);
1617 #endif 
1618 #else
1619         DIE("fcntl is not implemented");
1620 #endif
1621
1622     if (SvPOK(argsv)) {
1623         if (s[SvCUR(argsv)] != 17)
1624             DIE("Possible memory corruption: %s overflowed 3rd argument",
1625                 op_name[optype]);
1626         s[SvCUR(argsv)] = 0;            /* put our null back */
1627         SvSETMAGIC(argsv);              /* Assume it has changed */
1628     }
1629
1630     if (retval == -1)
1631         RETPUSHUNDEF;
1632     if (retval != 0) {
1633         PUSHi(retval);
1634     }
1635     else {
1636         PUSHp(zero_but_true, ZBTLEN);
1637     }
1638     RETURN;
1639 }
1640
1641 PP(pp_flock)
1642 {
1643     djSP; dTARGET;
1644     I32 value;
1645     int argtype;
1646     GV *gv;
1647     PerlIO *fp;
1648
1649 #ifdef FLOCK
1650     argtype = POPi;
1651     if (MAXARG <= 0)
1652         gv = PL_last_in_gv;
1653     else
1654         gv = (GV*)POPs;
1655     if (gv && GvIO(gv))
1656         fp = IoIFP(GvIOp(gv));
1657     else
1658         fp = Nullfp;
1659     if (fp) {
1660         (void)PerlIO_flush(fp);
1661         value = (I32)(PerlLIO_flock(PerlIO_fileno(fp), argtype) >= 0);
1662     }
1663     else
1664         value = 0;
1665     PUSHi(value);
1666     RETURN;
1667 #else
1668     DIE(no_func, "flock()");
1669 #endif
1670 }
1671
1672 /* Sockets. */
1673
1674 PP(pp_socket)
1675 {
1676     djSP;
1677 #ifdef HAS_SOCKET
1678     GV *gv;
1679     register IO *io;
1680     int protocol = POPi;
1681     int type = POPi;
1682     int domain = POPi;
1683     int fd;
1684
1685     gv = (GV*)POPs;
1686
1687     if (!gv) {
1688         SETERRNO(EBADF,LIB$_INVARG);
1689         RETPUSHUNDEF;
1690     }
1691
1692     io = GvIOn(gv);
1693     if (IoIFP(io))
1694         do_close(gv, FALSE);
1695
1696     TAINT_PROPER("socket");
1697     fd = PerlSock_socket(domain, type, protocol);
1698     if (fd < 0)
1699         RETPUSHUNDEF;
1700     IoIFP(io) = PerlIO_fdopen(fd, "r"); /* stdio gets confused about sockets */
1701     IoOFP(io) = PerlIO_fdopen(fd, "w");
1702     IoTYPE(io) = 's';
1703     if (!IoIFP(io) || !IoOFP(io)) {
1704         if (IoIFP(io)) PerlIO_close(IoIFP(io));
1705         if (IoOFP(io)) PerlIO_close(IoOFP(io));
1706         if (!IoIFP(io) && !IoOFP(io)) PerlLIO_close(fd);
1707         RETPUSHUNDEF;
1708     }
1709
1710     RETPUSHYES;
1711 #else
1712     DIE(no_sock_func, "socket");
1713 #endif
1714 }
1715
1716 PP(pp_sockpair)
1717 {
1718     djSP;
1719 #ifdef HAS_SOCKETPAIR
1720     GV *gv1;
1721     GV *gv2;
1722     register IO *io1;
1723     register IO *io2;
1724     int protocol = POPi;
1725     int type = POPi;
1726     int domain = POPi;
1727     int fd[2];
1728
1729     gv2 = (GV*)POPs;
1730     gv1 = (GV*)POPs;
1731     if (!gv1 || !gv2)
1732         RETPUSHUNDEF;
1733
1734     io1 = GvIOn(gv1);
1735     io2 = GvIOn(gv2);
1736     if (IoIFP(io1))
1737         do_close(gv1, FALSE);
1738     if (IoIFP(io2))
1739         do_close(gv2, FALSE);
1740
1741     TAINT_PROPER("socketpair");
1742     if (PerlSock_socketpair(domain, type, protocol, fd) < 0)
1743         RETPUSHUNDEF;
1744     IoIFP(io1) = PerlIO_fdopen(fd[0], "r");
1745     IoOFP(io1) = PerlIO_fdopen(fd[0], "w");
1746     IoTYPE(io1) = 's';
1747     IoIFP(io2) = PerlIO_fdopen(fd[1], "r");
1748     IoOFP(io2) = PerlIO_fdopen(fd[1], "w");
1749     IoTYPE(io2) = 's';
1750     if (!IoIFP(io1) || !IoOFP(io1) || !IoIFP(io2) || !IoOFP(io2)) {
1751         if (IoIFP(io1)) PerlIO_close(IoIFP(io1));
1752         if (IoOFP(io1)) PerlIO_close(IoOFP(io1));
1753         if (!IoIFP(io1) && !IoOFP(io1)) PerlLIO_close(fd[0]);
1754         if (IoIFP(io2)) PerlIO_close(IoIFP(io2));
1755         if (IoOFP(io2)) PerlIO_close(IoOFP(io2));
1756         if (!IoIFP(io2) && !IoOFP(io2)) PerlLIO_close(fd[1]);
1757         RETPUSHUNDEF;
1758     }
1759
1760     RETPUSHYES;
1761 #else
1762     DIE(no_sock_func, "socketpair");
1763 #endif
1764 }
1765
1766 PP(pp_bind)
1767 {
1768     djSP;
1769 #ifdef HAS_SOCKET
1770 #ifdef MPE /* Requires PRIV mode to bind() to ports < 1024 */
1771     extern GETPRIVMODE();
1772     extern GETUSERMODE();
1773 #endif
1774     SV *addrsv = POPs;
1775     char *addr;
1776     GV *gv = (GV*)POPs;
1777     register IO *io = GvIOn(gv);
1778     STRLEN len;
1779     int bind_ok = 0;
1780 #ifdef MPE
1781     int mpeprivmode = 0;
1782 #endif
1783
1784     if (!io || !IoIFP(io))
1785         goto nuts;
1786
1787     addr = SvPV(addrsv, len);
1788     TAINT_PROPER("bind");
1789 #ifdef MPE /* Deal with MPE bind() peculiarities */
1790     if (((struct sockaddr *)addr)->sa_family == AF_INET) {
1791         /* The address *MUST* stupidly be zero. */
1792         ((struct sockaddr_in *)addr)->sin_addr.s_addr = INADDR_ANY;
1793         /* PRIV mode is required to bind() to ports < 1024. */
1794         if (((struct sockaddr_in *)addr)->sin_port < 1024 &&
1795             ((struct sockaddr_in *)addr)->sin_port > 0) {
1796             GETPRIVMODE(); /* If this fails, we are aborted by MPE/iX. */
1797             mpeprivmode = 1;
1798         }
1799     }
1800 #endif /* MPE */
1801     if (PerlSock_bind(PerlIO_fileno(IoIFP(io)),
1802                       (struct sockaddr *)addr, len) >= 0)
1803         bind_ok = 1;
1804
1805 #ifdef MPE /* Switch back to USER mode */
1806     if (mpeprivmode)
1807         GETUSERMODE();
1808 #endif /* MPE */
1809
1810     if (bind_ok)
1811         RETPUSHYES;
1812     else
1813         RETPUSHUNDEF;
1814
1815 nuts:
1816     if (PL_dowarn)
1817         warn("bind() on closed fd");
1818     SETERRNO(EBADF,SS$_IVCHAN);
1819     RETPUSHUNDEF;
1820 #else
1821     DIE(no_sock_func, "bind");
1822 #endif
1823 }
1824
1825 PP(pp_connect)
1826 {
1827     djSP;
1828 #ifdef HAS_SOCKET
1829     SV *addrsv = POPs;
1830     char *addr;
1831     GV *gv = (GV*)POPs;
1832     register IO *io = GvIOn(gv);
1833     STRLEN len;
1834
1835     if (!io || !IoIFP(io))
1836         goto nuts;
1837
1838     addr = SvPV(addrsv, len);
1839     TAINT_PROPER("connect");
1840     if (PerlSock_connect(PerlIO_fileno(IoIFP(io)), (struct sockaddr *)addr, len) >= 0)
1841         RETPUSHYES;
1842     else
1843         RETPUSHUNDEF;
1844
1845 nuts:
1846     if (PL_dowarn)
1847         warn("connect() on closed fd");
1848     SETERRNO(EBADF,SS$_IVCHAN);
1849     RETPUSHUNDEF;
1850 #else
1851     DIE(no_sock_func, "connect");
1852 #endif
1853 }
1854
1855 PP(pp_listen)
1856 {
1857     djSP;
1858 #ifdef HAS_SOCKET
1859     int backlog = POPi;
1860     GV *gv = (GV*)POPs;
1861     register IO *io = GvIOn(gv);
1862
1863     if (!io || !IoIFP(io))
1864         goto nuts;
1865
1866     if (PerlSock_listen(PerlIO_fileno(IoIFP(io)), backlog) >= 0)
1867         RETPUSHYES;
1868     else
1869         RETPUSHUNDEF;
1870
1871 nuts:
1872     if (PL_dowarn)
1873         warn("listen() on closed fd");
1874     SETERRNO(EBADF,SS$_IVCHAN);
1875     RETPUSHUNDEF;
1876 #else
1877     DIE(no_sock_func, "listen");
1878 #endif
1879 }
1880
1881 PP(pp_accept)
1882 {
1883     djSP; dTARGET;
1884 #ifdef HAS_SOCKET
1885     GV *ngv;
1886     GV *ggv;
1887     register IO *nstio;
1888     register IO *gstio;
1889     struct sockaddr saddr;      /* use a struct to avoid alignment problems */
1890     Sock_size_t len = sizeof saddr;
1891     int fd;
1892
1893     ggv = (GV*)POPs;
1894     ngv = (GV*)POPs;
1895
1896     if (!ngv)
1897         goto badexit;
1898     if (!ggv)
1899         goto nuts;
1900
1901     gstio = GvIO(ggv);
1902     if (!gstio || !IoIFP(gstio))
1903         goto nuts;
1904
1905     nstio = GvIOn(ngv);
1906     if (IoIFP(nstio))
1907         do_close(ngv, FALSE);
1908
1909     fd = PerlSock_accept(PerlIO_fileno(IoIFP(gstio)), (struct sockaddr *)&saddr, &len);
1910     if (fd < 0)
1911         goto badexit;
1912     IoIFP(nstio) = PerlIO_fdopen(fd, "r");
1913     IoOFP(nstio) = PerlIO_fdopen(fd, "w");
1914     IoTYPE(nstio) = 's';
1915     if (!IoIFP(nstio) || !IoOFP(nstio)) {
1916         if (IoIFP(nstio)) PerlIO_close(IoIFP(nstio));
1917         if (IoOFP(nstio)) PerlIO_close(IoOFP(nstio));
1918         if (!IoIFP(nstio) && !IoOFP(nstio)) PerlLIO_close(fd);
1919         goto badexit;
1920     }
1921
1922     PUSHp((char *)&saddr, len);
1923     RETURN;
1924
1925 nuts:
1926     if (PL_dowarn)
1927         warn("accept() on closed fd");
1928     SETERRNO(EBADF,SS$_IVCHAN);
1929
1930 badexit:
1931     RETPUSHUNDEF;
1932
1933 #else
1934     DIE(no_sock_func, "accept");
1935 #endif
1936 }
1937
1938 PP(pp_shutdown)
1939 {
1940     djSP; dTARGET;
1941 #ifdef HAS_SOCKET
1942     int how = POPi;
1943     GV *gv = (GV*)POPs;
1944     register IO *io = GvIOn(gv);
1945
1946     if (!io || !IoIFP(io))
1947         goto nuts;
1948
1949     PUSHi( PerlSock_shutdown(PerlIO_fileno(IoIFP(io)), how) >= 0 );
1950     RETURN;
1951
1952 nuts:
1953     if (PL_dowarn)
1954         warn("shutdown() on closed fd");
1955     SETERRNO(EBADF,SS$_IVCHAN);
1956     RETPUSHUNDEF;
1957 #else
1958     DIE(no_sock_func, "shutdown");
1959 #endif
1960 }
1961
1962 PP(pp_gsockopt)
1963 {
1964 #ifdef HAS_SOCKET
1965     return pp_ssockopt(ARGS);
1966 #else
1967     DIE(no_sock_func, "getsockopt");
1968 #endif
1969 }
1970
1971 PP(pp_ssockopt)
1972 {
1973     djSP;
1974 #ifdef HAS_SOCKET
1975     int optype = PL_op->op_type;
1976     SV *sv;
1977     int fd;
1978     unsigned int optname;
1979     unsigned int lvl;
1980     GV *gv;
1981     register IO *io;
1982     Sock_size_t len;
1983
1984     if (optype == OP_GSOCKOPT)
1985         sv = sv_2mortal(NEWSV(22, 257));
1986     else
1987         sv = POPs;
1988     optname = (unsigned int) POPi;
1989     lvl = (unsigned int) POPi;
1990
1991     gv = (GV*)POPs;
1992     io = GvIOn(gv);
1993     if (!io || !IoIFP(io))
1994         goto nuts;
1995
1996     fd = PerlIO_fileno(IoIFP(io));
1997     switch (optype) {
1998     case OP_GSOCKOPT:
1999         SvGROW(sv, 257);
2000         (void)SvPOK_only(sv);
2001         SvCUR_set(sv,256);
2002         *SvEND(sv) ='\0';
2003         len = SvCUR(sv);
2004         if (PerlSock_getsockopt(fd, lvl, optname, SvPVX(sv), &len) < 0)
2005             goto nuts2;
2006         SvCUR_set(sv, len);
2007         *SvEND(sv) ='\0';
2008         PUSHs(sv);
2009         break;
2010     case OP_SSOCKOPT: {
2011             char *buf;
2012             int aint;
2013             if (SvPOKp(sv)) {
2014                 buf = SvPV(sv, PL_na);
2015                 len = PL_na;
2016             }
2017             else {
2018                 aint = (int)SvIV(sv);
2019                 buf = (char*)&aint;
2020                 len = sizeof(int);
2021             }
2022             if (PerlSock_setsockopt(fd, lvl, optname, buf, len) < 0)
2023                 goto nuts2;
2024             PUSHs(&PL_sv_yes);
2025         }
2026         break;
2027     }
2028     RETURN;
2029
2030 nuts:
2031     if (PL_dowarn)
2032         warn("[gs]etsockopt() on closed fd");
2033     SETERRNO(EBADF,SS$_IVCHAN);
2034 nuts2:
2035     RETPUSHUNDEF;
2036
2037 #else
2038     DIE(no_sock_func, "setsockopt");
2039 #endif
2040 }
2041
2042 PP(pp_getsockname)
2043 {
2044 #ifdef HAS_SOCKET
2045     return pp_getpeername(ARGS);
2046 #else
2047     DIE(no_sock_func, "getsockname");
2048 #endif
2049 }
2050
2051 PP(pp_getpeername)
2052 {
2053     djSP;
2054 #ifdef HAS_SOCKET
2055     int optype = PL_op->op_type;
2056     SV *sv;
2057     int fd;
2058     GV *gv = (GV*)POPs;
2059     register IO *io = GvIOn(gv);
2060     Sock_size_t len;
2061
2062     if (!io || !IoIFP(io))
2063         goto nuts;
2064
2065     sv = sv_2mortal(NEWSV(22, 257));
2066     (void)SvPOK_only(sv);
2067     len = 256;
2068     SvCUR_set(sv, len);
2069     *SvEND(sv) ='\0';
2070     fd = PerlIO_fileno(IoIFP(io));
2071     switch (optype) {
2072     case OP_GETSOCKNAME:
2073         if (PerlSock_getsockname(fd, (struct sockaddr *)SvPVX(sv), &len) < 0)
2074             goto nuts2;
2075         break;
2076     case OP_GETPEERNAME:
2077         if (PerlSock_getpeername(fd, (struct sockaddr *)SvPVX(sv), &len) < 0)
2078             goto nuts2;
2079 #if defined(VMS_DO_SOCKETS) && defined (DECCRTL_SOCKETS)
2080         {
2081             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";
2082             /* If the call succeeded, make sure we don't have a zeroed port/addr */
2083             if (((struct sockaddr *)SvPVX(sv))->sa_family == AF_INET &&
2084                 !memcmp((char *)SvPVX(sv) + sizeof(u_short), nowhere,
2085                         sizeof(u_short) + sizeof(struct in_addr))) {
2086                 goto nuts2;         
2087             }
2088         }
2089 #endif
2090         break;
2091     }
2092 #ifdef BOGUS_GETNAME_RETURN
2093     /* Interactive Unix, getpeername() and getsockname()
2094       does not return valid namelen */
2095     if (len == BOGUS_GETNAME_RETURN)
2096         len = sizeof(struct sockaddr);
2097 #endif
2098     SvCUR_set(sv, len);
2099     *SvEND(sv) ='\0';
2100     PUSHs(sv);
2101     RETURN;
2102
2103 nuts:
2104     if (PL_dowarn)
2105         warn("get{sock, peer}name() on closed fd");
2106     SETERRNO(EBADF,SS$_IVCHAN);
2107 nuts2:
2108     RETPUSHUNDEF;
2109
2110 #else
2111     DIE(no_sock_func, "getpeername");
2112 #endif
2113 }
2114
2115 /* Stat calls. */
2116
2117 PP(pp_lstat)
2118 {
2119     return pp_stat(ARGS);
2120 }
2121
2122 PP(pp_stat)
2123 {
2124     djSP;
2125     GV *tmpgv;
2126     I32 gimme;
2127     I32 max = 13;
2128
2129     if (PL_op->op_flags & OPf_REF) {
2130         tmpgv = cGVOP->op_gv;
2131       do_fstat:
2132         if (tmpgv != PL_defgv) {
2133             PL_laststype = OP_STAT;
2134             PL_statgv = tmpgv;
2135             sv_setpv(PL_statname, "");
2136             PL_laststatval = (GvIO(tmpgv) && IoIFP(GvIOp(tmpgv))
2137                 ? PerlLIO_fstat(PerlIO_fileno(IoIFP(GvIOn(tmpgv))), &PL_statcache) : -1);
2138         }
2139         if (PL_laststatval < 0)
2140             max = 0;
2141     }
2142     else {
2143         SV* sv = POPs;
2144         if (SvTYPE(sv) == SVt_PVGV) {
2145             tmpgv = (GV*)sv;
2146             goto do_fstat;
2147         }
2148         else if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVGV) {
2149             tmpgv = (GV*)SvRV(sv);
2150             goto do_fstat;
2151         }
2152         sv_setpv(PL_statname, SvPV(sv,PL_na));
2153         PL_statgv = Nullgv;
2154 #ifdef HAS_LSTAT
2155         PL_laststype = PL_op->op_type;
2156         if (PL_op->op_type == OP_LSTAT)
2157             PL_laststatval = PerlLIO_lstat(SvPV(PL_statname, PL_na), &PL_statcache);
2158         else
2159 #endif
2160             PL_laststatval = PerlLIO_stat(SvPV(PL_statname, PL_na), &PL_statcache);
2161         if (PL_laststatval < 0) {
2162             if (PL_dowarn && strchr(SvPV(PL_statname, PL_na), '\n'))
2163                 warn(warn_nl, "stat");
2164             max = 0;
2165         }
2166     }
2167
2168     gimme = GIMME_V;
2169     if (gimme != G_ARRAY) {
2170         if (gimme != G_VOID)
2171             XPUSHs(boolSV(max));
2172         RETURN;
2173     }
2174     if (max) {
2175         EXTEND(SP, max);
2176         EXTEND_MORTAL(max);
2177         PUSHs(sv_2mortal(newSViv((I32)PL_statcache.st_dev)));
2178         PUSHs(sv_2mortal(newSViv((I32)PL_statcache.st_ino)));
2179         PUSHs(sv_2mortal(newSViv((I32)PL_statcache.st_mode)));
2180         PUSHs(sv_2mortal(newSViv((I32)PL_statcache.st_nlink)));
2181         PUSHs(sv_2mortal(newSViv((I32)PL_statcache.st_uid)));
2182         PUSHs(sv_2mortal(newSViv((I32)PL_statcache.st_gid)));
2183 #ifdef USE_STAT_RDEV
2184         PUSHs(sv_2mortal(newSViv((I32)PL_statcache.st_rdev)));
2185 #else
2186         PUSHs(sv_2mortal(newSVpv("", 0)));
2187 #endif
2188         PUSHs(sv_2mortal(newSViv((I32)PL_statcache.st_size)));
2189 #ifdef BIG_TIME
2190         PUSHs(sv_2mortal(newSVnv((U32)PL_statcache.st_atime)));
2191         PUSHs(sv_2mortal(newSVnv((U32)PL_statcache.st_mtime)));
2192         PUSHs(sv_2mortal(newSVnv((U32)PL_statcache.st_ctime)));
2193 #else
2194         PUSHs(sv_2mortal(newSViv((I32)PL_statcache.st_atime)));
2195         PUSHs(sv_2mortal(newSViv((I32)PL_statcache.st_mtime)));
2196         PUSHs(sv_2mortal(newSViv((I32)PL_statcache.st_ctime)));
2197 #endif
2198 #ifdef USE_STAT_BLOCKS
2199         PUSHs(sv_2mortal(newSViv((I32)PL_statcache.st_blksize)));
2200         PUSHs(sv_2mortal(newSViv((I32)PL_statcache.st_blocks)));
2201 #else
2202         PUSHs(sv_2mortal(newSVpv("", 0)));
2203         PUSHs(sv_2mortal(newSVpv("", 0)));
2204 #endif
2205     }
2206     RETURN;
2207 }
2208
2209 PP(pp_ftrread)
2210 {
2211     I32 result = my_stat(ARGS);
2212     djSP;
2213     if (result < 0)
2214         RETPUSHUNDEF;
2215     if (cando(S_IRUSR, 0, &PL_statcache))
2216         RETPUSHYES;
2217     RETPUSHNO;
2218 }
2219
2220 PP(pp_ftrwrite)
2221 {
2222     I32 result = my_stat(ARGS);
2223     djSP;
2224     if (result < 0)
2225         RETPUSHUNDEF;
2226     if (cando(S_IWUSR, 0, &PL_statcache))
2227         RETPUSHYES;
2228     RETPUSHNO;
2229 }
2230
2231 PP(pp_ftrexec)
2232 {
2233     I32 result = my_stat(ARGS);
2234     djSP;
2235     if (result < 0)
2236         RETPUSHUNDEF;
2237     if (cando(S_IXUSR, 0, &PL_statcache))
2238         RETPUSHYES;
2239     RETPUSHNO;
2240 }
2241
2242 PP(pp_fteread)
2243 {
2244     I32 result = my_stat(ARGS);
2245     djSP;
2246     if (result < 0)
2247         RETPUSHUNDEF;
2248     if (cando(S_IRUSR, 1, &PL_statcache))
2249         RETPUSHYES;
2250     RETPUSHNO;
2251 }
2252
2253 PP(pp_ftewrite)
2254 {
2255     I32 result = my_stat(ARGS);
2256     djSP;
2257     if (result < 0)
2258         RETPUSHUNDEF;
2259     if (cando(S_IWUSR, 1, &PL_statcache))
2260         RETPUSHYES;
2261     RETPUSHNO;
2262 }
2263
2264 PP(pp_fteexec)
2265 {
2266     I32 result = my_stat(ARGS);
2267     djSP;
2268     if (result < 0)
2269         RETPUSHUNDEF;
2270     if (cando(S_IXUSR, 1, &PL_statcache))
2271         RETPUSHYES;
2272     RETPUSHNO;
2273 }
2274
2275 PP(pp_ftis)
2276 {
2277     I32 result = my_stat(ARGS);
2278     djSP;
2279     if (result < 0)
2280         RETPUSHUNDEF;
2281     RETPUSHYES;
2282 }
2283
2284 PP(pp_fteowned)
2285 {
2286     return pp_ftrowned(ARGS);
2287 }
2288
2289 PP(pp_ftrowned)
2290 {
2291     I32 result = my_stat(ARGS);
2292     djSP;
2293     if (result < 0)
2294         RETPUSHUNDEF;
2295     if (PL_statcache.st_uid == (PL_op->op_type == OP_FTEOWNED ? PL_euid : PL_uid) )
2296         RETPUSHYES;
2297     RETPUSHNO;
2298 }
2299
2300 PP(pp_ftzero)
2301 {
2302     I32 result = my_stat(ARGS);
2303     djSP;
2304     if (result < 0)
2305         RETPUSHUNDEF;
2306     if (!PL_statcache.st_size)
2307         RETPUSHYES;
2308     RETPUSHNO;
2309 }
2310
2311 PP(pp_ftsize)
2312 {
2313     I32 result = my_stat(ARGS);
2314     djSP; dTARGET;
2315     if (result < 0)
2316         RETPUSHUNDEF;
2317     PUSHi(PL_statcache.st_size);
2318     RETURN;
2319 }
2320
2321 PP(pp_ftmtime)
2322 {
2323     I32 result = my_stat(ARGS);
2324     djSP; dTARGET;
2325     if (result < 0)
2326         RETPUSHUNDEF;
2327     PUSHn( ((I32)PL_basetime - (I32)PL_statcache.st_mtime) / 86400.0 );
2328     RETURN;
2329 }
2330
2331 PP(pp_ftatime)
2332 {
2333     I32 result = my_stat(ARGS);
2334     djSP; dTARGET;
2335     if (result < 0)
2336         RETPUSHUNDEF;
2337     PUSHn( ((I32)PL_basetime - (I32)PL_statcache.st_atime) / 86400.0 );
2338     RETURN;
2339 }
2340
2341 PP(pp_ftctime)
2342 {
2343     I32 result = my_stat(ARGS);
2344     djSP; dTARGET;
2345     if (result < 0)
2346         RETPUSHUNDEF;
2347     PUSHn( ((I32)PL_basetime - (I32)PL_statcache.st_ctime) / 86400.0 );
2348     RETURN;
2349 }
2350
2351 PP(pp_ftsock)
2352 {
2353     I32 result = my_stat(ARGS);
2354     djSP;
2355     if (result < 0)
2356         RETPUSHUNDEF;
2357     if (S_ISSOCK(PL_statcache.st_mode))
2358         RETPUSHYES;
2359     RETPUSHNO;
2360 }
2361
2362 PP(pp_ftchr)
2363 {
2364     I32 result = my_stat(ARGS);
2365     djSP;
2366     if (result < 0)
2367         RETPUSHUNDEF;
2368     if (S_ISCHR(PL_statcache.st_mode))
2369         RETPUSHYES;
2370     RETPUSHNO;
2371 }
2372
2373 PP(pp_ftblk)
2374 {
2375     I32 result = my_stat(ARGS);
2376     djSP;
2377     if (result < 0)
2378         RETPUSHUNDEF;
2379     if (S_ISBLK(PL_statcache.st_mode))
2380         RETPUSHYES;
2381     RETPUSHNO;
2382 }
2383
2384 PP(pp_ftfile)
2385 {
2386     I32 result = my_stat(ARGS);
2387     djSP;
2388     if (result < 0)
2389         RETPUSHUNDEF;
2390     if (S_ISREG(PL_statcache.st_mode))
2391         RETPUSHYES;
2392     RETPUSHNO;
2393 }
2394
2395 PP(pp_ftdir)
2396 {
2397     I32 result = my_stat(ARGS);
2398     djSP;
2399     if (result < 0)
2400         RETPUSHUNDEF;
2401     if (S_ISDIR(PL_statcache.st_mode))
2402         RETPUSHYES;
2403     RETPUSHNO;
2404 }
2405
2406 PP(pp_ftpipe)
2407 {
2408     I32 result = my_stat(ARGS);
2409     djSP;
2410     if (result < 0)
2411         RETPUSHUNDEF;
2412     if (S_ISFIFO(PL_statcache.st_mode))
2413         RETPUSHYES;
2414     RETPUSHNO;
2415 }
2416
2417 PP(pp_ftlink)
2418 {
2419     I32 result = my_lstat(ARGS);
2420     djSP;
2421     if (result < 0)
2422         RETPUSHUNDEF;
2423     if (S_ISLNK(PL_statcache.st_mode))
2424         RETPUSHYES;
2425     RETPUSHNO;
2426 }
2427
2428 PP(pp_ftsuid)
2429 {
2430     djSP;
2431 #ifdef S_ISUID
2432     I32 result = my_stat(ARGS);
2433     SPAGAIN;
2434     if (result < 0)
2435         RETPUSHUNDEF;
2436     if (PL_statcache.st_mode & S_ISUID)
2437         RETPUSHYES;
2438 #endif
2439     RETPUSHNO;
2440 }
2441
2442 PP(pp_ftsgid)
2443 {
2444     djSP;
2445 #ifdef S_ISGID
2446     I32 result = my_stat(ARGS);
2447     SPAGAIN;
2448     if (result < 0)
2449         RETPUSHUNDEF;
2450     if (PL_statcache.st_mode & S_ISGID)
2451         RETPUSHYES;
2452 #endif
2453     RETPUSHNO;
2454 }
2455
2456 PP(pp_ftsvtx)
2457 {
2458     djSP;
2459 #ifdef S_ISVTX
2460     I32 result = my_stat(ARGS);
2461     SPAGAIN;
2462     if (result < 0)
2463         RETPUSHUNDEF;
2464     if (PL_statcache.st_mode & S_ISVTX)
2465         RETPUSHYES;
2466 #endif
2467     RETPUSHNO;
2468 }
2469
2470 PP(pp_fttty)
2471 {
2472     djSP;
2473     int fd;
2474     GV *gv;
2475     char *tmps = Nullch;
2476
2477     if (PL_op->op_flags & OPf_REF)
2478         gv = cGVOP->op_gv;
2479     else if (isGV(TOPs))
2480         gv = (GV*)POPs;
2481     else if (SvROK(TOPs) && isGV(SvRV(TOPs)))
2482         gv = (GV*)SvRV(POPs);
2483     else
2484         gv = gv_fetchpv(tmps = POPp, FALSE, SVt_PVIO);
2485
2486     if (GvIO(gv) && IoIFP(GvIOp(gv)))
2487         fd = PerlIO_fileno(IoIFP(GvIOp(gv)));
2488     else if (tmps && isDIGIT(*tmps))
2489         fd = atoi(tmps);
2490     else
2491         RETPUSHUNDEF;
2492     if (PerlLIO_isatty(fd))
2493         RETPUSHYES;
2494     RETPUSHNO;
2495 }
2496
2497 #if defined(atarist) /* this will work with atariST. Configure will
2498                         make guesses for other systems. */
2499 # define FILE_base(f) ((f)->_base)
2500 # define FILE_ptr(f) ((f)->_ptr)
2501 # define FILE_cnt(f) ((f)->_cnt)
2502 # define FILE_bufsiz(f) ((f)->_cnt + ((f)->_ptr - (f)->_base))
2503 #endif
2504
2505 PP(pp_fttext)
2506 {
2507     djSP;
2508     I32 i;
2509     I32 len;
2510     I32 odd = 0;
2511     STDCHAR tbuf[512];
2512     register STDCHAR *s;
2513     register IO *io;
2514     register SV *sv;
2515     GV *gv;
2516
2517     if (PL_op->op_flags & OPf_REF)
2518         gv = cGVOP->op_gv;
2519     else if (isGV(TOPs))
2520         gv = (GV*)POPs;
2521     else if (SvROK(TOPs) && isGV(SvRV(TOPs)))
2522         gv = (GV*)SvRV(POPs);
2523     else
2524         gv = Nullgv;
2525
2526     if (gv) {
2527         EXTEND(SP, 1);
2528         if (gv == PL_defgv) {
2529             if (PL_statgv)
2530                 io = GvIO(PL_statgv);
2531             else {
2532                 sv = PL_statname;
2533                 goto really_filename;
2534             }
2535         }
2536         else {
2537             PL_statgv = gv;
2538             PL_laststatval = -1;
2539             sv_setpv(PL_statname, "");
2540             io = GvIO(PL_statgv);
2541         }
2542         if (io && IoIFP(io)) {
2543             if (! PerlIO_has_base(IoIFP(io)))
2544                 DIE("-T and -B not implemented on filehandles");
2545             PL_laststatval = PerlLIO_fstat(PerlIO_fileno(IoIFP(io)), &PL_statcache);
2546             if (PL_laststatval < 0)
2547                 RETPUSHUNDEF;
2548             if (S_ISDIR(PL_statcache.st_mode))  /* handle NFS glitch */
2549                 if (PL_op->op_type == OP_FTTEXT)
2550                     RETPUSHNO;
2551                 else
2552                     RETPUSHYES;
2553             if (PerlIO_get_cnt(IoIFP(io)) <= 0) {
2554                 i = PerlIO_getc(IoIFP(io));
2555                 if (i != EOF)
2556                     (void)PerlIO_ungetc(IoIFP(io),i);
2557             }
2558             if (PerlIO_get_cnt(IoIFP(io)) <= 0) /* null file is anything */
2559                 RETPUSHYES;
2560             len = PerlIO_get_bufsiz(IoIFP(io));
2561             s = (STDCHAR *) PerlIO_get_base(IoIFP(io));
2562             /* sfio can have large buffers - limit to 512 */
2563             if (len > 512)
2564                 len = 512;
2565         }
2566         else {
2567             if (PL_dowarn)
2568                 warn("Test on unopened file <%s>",
2569                   GvENAME(cGVOP->op_gv));
2570             SETERRNO(EBADF,RMS$_IFI);
2571             RETPUSHUNDEF;
2572         }
2573     }
2574     else {
2575         sv = POPs;
2576       really_filename:
2577         PL_statgv = Nullgv;
2578         PL_laststatval = -1;
2579         sv_setpv(PL_statname, SvPV(sv, PL_na));
2580 #ifdef HAS_OPEN3
2581         i = PerlLIO_open3(SvPV(sv, PL_na), O_RDONLY, 0);
2582 #else
2583         i = PerlLIO_open(SvPV(sv, PL_na), 0);
2584 #endif
2585         if (i < 0) {
2586             if (PL_dowarn && strchr(SvPV(sv, PL_na), '\n'))
2587                 warn(warn_nl, "open");
2588             RETPUSHUNDEF;
2589         }
2590         PL_laststatval = PerlLIO_fstat(i, &PL_statcache);
2591         if (PL_laststatval < 0)
2592             RETPUSHUNDEF;
2593         len = PerlLIO_read(i, tbuf, 512);
2594         (void)PerlLIO_close(i);
2595         if (len <= 0) {
2596             if (S_ISDIR(PL_statcache.st_mode) && PL_op->op_type == OP_FTTEXT)
2597                 RETPUSHNO;              /* special case NFS directories */
2598             RETPUSHYES;         /* null file is anything */
2599         }
2600         s = tbuf;
2601     }
2602
2603     /* now scan s to look for textiness */
2604     /*   XXX ASCII dependent code */
2605
2606     for (i = 0; i < len; i++, s++) {
2607         if (!*s) {                      /* null never allowed in text */
2608             odd += len;
2609             break;
2610         }
2611         else if (*s & 128)
2612             odd++;
2613         else if (*s < 32 &&
2614           *s != '\n' && *s != '\r' && *s != '\b' &&
2615           *s != '\t' && *s != '\f' && *s != 27)
2616             odd++;
2617     }
2618
2619     if ((odd * 3 > len) == (PL_op->op_type == OP_FTTEXT)) /* allow 1/3 odd */
2620         RETPUSHNO;
2621     else
2622         RETPUSHYES;
2623 }
2624
2625 PP(pp_ftbinary)
2626 {
2627     return pp_fttext(ARGS);
2628 }
2629
2630 /* File calls. */
2631
2632 PP(pp_chdir)
2633 {
2634     djSP; dTARGET;
2635     char *tmps;
2636     SV **svp;
2637
2638     if (MAXARG < 1)
2639         tmps = Nullch;
2640     else
2641         tmps = POPp;
2642     if (!tmps || !*tmps) {
2643         svp = hv_fetch(GvHVn(PL_envgv), "HOME", 4, FALSE);
2644         if (svp)
2645             tmps = SvPV(*svp, PL_na);
2646     }
2647     if (!tmps || !*tmps) {
2648         svp = hv_fetch(GvHVn(PL_envgv), "LOGDIR", 6, FALSE);
2649         if (svp)
2650             tmps = SvPV(*svp, PL_na);
2651     }
2652 #ifdef VMS
2653     if (!tmps || !*tmps) {
2654        svp = hv_fetch(GvHVn(PL_envgv), "SYS$LOGIN", 9, FALSE);
2655        if (svp)
2656            tmps = SvPV(*svp, PL_na);
2657     }
2658 #endif
2659     TAINT_PROPER("chdir");
2660     PUSHi( PerlDir_chdir(tmps) >= 0 );
2661 #ifdef VMS
2662     /* Clear the DEFAULT element of ENV so we'll get the new value
2663      * in the future. */
2664     hv_delete(GvHVn(PL_envgv),"DEFAULT",7,G_DISCARD);
2665 #endif
2666     RETURN;
2667 }
2668
2669 PP(pp_chown)
2670 {
2671     djSP; dMARK; dTARGET;
2672     I32 value;
2673 #ifdef HAS_CHOWN
2674     value = (I32)apply(PL_op->op_type, MARK, SP);
2675     SP = MARK;
2676     PUSHi(value);
2677     RETURN;
2678 #else
2679     DIE(no_func, "Unsupported function chown");
2680 #endif
2681 }
2682
2683 PP(pp_chroot)
2684 {
2685     djSP; dTARGET;
2686     char *tmps;
2687 #ifdef HAS_CHROOT
2688     tmps = POPp;
2689     TAINT_PROPER("chroot");
2690     PUSHi( chroot(tmps) >= 0 );
2691     RETURN;
2692 #else
2693     DIE(no_func, "chroot");
2694 #endif
2695 }
2696
2697 PP(pp_unlink)
2698 {
2699     djSP; dMARK; dTARGET;
2700     I32 value;
2701     value = (I32)apply(PL_op->op_type, MARK, SP);
2702     SP = MARK;
2703     PUSHi(value);
2704     RETURN;
2705 }
2706
2707 PP(pp_chmod)
2708 {
2709     djSP; dMARK; dTARGET;
2710     I32 value;
2711     value = (I32)apply(PL_op->op_type, MARK, SP);
2712     SP = MARK;
2713     PUSHi(value);
2714     RETURN;
2715 }
2716
2717 PP(pp_utime)
2718 {
2719     djSP; dMARK; dTARGET;
2720     I32 value;
2721     value = (I32)apply(PL_op->op_type, MARK, SP);
2722     SP = MARK;
2723     PUSHi(value);
2724     RETURN;
2725 }
2726
2727 PP(pp_rename)
2728 {
2729     djSP; dTARGET;
2730     int anum;
2731
2732     char *tmps2 = POPp;
2733     char *tmps = SvPV(TOPs, PL_na);
2734     TAINT_PROPER("rename");
2735 #ifdef HAS_RENAME
2736     anum = PerlLIO_rename(tmps, tmps2);
2737 #else
2738     if (!(anum = PerlLIO_stat(tmps, &PL_statbuf))) {
2739         if (same_dirent(tmps2, tmps))   /* can always rename to same name */
2740             anum = 1;
2741         else {
2742             if (euid || PerlLIO_stat(tmps2, &PL_statbuf) < 0 || !S_ISDIR(PL_statbuf.st_mode))
2743                 (void)UNLINK(tmps2);
2744             if (!(anum = link(tmps, tmps2)))
2745                 anum = UNLINK(tmps);
2746         }
2747     }
2748 #endif
2749     SETi( anum >= 0 );
2750     RETURN;
2751 }
2752
2753 PP(pp_link)
2754 {
2755     djSP; dTARGET;
2756 #ifdef HAS_LINK
2757     char *tmps2 = POPp;
2758     char *tmps = SvPV(TOPs, PL_na);
2759     TAINT_PROPER("link");
2760     SETi( link(tmps, tmps2) >= 0 );
2761 #else
2762     DIE(no_func, "Unsupported function link");
2763 #endif
2764     RETURN;
2765 }
2766
2767 PP(pp_symlink)
2768 {
2769     djSP; dTARGET;
2770 #ifdef HAS_SYMLINK
2771     char *tmps2 = POPp;
2772     char *tmps = SvPV(TOPs, PL_na);
2773     TAINT_PROPER("symlink");
2774     SETi( symlink(tmps, tmps2) >= 0 );
2775     RETURN;
2776 #else
2777     DIE(no_func, "symlink");
2778 #endif
2779 }
2780
2781 PP(pp_readlink)
2782 {
2783     djSP; dTARGET;
2784 #ifdef HAS_SYMLINK
2785     char *tmps;
2786     char buf[MAXPATHLEN];
2787     int len;
2788
2789 #ifndef INCOMPLETE_TAINTS
2790     TAINT;
2791 #endif
2792     tmps = POPp;
2793     len = readlink(tmps, buf, sizeof buf);
2794     EXTEND(SP, 1);
2795     if (len < 0)
2796         RETPUSHUNDEF;
2797     PUSHp(buf, len);
2798     RETURN;
2799 #else
2800     EXTEND(SP, 1);
2801     RETSETUNDEF;                /* just pretend it's a normal file */
2802 #endif
2803 }
2804
2805 #if !defined(HAS_MKDIR) || !defined(HAS_RMDIR)
2806 static int
2807 dooneliner(cmd, filename)
2808 char *cmd;
2809 char *filename;
2810 {
2811     char *save_filename = filename;
2812     char *cmdline;
2813     char *s;
2814     PerlIO *myfp;
2815     int anum = 1;
2816
2817     New(666, cmdline, strlen(cmd) + (strlen(filename) * 2) + 10, char);
2818     strcpy(cmdline, cmd);
2819     strcat(cmdline, " ");
2820     for (s = cmdline + strlen(cmdline); *filename; ) {
2821         *s++ = '\\';
2822         *s++ = *filename++;
2823     }
2824     strcpy(s, " 2>&1");
2825     myfp = PerlProc_popen(cmdline, "r");
2826     Safefree(cmdline);
2827
2828     if (myfp) {
2829         SV *tmpsv = sv_newmortal();
2830         /* Need to save/restore 'PL_rs' ?? */
2831         s = sv_gets(tmpsv, myfp, 0);
2832         (void)PerlProc_pclose(myfp);
2833         if (s != Nullch) {
2834             int e;
2835             for (e = 1;
2836 #ifdef HAS_SYS_ERRLIST
2837                  e <= sys_nerr
2838 #endif
2839                  ; e++)
2840             {
2841                 /* you don't see this */
2842                 char *errmsg =
2843 #ifdef HAS_SYS_ERRLIST
2844                     sys_errlist[e]
2845 #else
2846                     strerror(e)
2847 #endif
2848                     ;
2849                 if (!errmsg)
2850                     break;
2851                 if (instr(s, errmsg)) {
2852                     SETERRNO(e,0);
2853                     return 0;
2854                 }
2855             }
2856             SETERRNO(0,0);
2857 #ifndef EACCES
2858 #define EACCES EPERM
2859 #endif
2860             if (instr(s, "cannot make"))
2861                 SETERRNO(EEXIST,RMS$_FEX);
2862             else if (instr(s, "existing file"))
2863                 SETERRNO(EEXIST,RMS$_FEX);
2864             else if (instr(s, "ile exists"))
2865                 SETERRNO(EEXIST,RMS$_FEX);
2866             else if (instr(s, "non-exist"))
2867                 SETERRNO(ENOENT,RMS$_FNF);
2868             else if (instr(s, "does not exist"))
2869                 SETERRNO(ENOENT,RMS$_FNF);
2870             else if (instr(s, "not empty"))
2871                 SETERRNO(EBUSY,SS$_DEVOFFLINE);
2872             else if (instr(s, "cannot access"))
2873                 SETERRNO(EACCES,RMS$_PRV);
2874             else
2875                 SETERRNO(EPERM,RMS$_PRV);
2876             return 0;
2877         }
2878         else {  /* some mkdirs return no failure indication */
2879             anum = (PerlLIO_stat(save_filename, &PL_statbuf) >= 0);
2880             if (PL_op->op_type == OP_RMDIR)
2881                 anum = !anum;
2882             if (anum)
2883                 SETERRNO(0,0);
2884             else
2885                 SETERRNO(EACCES,RMS$_PRV);      /* a guess */
2886         }
2887         return anum;
2888     }
2889     else
2890         return 0;
2891 }
2892 #endif
2893
2894 PP(pp_mkdir)
2895 {
2896     djSP; dTARGET;
2897     int mode = POPi;
2898 #ifndef HAS_MKDIR
2899     int oldumask;
2900 #endif
2901     char *tmps = SvPV(TOPs, PL_na);
2902
2903     TAINT_PROPER("mkdir");
2904 #ifdef HAS_MKDIR
2905     SETi( PerlDir_mkdir(tmps, mode) >= 0 );
2906 #else
2907     SETi( dooneliner("mkdir", tmps) );
2908     oldumask = PerlLIO_umask(0);
2909     PerlLIO_umask(oldumask);
2910     PerlLIO_chmod(tmps, (mode & ~oldumask) & 0777);
2911 #endif
2912     RETURN;
2913 }
2914
2915 PP(pp_rmdir)
2916 {
2917     djSP; dTARGET;
2918     char *tmps;
2919
2920     tmps = POPp;
2921     TAINT_PROPER("rmdir");
2922 #ifdef HAS_RMDIR
2923     XPUSHi( PerlDir_rmdir(tmps) >= 0 );
2924 #else
2925     XPUSHi( dooneliner("rmdir", tmps) );
2926 #endif
2927     RETURN;
2928 }
2929
2930 /* Directory calls. */
2931
2932 PP(pp_open_dir)
2933 {
2934     djSP;
2935 #if defined(Direntry_t) && defined(HAS_READDIR)
2936     char *dirname = POPp;
2937     GV *gv = (GV*)POPs;
2938     register IO *io = GvIOn(gv);
2939
2940     if (!io)
2941         goto nope;
2942
2943     if (IoDIRP(io))
2944         PerlDir_close(IoDIRP(io));
2945     if (!(IoDIRP(io) = PerlDir_open(dirname)))
2946         goto nope;
2947
2948     RETPUSHYES;
2949 nope:
2950     if (!errno)
2951         SETERRNO(EBADF,RMS$_DIR);
2952     RETPUSHUNDEF;
2953 #else
2954     DIE(no_dir_func, "opendir");
2955 #endif
2956 }
2957
2958 PP(pp_readdir)
2959 {
2960     djSP;
2961 #if defined(Direntry_t) && defined(HAS_READDIR)
2962 #ifndef I_DIRENT
2963     Direntry_t *readdir _((DIR *));
2964 #endif
2965     register Direntry_t *dp;
2966     GV *gv = (GV*)POPs;
2967     register IO *io = GvIOn(gv);
2968     SV *sv;
2969
2970     if (!io || !IoDIRP(io))
2971         goto nope;
2972
2973     if (GIMME == G_ARRAY) {
2974         /*SUPPRESS 560*/
2975         while (dp = (Direntry_t *)PerlDir_read(IoDIRP(io))) {
2976 #ifdef DIRNAMLEN
2977             sv = newSVpv(dp->d_name, dp->d_namlen);
2978 #else
2979             sv = newSVpv(dp->d_name, 0);
2980 #endif
2981 #ifndef INCOMPLETE_TAINTS
2982             SvTAINTED_on(sv);
2983 #endif
2984             XPUSHs(sv_2mortal(sv));
2985         }
2986     }
2987     else {
2988         if (!(dp = (Direntry_t *)PerlDir_read(IoDIRP(io))))
2989             goto nope;
2990 #ifdef DIRNAMLEN
2991         sv = newSVpv(dp->d_name, dp->d_namlen);
2992 #else
2993         sv = newSVpv(dp->d_name, 0);
2994 #endif
2995 #ifndef INCOMPLETE_TAINTS
2996         SvTAINTED_on(sv);
2997 #endif
2998         XPUSHs(sv_2mortal(sv));
2999     }
3000     RETURN;
3001
3002 nope:
3003     if (!errno)
3004         SETERRNO(EBADF,RMS$_ISI);
3005     if (GIMME == G_ARRAY)
3006         RETURN;
3007     else
3008         RETPUSHUNDEF;
3009 #else
3010     DIE(no_dir_func, "readdir");
3011 #endif
3012 }
3013
3014 PP(pp_telldir)
3015 {
3016     djSP; dTARGET;
3017 #if defined(HAS_TELLDIR) || defined(telldir)
3018 # ifdef NEED_TELLDIR_PROTO /* XXX does _anyone_ need this? --AD 2/20/1998 */
3019     long telldir _((DIR *));
3020 # endif
3021     GV *gv = (GV*)POPs;
3022     register IO *io = GvIOn(gv);
3023
3024     if (!io || !IoDIRP(io))
3025         goto nope;
3026
3027     PUSHi( PerlDir_tell(IoDIRP(io)) );
3028     RETURN;
3029 nope:
3030     if (!errno)
3031         SETERRNO(EBADF,RMS$_ISI);
3032     RETPUSHUNDEF;
3033 #else
3034     DIE(no_dir_func, "telldir");
3035 #endif
3036 }
3037
3038 PP(pp_seekdir)
3039 {
3040     djSP;
3041 #if defined(HAS_SEEKDIR) || defined(seekdir)
3042     long along = POPl;
3043     GV *gv = (GV*)POPs;
3044     register IO *io = GvIOn(gv);
3045
3046     if (!io || !IoDIRP(io))
3047         goto nope;
3048
3049     (void)PerlDir_seek(IoDIRP(io), along);
3050
3051     RETPUSHYES;
3052 nope:
3053     if (!errno)
3054         SETERRNO(EBADF,RMS$_ISI);
3055     RETPUSHUNDEF;
3056 #else
3057     DIE(no_dir_func, "seekdir");
3058 #endif
3059 }
3060
3061 PP(pp_rewinddir)
3062 {
3063     djSP;
3064 #if defined(HAS_REWINDDIR) || defined(rewinddir)
3065     GV *gv = (GV*)POPs;
3066     register IO *io = GvIOn(gv);
3067
3068     if (!io || !IoDIRP(io))
3069         goto nope;
3070
3071     (void)PerlDir_rewind(IoDIRP(io));
3072     RETPUSHYES;
3073 nope:
3074     if (!errno)
3075         SETERRNO(EBADF,RMS$_ISI);
3076     RETPUSHUNDEF;
3077 #else
3078     DIE(no_dir_func, "rewinddir");
3079 #endif
3080 }
3081
3082 PP(pp_closedir)
3083 {
3084     djSP;
3085 #if defined(Direntry_t) && defined(HAS_READDIR)
3086     GV *gv = (GV*)POPs;
3087     register IO *io = GvIOn(gv);
3088
3089     if (!io || !IoDIRP(io))
3090         goto nope;
3091
3092 #ifdef VOID_CLOSEDIR
3093     PerlDir_close(IoDIRP(io));
3094 #else
3095     if (PerlDir_close(IoDIRP(io)) < 0) {
3096         IoDIRP(io) = 0; /* Don't try to close again--coredumps on SysV */
3097         goto nope;
3098     }
3099 #endif
3100     IoDIRP(io) = 0;
3101
3102     RETPUSHYES;
3103 nope:
3104     if (!errno)
3105         SETERRNO(EBADF,RMS$_IFI);
3106     RETPUSHUNDEF;
3107 #else
3108     DIE(no_dir_func, "closedir");
3109 #endif
3110 }
3111
3112 /* Process control. */
3113
3114 PP(pp_fork)
3115 {
3116 #ifdef HAS_FORK
3117     djSP; dTARGET;
3118     int childpid;
3119     GV *tmpgv;
3120
3121     EXTEND(SP, 1);
3122     childpid = fork();
3123     if (childpid < 0)
3124         RETSETUNDEF;
3125     if (!childpid) {
3126         /*SUPPRESS 560*/
3127         if (tmpgv = gv_fetchpv("$", TRUE, SVt_PV))
3128             sv_setiv(GvSV(tmpgv), (IV)getpid());
3129         hv_clear(PL_pidstatus); /* no kids, so don't wait for 'em */
3130     }
3131     PUSHi(childpid);
3132     RETURN;
3133 #else
3134     DIE(no_func, "Unsupported function fork");
3135 #endif
3136 }
3137
3138 PP(pp_wait)
3139 {
3140 #if !defined(DOSISH) || defined(OS2) || defined(WIN32)
3141     djSP; dTARGET;
3142     int childpid;
3143     int argflags;
3144
3145     childpid = wait4pid(-1, &argflags, 0);
3146     STATUS_NATIVE_SET((childpid > 0) ? argflags : -1);
3147     XPUSHi(childpid);
3148     RETURN;
3149 #else
3150     DIE(no_func, "Unsupported function wait");
3151 #endif
3152 }
3153
3154 PP(pp_waitpid)
3155 {
3156 #if !defined(DOSISH) || defined(OS2) || defined(WIN32)
3157     djSP; dTARGET;
3158     int childpid;
3159     int optype;
3160     int argflags;
3161
3162     optype = POPi;
3163     childpid = TOPi;
3164     childpid = wait4pid(childpid, &argflags, optype);
3165     STATUS_NATIVE_SET((childpid > 0) ? argflags : -1);
3166     SETi(childpid);
3167     RETURN;
3168 #else
3169     DIE(no_func, "Unsupported function waitpid");
3170 #endif
3171 }
3172
3173 PP(pp_system)
3174 {
3175     djSP; dMARK; dORIGMARK; dTARGET;
3176     I32 value;
3177     int childpid;
3178     int result;
3179     int status;
3180     Sigsave_t ihand,qhand;     /* place to save signals during system() */
3181
3182     if (SP - MARK == 1) {
3183         if (PL_tainting) {
3184             char *junk = SvPV(TOPs, PL_na);
3185             TAINT_ENV();
3186             TAINT_PROPER("system");
3187         }
3188     }
3189 #if (defined(HAS_FORK) || defined(AMIGAOS)) && !defined(VMS) && !defined(OS2)
3190     while ((childpid = vfork()) == -1) {
3191         if (errno != EAGAIN) {
3192             value = -1;
3193             SP = ORIGMARK;
3194             PUSHi(value);
3195             RETURN;
3196         }
3197         sleep(5);
3198     }
3199     if (childpid > 0) {
3200         rsignal_save(SIGINT, SIG_IGN, &ihand);
3201         rsignal_save(SIGQUIT, SIG_IGN, &qhand);
3202         do {
3203             result = wait4pid(childpid, &status, 0);
3204         } while (result == -1 && errno == EINTR);
3205         (void)rsignal_restore(SIGINT, &ihand);
3206         (void)rsignal_restore(SIGQUIT, &qhand);
3207         STATUS_NATIVE_SET(result == -1 ? -1 : status);
3208         do_execfree();  /* free any memory child malloced on vfork */
3209         SP = ORIGMARK;
3210         PUSHi(STATUS_CURRENT);
3211         RETURN;
3212     }
3213     if (PL_op->op_flags & OPf_STACKED) {
3214         SV *really = *++MARK;
3215         value = (I32)do_aexec(really, MARK, SP);
3216     }
3217     else if (SP - MARK != 1)
3218         value = (I32)do_aexec(Nullsv, MARK, SP);
3219     else {
3220         value = (I32)do_exec(SvPVx(sv_mortalcopy(*SP), PL_na));
3221     }
3222     PerlProc__exit(-1);
3223 #else /* ! FORK or VMS or OS/2 */
3224     if (PL_op->op_flags & OPf_STACKED) {
3225         SV *really = *++MARK;
3226         value = (I32)do_aspawn(really, (void **)MARK, (void **)SP);
3227     }
3228     else if (SP - MARK != 1)
3229         value = (I32)do_aspawn(Nullsv, (void **)MARK, (void **)SP);
3230     else {
3231         value = (I32)do_spawn(SvPVx(sv_mortalcopy(*SP), PL_na));
3232     }
3233     STATUS_NATIVE_SET(value);
3234     do_execfree();
3235     SP = ORIGMARK;
3236     PUSHi(STATUS_CURRENT);
3237 #endif /* !FORK or VMS */
3238     RETURN;
3239 }
3240
3241 PP(pp_exec)
3242 {
3243     djSP; dMARK; dORIGMARK; dTARGET;
3244     I32 value;
3245
3246     if (PL_op->op_flags & OPf_STACKED) {
3247         SV *really = *++MARK;
3248         value = (I32)do_aexec(really, MARK, SP);
3249     }
3250     else if (SP - MARK != 1)
3251 #ifdef VMS
3252         value = (I32)vms_do_aexec(Nullsv, MARK, SP);
3253 #else
3254         value = (I32)do_aexec(Nullsv, MARK, SP);
3255 #endif
3256     else {
3257         if (PL_tainting) {
3258             char *junk = SvPV(*SP, PL_na);
3259             TAINT_ENV();
3260             TAINT_PROPER("exec");
3261         }
3262 #ifdef VMS
3263         value = (I32)vms_do_exec(SvPVx(sv_mortalcopy(*SP), PL_na));
3264 #else
3265         value = (I32)do_exec(SvPVx(sv_mortalcopy(*SP), PL_na));
3266 #endif
3267     }
3268     SP = ORIGMARK;
3269     PUSHi(value);
3270     RETURN;
3271 }
3272
3273 PP(pp_kill)
3274 {
3275     djSP; dMARK; dTARGET;
3276     I32 value;
3277 #ifdef HAS_KILL
3278     value = (I32)apply(PL_op->op_type, MARK, SP);
3279     SP = MARK;
3280     PUSHi(value);
3281     RETURN;
3282 #else
3283     DIE(no_func, "Unsupported function kill");
3284 #endif
3285 }
3286
3287 PP(pp_getppid)
3288 {
3289 #ifdef HAS_GETPPID
3290     djSP; dTARGET;
3291     XPUSHi( getppid() );
3292     RETURN;
3293 #else
3294     DIE(no_func, "getppid");
3295 #endif
3296 }
3297
3298 PP(pp_getpgrp)
3299 {
3300 #ifdef HAS_GETPGRP
3301     djSP; dTARGET;
3302     int pid;
3303     I32 value;
3304
3305     if (MAXARG < 1)
3306         pid = 0;
3307     else
3308         pid = SvIVx(POPs);
3309 #ifdef BSD_GETPGRP
3310     value = (I32)BSD_GETPGRP(pid);
3311 #else
3312     if (pid != 0 && pid != getpid())
3313         DIE("POSIX getpgrp can't take an argument");
3314     value = (I32)getpgrp();
3315 #endif
3316     XPUSHi(value);
3317     RETURN;
3318 #else
3319     DIE(no_func, "getpgrp()");
3320 #endif
3321 }
3322
3323 PP(pp_setpgrp)
3324 {
3325 #ifdef HAS_SETPGRP
3326     djSP; dTARGET;
3327     int pgrp;
3328     int pid;
3329     if (MAXARG < 2) {
3330         pgrp = 0;
3331         pid = 0;
3332     }
3333     else {
3334         pgrp = POPi;
3335         pid = TOPi;
3336     }
3337
3338     TAINT_PROPER("setpgrp");
3339 #ifdef BSD_SETPGRP
3340     SETi( BSD_SETPGRP(pid, pgrp) >= 0 );
3341 #else
3342     if ((pgrp != 0 && pgrp != getpid()) || (pid != 0 && pid != getpid()))
3343         DIE("POSIX setpgrp can't take an argument");
3344     SETi( setpgrp() >= 0 );
3345 #endif /* USE_BSDPGRP */
3346     RETURN;
3347 #else
3348     DIE(no_func, "setpgrp()");
3349 #endif
3350 }
3351
3352 PP(pp_getpriority)
3353 {
3354     djSP; dTARGET;
3355     int which;
3356     int who;
3357 #ifdef HAS_GETPRIORITY
3358     who = POPi;
3359     which = TOPi;
3360     SETi( getpriority(which, who) );
3361     RETURN;
3362 #else
3363     DIE(no_func, "getpriority()");
3364 #endif
3365 }
3366
3367 PP(pp_setpriority)
3368 {
3369     djSP; dTARGET;
3370     int which;
3371     int who;
3372     int niceval;
3373 #ifdef HAS_SETPRIORITY
3374     niceval = POPi;
3375     who = POPi;
3376     which = TOPi;
3377     TAINT_PROPER("setpriority");
3378     SETi( setpriority(which, who, niceval) >= 0 );
3379     RETURN;
3380 #else
3381     DIE(no_func, "setpriority()");
3382 #endif
3383 }
3384
3385 /* Time calls. */
3386
3387 PP(pp_time)
3388 {
3389     djSP; dTARGET;
3390 #ifdef BIG_TIME
3391     XPUSHn( time(Null(Time_t*)) );
3392 #else
3393     XPUSHi( time(Null(Time_t*)) );
3394 #endif
3395     RETURN;
3396 }
3397
3398 /* XXX The POSIX name is CLK_TCK; it is to be preferred
3399    to HZ.  Probably.  For now, assume that if the system
3400    defines HZ, it does so correctly.  (Will this break
3401    on VMS?)
3402    Probably we ought to use _sysconf(_SC_CLK_TCK), if
3403    it's supported.    --AD  9/96.
3404 */
3405
3406 #ifndef HZ
3407 #  ifdef CLK_TCK
3408 #    define HZ CLK_TCK
3409 #  else
3410 #    define HZ 60
3411 #  endif
3412 #endif
3413
3414 PP(pp_tms)
3415 {
3416     djSP;
3417
3418 #ifndef HAS_TIMES
3419     DIE("times not implemented");
3420 #else
3421     EXTEND(SP, 4);
3422
3423 #ifndef VMS
3424     (void)PerlProc_times(&PL_timesbuf);
3425 #else
3426     (void)PerlProc_times((tbuffer_t *)&PL_timesbuf);  /* time.h uses different name for */
3427                                                    /* struct tms, though same data   */
3428                                                    /* is returned.                   */
3429 #endif
3430
3431     PUSHs(sv_2mortal(newSVnv(((double)PL_timesbuf.tms_utime)/HZ)));
3432     if (GIMME == G_ARRAY) {
3433         PUSHs(sv_2mortal(newSVnv(((double)PL_timesbuf.tms_stime)/HZ)));
3434         PUSHs(sv_2mortal(newSVnv(((double)PL_timesbuf.tms_cutime)/HZ)));
3435         PUSHs(sv_2mortal(newSVnv(((double)PL_timesbuf.tms_cstime)/HZ)));
3436     }
3437     RETURN;
3438 #endif /* HAS_TIMES */
3439 }
3440
3441 PP(pp_localtime)
3442 {
3443     return pp_gmtime(ARGS);
3444 }
3445
3446 PP(pp_gmtime)
3447 {
3448     djSP;
3449     Time_t when;
3450     struct tm *tmbuf;
3451     static char *dayname[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
3452     static char *monname[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
3453                               "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
3454
3455     if (MAXARG < 1)
3456         (void)time(&when);
3457     else
3458 #ifdef BIG_TIME
3459         when = (Time_t)SvNVx(POPs);
3460 #else
3461         when = (Time_t)SvIVx(POPs);
3462 #endif
3463
3464     if (PL_op->op_type == OP_LOCALTIME)
3465         tmbuf = localtime(&when);
3466     else
3467         tmbuf = gmtime(&when);
3468
3469     EXTEND(SP, 9);
3470     EXTEND_MORTAL(9);
3471     if (GIMME != G_ARRAY) {
3472         dTARGET;
3473         SV *tsv;
3474         if (!tmbuf)
3475             RETPUSHUNDEF;
3476         tsv = newSVpvf("%s %s %2d %02d:%02d:%02d %d",
3477                        dayname[tmbuf->tm_wday],
3478                        monname[tmbuf->tm_mon],
3479                        tmbuf->tm_mday,
3480                        tmbuf->tm_hour,
3481                        tmbuf->tm_min,
3482                        tmbuf->tm_sec,
3483                        tmbuf->tm_year + 1900);
3484         PUSHs(sv_2mortal(tsv));
3485     }
3486     else if (tmbuf) {
3487         PUSHs(sv_2mortal(newSViv((I32)tmbuf->tm_sec)));
3488         PUSHs(sv_2mortal(newSViv((I32)tmbuf->tm_min)));
3489         PUSHs(sv_2mortal(newSViv((I32)tmbuf->tm_hour)));
3490         PUSHs(sv_2mortal(newSViv((I32)tmbuf->tm_mday)));
3491         PUSHs(sv_2mortal(newSViv((I32)tmbuf->tm_mon)));
3492         PUSHs(sv_2mortal(newSViv((I32)tmbuf->tm_year)));
3493         PUSHs(sv_2mortal(newSViv((I32)tmbuf->tm_wday)));
3494         PUSHs(sv_2mortal(newSViv((I32)tmbuf->tm_yday)));
3495         PUSHs(sv_2mortal(newSViv((I32)tmbuf->tm_isdst)));
3496     }
3497     RETURN;
3498 }
3499
3500 PP(pp_alarm)
3501 {
3502     djSP; dTARGET;
3503     int anum;
3504 #ifdef HAS_ALARM
3505     anum = POPi;
3506     anum = alarm((unsigned int)anum);
3507     EXTEND(SP, 1);
3508     if (anum < 0)
3509         RETPUSHUNDEF;
3510     PUSHi((I32)anum);
3511     RETURN;
3512 #else
3513     DIE(no_func, "Unsupported function alarm");
3514 #endif
3515 }
3516
3517 PP(pp_sleep)
3518 {
3519     djSP; dTARGET;
3520     I32 duration;
3521     Time_t lasttime;
3522     Time_t when;
3523
3524     (void)time(&lasttime);
3525     if (MAXARG < 1)
3526         PerlProc_pause();
3527     else {
3528         duration = POPi;
3529         PerlProc_sleep((unsigned int)duration);
3530     }
3531     (void)time(&when);
3532     XPUSHi(when - lasttime);
3533     RETURN;
3534 }
3535
3536 /* Shared memory. */
3537
3538 PP(pp_shmget)
3539 {
3540     return pp_semget(ARGS);
3541 }
3542
3543 PP(pp_shmctl)
3544 {
3545     return pp_semctl(ARGS);
3546 }
3547
3548 PP(pp_shmread)
3549 {
3550     return pp_shmwrite(ARGS);
3551 }
3552
3553 PP(pp_shmwrite)
3554 {
3555 #if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
3556     djSP; dMARK; dTARGET;
3557     I32 value = (I32)(do_shmio(PL_op->op_type, MARK, SP) >= 0);
3558     SP = MARK;
3559     PUSHi(value);
3560     RETURN;
3561 #else
3562     return pp_semget(ARGS);
3563 #endif
3564 }
3565
3566 /* Message passing. */
3567
3568 PP(pp_msgget)
3569 {
3570     return pp_semget(ARGS);
3571 }
3572
3573 PP(pp_msgctl)
3574 {
3575     return pp_semctl(ARGS);
3576 }
3577
3578 PP(pp_msgsnd)
3579 {
3580 #if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
3581     djSP; dMARK; dTARGET;
3582     I32 value = (I32)(do_msgsnd(MARK, SP) >= 0);
3583     SP = MARK;
3584     PUSHi(value);
3585     RETURN;
3586 #else
3587     return pp_semget(ARGS);
3588 #endif
3589 }
3590
3591 PP(pp_msgrcv)
3592 {
3593 #if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
3594     djSP; dMARK; dTARGET;
3595     I32 value = (I32)(do_msgrcv(MARK, SP) >= 0);
3596     SP = MARK;
3597     PUSHi(value);
3598     RETURN;
3599 #else
3600     return pp_semget(ARGS);
3601 #endif
3602 }
3603
3604 /* Semaphores. */
3605
3606 PP(pp_semget)
3607 {
3608 #if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
3609     djSP; dMARK; dTARGET;
3610     int anum = do_ipcget(PL_op->op_type, MARK, SP);
3611     SP = MARK;
3612     if (anum == -1)
3613         RETPUSHUNDEF;
3614     PUSHi(anum);
3615     RETURN;
3616 #else
3617     DIE("System V IPC is not implemented on this machine");
3618 #endif
3619 }
3620
3621 PP(pp_semctl)
3622 {
3623 #if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
3624     djSP; dMARK; dTARGET;
3625     int anum = do_ipcctl(PL_op->op_type, MARK, SP);
3626     SP = MARK;
3627     if (anum == -1)
3628         RETSETUNDEF;
3629     if (anum != 0) {
3630         PUSHi(anum);
3631     }
3632     else {
3633         PUSHp(zero_but_true, ZBTLEN);
3634     }
3635     RETURN;
3636 #else
3637     return pp_semget(ARGS);
3638 #endif
3639 }
3640
3641 PP(pp_semop)
3642 {
3643 #if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
3644     djSP; dMARK; dTARGET;
3645     I32 value = (I32)(do_semop(MARK, SP) >= 0);
3646     SP = MARK;
3647     PUSHi(value);
3648     RETURN;
3649 #else
3650     return pp_semget(ARGS);
3651 #endif
3652 }
3653
3654 /* Get system info. */
3655
3656 PP(pp_ghbyname)
3657 {
3658 #ifdef HAS_GETHOSTBYNAME
3659     return pp_ghostent(ARGS);
3660 #else
3661     DIE(no_sock_func, "gethostbyname");
3662 #endif
3663 }
3664
3665 PP(pp_ghbyaddr)
3666 {
3667 #ifdef HAS_GETHOSTBYADDR
3668     return pp_ghostent(ARGS);
3669 #else
3670     DIE(no_sock_func, "gethostbyaddr");
3671 #endif
3672 }
3673
3674 PP(pp_ghostent)
3675 {
3676     djSP;
3677 #if defined(HAS_GETHOSTBYNAME) || defined(HAS_GETHOSTBYADDR) || defined(HAS_GETHOSTENT)
3678     I32 which = PL_op->op_type;
3679     register char **elem;
3680     register SV *sv;
3681 #ifndef HAS_GETHOST_PROTOS /* XXX Do we need individual probes? */
3682     struct hostent *PerlSock_gethostbyaddr(Netdb_host_t, Netdb_hlen_t, int);
3683     struct hostent *PerlSock_gethostbyname(Netdb_name_t);
3684     struct hostent *PerlSock_gethostent(void);
3685 #endif
3686     struct hostent *hent;
3687     unsigned long len;
3688
3689     EXTEND(SP, 10);
3690     if (which == OP_GHBYNAME)
3691 #ifdef HAS_GETHOSTBYNAME
3692         hent = PerlSock_gethostbyname(POPp);
3693 #else
3694         DIE(no_sock_func, "gethostbyname");
3695 #endif
3696     else if (which == OP_GHBYADDR) {
3697 #ifdef HAS_GETHOSTBYADDR
3698         int addrtype = POPi;
3699         SV *addrsv = POPs;
3700         STRLEN addrlen;
3701         Netdb_host_t addr = (Netdb_host_t) SvPV(addrsv, addrlen);
3702
3703         hent = PerlSock_gethostbyaddr(addr, (Netdb_hlen_t) addrlen, addrtype);
3704 #else
3705         DIE(no_sock_func, "gethostbyaddr");
3706 #endif
3707     }
3708     else
3709 #ifdef HAS_GETHOSTENT
3710         hent = PerlSock_gethostent();
3711 #else
3712         DIE(no_sock_func, "gethostent");
3713 #endif
3714
3715 #ifdef HOST_NOT_FOUND
3716     if (!hent)
3717         STATUS_NATIVE_SET(h_errno);
3718 #endif
3719
3720     if (GIMME != G_ARRAY) {
3721         PUSHs(sv = sv_newmortal());
3722         if (hent) {
3723             if (which == OP_GHBYNAME) {
3724                 if (hent->h_addr)
3725                     sv_setpvn(sv, hent->h_addr, hent->h_length);
3726             }
3727             else
3728                 sv_setpv(sv, (char*)hent->h_name);
3729         }
3730         RETURN;
3731     }
3732
3733     if (hent) {
3734         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
3735         sv_setpv(sv, (char*)hent->h_name);
3736         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
3737         for (elem = hent->h_aliases; elem && *elem; elem++) {
3738             sv_catpv(sv, *elem);
3739             if (elem[1])
3740                 sv_catpvn(sv, " ", 1);
3741         }
3742         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
3743         sv_setiv(sv, (IV)hent->h_addrtype);
3744         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
3745         len = hent->h_length;
3746         sv_setiv(sv, (IV)len);
3747 #ifdef h_addr
3748         for (elem = hent->h_addr_list; elem && *elem; elem++) {
3749             XPUSHs(sv = sv_mortalcopy(&PL_sv_no));
3750             sv_setpvn(sv, *elem, len);
3751         }
3752 #else
3753         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
3754         if (hent->h_addr)
3755             sv_setpvn(sv, hent->h_addr, len);
3756 #endif /* h_addr */
3757     }
3758     RETURN;
3759 #else
3760     DIE(no_sock_func, "gethostent");
3761 #endif
3762 }
3763
3764 PP(pp_gnbyname)
3765 {
3766 #ifdef HAS_GETNETBYNAME
3767     return pp_gnetent(ARGS);
3768 #else
3769     DIE(no_sock_func, "getnetbyname");
3770 #endif
3771 }
3772
3773 PP(pp_gnbyaddr)
3774 {
3775 #ifdef HAS_GETNETBYADDR
3776     return pp_gnetent(ARGS);
3777 #else
3778     DIE(no_sock_func, "getnetbyaddr");
3779 #endif
3780 }
3781
3782 PP(pp_gnetent)
3783 {
3784     djSP;
3785 #if defined(HAS_GETNETBYNAME) || defined(HAS_GETNETBYADDR) || defined(HAS_GETNETENT)
3786     I32 which = PL_op->op_type;
3787     register char **elem;
3788     register SV *sv;
3789 #ifndef HAS_GETNET_PROTOS /* XXX Do we need individual probes? */
3790     struct netent *PerlSock_getnetbyaddr(Netdb_net_t, int);
3791     struct netent *PerlSock_getnetbyname(Netdb_name_t);
3792     struct netent *PerlSock_getnetent(void);
3793 #endif
3794     struct netent *nent;
3795
3796     if (which == OP_GNBYNAME)
3797 #ifdef HAS_GETNETBYNAME
3798         nent = PerlSock_getnetbyname(POPp);
3799 #else
3800         DIE(no_sock_func, "getnetbyname");
3801 #endif
3802     else if (which == OP_GNBYADDR) {
3803 #ifdef HAS_GETNETBYADDR
3804         int addrtype = POPi;
3805         Netdb_net_t addr = (Netdb_net_t) U_L(POPn);
3806         nent = PerlSock_getnetbyaddr(addr, addrtype);
3807 #else
3808         DIE(no_sock_func, "getnetbyaddr");
3809 #endif
3810     }
3811     else
3812 #ifdef HAS_GETNETENT
3813         nent = PerlSock_getnetent();
3814 #else
3815         DIE(no_sock_func, "getnetent");
3816 #endif
3817
3818     EXTEND(SP, 4);
3819     if (GIMME != G_ARRAY) {
3820         PUSHs(sv = sv_newmortal());
3821         if (nent) {
3822             if (which == OP_GNBYNAME)
3823                 sv_setiv(sv, (IV)nent->n_net);
3824             else
3825                 sv_setpv(sv, nent->n_name);
3826         }
3827         RETURN;
3828     }
3829
3830     if (nent) {
3831         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
3832         sv_setpv(sv, nent->n_name);
3833         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
3834         for (elem = nent->n_aliases; elem && *elem; elem++) {
3835             sv_catpv(sv, *elem);
3836             if (elem[1])
3837                 sv_catpvn(sv, " ", 1);
3838         }
3839         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
3840         sv_setiv(sv, (IV)nent->n_addrtype);
3841         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
3842         sv_setiv(sv, (IV)nent->n_net);
3843     }
3844
3845     RETURN;
3846 #else
3847     DIE(no_sock_func, "getnetent");
3848 #endif
3849 }
3850
3851 PP(pp_gpbyname)
3852 {
3853 #ifdef HAS_GETPROTOBYNAME
3854     return pp_gprotoent(ARGS);
3855 #else
3856     DIE(no_sock_func, "getprotobyname");
3857 #endif
3858 }
3859
3860 PP(pp_gpbynumber)
3861 {
3862 #ifdef HAS_GETPROTOBYNUMBER
3863     return pp_gprotoent(ARGS);
3864 #else
3865     DIE(no_sock_func, "getprotobynumber");
3866 #endif
3867 }
3868
3869 PP(pp_gprotoent)
3870 {
3871     djSP;
3872 #if defined(HAS_GETPROTOBYNAME) || defined(HAS_GETPROTOBYNUMBER) || defined(HAS_GETPROTOENT)
3873     I32 which = PL_op->op_type;
3874     register char **elem;
3875     register SV *sv;  
3876 #ifndef HAS_GETPROTO_PROTOS /* XXX Do we need individual probes? */
3877     struct protoent *PerlSock_getprotobyname(Netdb_name_t);
3878     struct protoent *PerlSock_getprotobynumber(int);
3879     struct protoent *PerlSock_getprotoent(void);
3880 #endif
3881     struct protoent *pent;
3882
3883     if (which == OP_GPBYNAME)
3884 #ifdef HAS_GETPROTOBYNAME
3885         pent = PerlSock_getprotobyname(POPp);
3886 #else
3887         DIE(no_sock_func, "getprotobyname");
3888 #endif
3889     else if (which == OP_GPBYNUMBER)
3890 #ifdef HAS_GETPROTOBYNUMBER
3891         pent = PerlSock_getprotobynumber(POPi);
3892 #else
3893     DIE(no_sock_func, "getprotobynumber");
3894 #endif
3895     else
3896 #ifdef HAS_GETPROTOENT
3897         pent = PerlSock_getprotoent();
3898 #else
3899         DIE(no_sock_func, "getprotoent");
3900 #endif
3901
3902     EXTEND(SP, 3);
3903     if (GIMME != G_ARRAY) {
3904         PUSHs(sv = sv_newmortal());
3905         if (pent) {
3906             if (which == OP_GPBYNAME)
3907                 sv_setiv(sv, (IV)pent->p_proto);
3908             else
3909                 sv_setpv(sv, pent->p_name);
3910         }
3911         RETURN;
3912     }
3913
3914     if (pent) {
3915         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
3916         sv_setpv(sv, pent->p_name);
3917         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
3918         for (elem = pent->p_aliases; elem && *elem; elem++) {
3919             sv_catpv(sv, *elem);
3920             if (elem[1])
3921                 sv_catpvn(sv, " ", 1);
3922         }
3923         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
3924         sv_setiv(sv, (IV)pent->p_proto);
3925     }
3926
3927     RETURN;
3928 #else
3929     DIE(no_sock_func, "getprotoent");
3930 #endif
3931 }
3932
3933 PP(pp_gsbyname)
3934 {
3935 #ifdef HAS_GETSERVBYNAME
3936     return pp_gservent(ARGS);
3937 #else
3938     DIE(no_sock_func, "getservbyname");
3939 #endif
3940 }
3941
3942 PP(pp_gsbyport)
3943 {
3944 #ifdef HAS_GETSERVBYPORT
3945     return pp_gservent(ARGS);
3946 #else
3947     DIE(no_sock_func, "getservbyport");
3948 #endif
3949 }
3950
3951 PP(pp_gservent)
3952 {
3953     djSP;
3954 #if defined(HAS_GETSERVBYNAME) || defined(HAS_GETSERVBYPORT) || defined(HAS_GETSERVENT)
3955     I32 which = PL_op->op_type;
3956     register char **elem;
3957     register SV *sv;
3958 #ifndef HAS_GETSERV_PROTOS /* XXX Do we need individual probes? */
3959     struct servent *PerlSock_getservbyname(Netdb_name_t, Netdb_name_t);
3960     struct servent *PerlSock_getservbyport(int, Netdb_name_t);
3961     struct servent *PerlSock_getservent(void);
3962 #endif
3963     struct servent *sent;
3964
3965     if (which == OP_GSBYNAME) {
3966 #ifdef HAS_GETSERVBYNAME
3967         char *proto = POPp;
3968         char *name = POPp;
3969
3970         if (proto && !*proto)
3971             proto = Nullch;
3972
3973         sent = PerlSock_getservbyname(name, proto);
3974 #else
3975         DIE(no_sock_func, "getservbyname");
3976 #endif
3977     }
3978     else if (which == OP_GSBYPORT) {
3979 #ifdef HAS_GETSERVBYPORT
3980         char *proto = POPp;
3981         unsigned short port = POPu;
3982
3983 #ifdef HAS_HTONS
3984         port = PerlSock_htons(port);
3985 #endif
3986         sent = PerlSock_getservbyport(port, proto);
3987 #else
3988         DIE(no_sock_func, "getservbyport");
3989 #endif
3990     }
3991     else
3992 #ifdef HAS_GETSERVENT
3993         sent = PerlSock_getservent();
3994 #else
3995         DIE(no_sock_func, "getservent");
3996 #endif
3997
3998     EXTEND(SP, 4);
3999     if (GIMME != G_ARRAY) {
4000         PUSHs(sv = sv_newmortal());
4001         if (sent) {
4002             if (which == OP_GSBYNAME) {
4003 #ifdef HAS_NTOHS
4004                 sv_setiv(sv, (IV)PerlSock_ntohs(sent->s_port));
4005 #else
4006                 sv_setiv(sv, (IV)(sent->s_port));
4007 #endif
4008             }
4009             else
4010                 sv_setpv(sv, sent->s_name);
4011         }
4012         RETURN;
4013     }
4014
4015     if (sent) {
4016         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
4017         sv_setpv(sv, sent->s_name);
4018         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
4019         for (elem = sent->s_aliases; elem && *elem; elem++) {
4020             sv_catpv(sv, *elem);
4021             if (elem[1])
4022                 sv_catpvn(sv, " ", 1);
4023         }
4024         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
4025 #ifdef HAS_NTOHS
4026         sv_setiv(sv, (IV)PerlSock_ntohs(sent->s_port));
4027 #else
4028         sv_setiv(sv, (IV)(sent->s_port));
4029 #endif
4030         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
4031         sv_setpv(sv, sent->s_proto);
4032     }
4033
4034     RETURN;
4035 #else
4036     DIE(no_sock_func, "getservent");
4037 #endif
4038 }
4039
4040 PP(pp_shostent)
4041 {
4042     djSP;
4043 #ifdef HAS_SETHOSTENT
4044     PerlSock_sethostent(TOPi);
4045     RETSETYES;
4046 #else
4047     DIE(no_sock_func, "sethostent");
4048 #endif
4049 }
4050
4051 PP(pp_snetent)
4052 {
4053     djSP;
4054 #ifdef HAS_SETNETENT
4055     PerlSock_setnetent(TOPi);
4056     RETSETYES;
4057 #else
4058     DIE(no_sock_func, "setnetent");
4059 #endif
4060 }
4061
4062 PP(pp_sprotoent)
4063 {
4064     djSP;
4065 #ifdef HAS_SETPROTOENT
4066     PerlSock_setprotoent(TOPi);
4067     RETSETYES;
4068 #else
4069     DIE(no_sock_func, "setprotoent");
4070 #endif
4071 }
4072
4073 PP(pp_sservent)
4074 {
4075     djSP;
4076 #ifdef HAS_SETSERVENT
4077     PerlSock_setservent(TOPi);
4078     RETSETYES;
4079 #else
4080     DIE(no_sock_func, "setservent");
4081 #endif
4082 }
4083
4084 PP(pp_ehostent)
4085 {
4086     djSP;
4087 #ifdef HAS_ENDHOSTENT
4088     PerlSock_endhostent();
4089     EXTEND(SP,1);
4090     RETPUSHYES;
4091 #else
4092     DIE(no_sock_func, "endhostent");
4093 #endif
4094 }
4095
4096 PP(pp_enetent)
4097 {
4098     djSP;
4099 #ifdef HAS_ENDNETENT
4100     PerlSock_endnetent();
4101     EXTEND(SP,1);
4102     RETPUSHYES;
4103 #else
4104     DIE(no_sock_func, "endnetent");
4105 #endif
4106 }
4107
4108 PP(pp_eprotoent)
4109 {
4110     djSP;
4111 #ifdef HAS_ENDPROTOENT
4112     PerlSock_endprotoent();
4113     EXTEND(SP,1);
4114     RETPUSHYES;
4115 #else
4116     DIE(no_sock_func, "endprotoent");
4117 #endif
4118 }
4119
4120 PP(pp_eservent)
4121 {
4122     djSP;
4123 #ifdef HAS_ENDSERVENT
4124     PerlSock_endservent();
4125     EXTEND(SP,1);
4126     RETPUSHYES;
4127 #else
4128     DIE(no_sock_func, "endservent");
4129 #endif
4130 }
4131
4132 PP(pp_gpwnam)
4133 {
4134 #ifdef HAS_PASSWD
4135     return pp_gpwent(ARGS);
4136 #else
4137     DIE(no_func, "getpwnam");
4138 #endif
4139 }
4140
4141 PP(pp_gpwuid)
4142 {
4143 #ifdef HAS_PASSWD
4144     return pp_gpwent(ARGS);
4145 #else
4146     DIE(no_func, "getpwuid");
4147 #endif
4148 }
4149
4150 PP(pp_gpwent)
4151 {
4152     djSP;
4153 #if defined(HAS_PASSWD) && defined(HAS_GETPWENT)
4154     I32 which = PL_op->op_type;
4155     register SV *sv;
4156     struct passwd *pwent;
4157
4158     if (which == OP_GPWNAM)
4159         pwent = getpwnam(POPp);
4160     else if (which == OP_GPWUID)
4161         pwent = getpwuid(POPi);
4162     else
4163         pwent = (struct passwd *)getpwent();
4164
4165     EXTEND(SP, 10);
4166     if (GIMME != G_ARRAY) {
4167         PUSHs(sv = sv_newmortal());
4168         if (pwent) {
4169             if (which == OP_GPWNAM)
4170                 sv_setiv(sv, (IV)pwent->pw_uid);
4171             else
4172                 sv_setpv(sv, pwent->pw_name);
4173         }
4174         RETURN;
4175     }
4176
4177     if (pwent) {
4178         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
4179         sv_setpv(sv, pwent->pw_name);
4180
4181         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
4182 #ifdef PWPASSWD
4183         sv_setpv(sv, pwent->pw_passwd);
4184 #endif
4185
4186         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
4187         sv_setiv(sv, (IV)pwent->pw_uid);
4188
4189         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
4190         sv_setiv(sv, (IV)pwent->pw_gid);
4191
4192         /* pw_change, pw_quota, and pw_age are mutually exclusive. */
4193         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
4194 #ifdef PWCHANGE
4195         sv_setiv(sv, (IV)pwent->pw_change);
4196 #else
4197 #   ifdef PWQUOTA
4198         sv_setiv(sv, (IV)pwent->pw_quota);
4199 #   else
4200 #       ifdef PWAGE
4201         sv_setpv(sv, pwent->pw_age);
4202 #       endif
4203 #   endif
4204 #endif
4205
4206         /* pw_class and pw_comment are mutually exclusive. */
4207         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
4208 #ifdef PWCLASS
4209         sv_setpv(sv, pwent->pw_class);
4210 #else
4211 #   ifdef PWCOMMENT
4212         sv_setpv(sv, pwent->pw_comment);
4213 #   endif
4214 #endif
4215
4216         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
4217 #ifdef PWGECOS
4218         sv_setpv(sv, pwent->pw_gecos);
4219 #endif
4220 #ifndef INCOMPLETE_TAINTS
4221         /* pw_gecos is tainted because user himself can diddle with it. */
4222         SvTAINTED_on(sv);
4223 #endif
4224
4225         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
4226         sv_setpv(sv, pwent->pw_dir);
4227
4228         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
4229         sv_setpv(sv, pwent->pw_shell);
4230
4231 #ifdef PWEXPIRE
4232         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
4233         sv_setiv(sv, (IV)pwent->pw_expire);
4234 #endif
4235     }
4236     RETURN;
4237 #else
4238     DIE(no_func, "getpwent");
4239 #endif
4240 }
4241
4242 PP(pp_spwent)
4243 {
4244     djSP;
4245 #if defined(HAS_PASSWD) && defined(HAS_SETPWENT) && !defined(CYGWIN32)
4246     setpwent();
4247     RETPUSHYES;
4248 #else
4249     DIE(no_func, "setpwent");
4250 #endif
4251 }
4252
4253 PP(pp_epwent)
4254 {
4255     djSP;
4256 #if defined(HAS_PASSWD) && defined(HAS_ENDPWENT)
4257     endpwent();
4258     RETPUSHYES;
4259 #else
4260     DIE(no_func, "endpwent");
4261 #endif
4262 }
4263
4264 PP(pp_ggrnam)
4265 {
4266 #ifdef HAS_GROUP
4267     return pp_ggrent(ARGS);
4268 #else
4269     DIE(no_func, "getgrnam");
4270 #endif
4271 }
4272
4273 PP(pp_ggrgid)
4274 {
4275 #ifdef HAS_GROUP
4276     return pp_ggrent(ARGS);
4277 #else
4278     DIE(no_func, "getgrgid");
4279 #endif
4280 }
4281
4282 PP(pp_ggrent)
4283 {
4284     djSP;
4285 #if defined(HAS_GROUP) && defined(HAS_GETGRENT)
4286     I32 which = PL_op->op_type;
4287     register char **elem;
4288     register SV *sv;
4289     struct group *grent;
4290
4291     if (which == OP_GGRNAM)
4292         grent = (struct group *)getgrnam(POPp);
4293     else if (which == OP_GGRGID)
4294         grent = (struct group *)getgrgid(POPi);
4295     else
4296         grent = (struct group *)getgrent();
4297
4298     EXTEND(SP, 4);
4299     if (GIMME != G_ARRAY) {
4300         PUSHs(sv = sv_newmortal());
4301         if (grent) {
4302             if (which == OP_GGRNAM)
4303                 sv_setiv(sv, (IV)grent->gr_gid);
4304             else
4305                 sv_setpv(sv, grent->gr_name);
4306         }
4307         RETURN;
4308     }
4309
4310     if (grent) {
4311         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
4312         sv_setpv(sv, grent->gr_name);
4313
4314         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
4315 #ifdef GRPASSWD
4316         sv_setpv(sv, grent->gr_passwd);
4317 #endif
4318
4319         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
4320         sv_setiv(sv, (IV)grent->gr_gid);
4321
4322         PUSHs(sv = sv_mortalcopy(&PL_sv_no));
4323         for (elem = grent->gr_mem; elem && *elem; elem++) {
4324             sv_catpv(sv, *elem);
4325             if (elem[1])
4326                 sv_catpvn(sv, " ", 1);
4327         }
4328     }
4329
4330     RETURN;
4331 #else
4332     DIE(no_func, "getgrent");
4333 #endif
4334 }
4335
4336 PP(pp_sgrent)
4337 {
4338     djSP;
4339 #if defined(HAS_GROUP) && defined(HAS_SETGRENT)
4340     setgrent();
4341     RETPUSHYES;
4342 #else
4343     DIE(no_func, "setgrent");
4344 #endif
4345 }
4346
4347 PP(pp_egrent)
4348 {
4349     djSP;
4350 #if defined(HAS_GROUP) && defined(HAS_ENDGRENT)
4351     endgrent();
4352     RETPUSHYES;
4353 #else
4354     DIE(no_func, "endgrent");
4355 #endif
4356 }
4357
4358 PP(pp_getlogin)
4359 {
4360     djSP; dTARGET;
4361 #ifdef HAS_GETLOGIN
4362     char *tmps;
4363     EXTEND(SP, 1);
4364     if (!(tmps = PerlProc_getlogin()))
4365         RETPUSHUNDEF;
4366     PUSHp(tmps, strlen(tmps));
4367     RETURN;
4368 #else
4369     DIE(no_func, "getlogin");
4370 #endif
4371 }
4372
4373 /* Miscellaneous. */
4374
4375 PP(pp_syscall)
4376 {
4377 #ifdef HAS_SYSCALL
4378     djSP; dMARK; dORIGMARK; dTARGET;
4379     register I32 items = SP - MARK;
4380     unsigned long a[20];
4381     register I32 i = 0;
4382     I32 retval = -1;
4383     MAGIC *mg;
4384
4385     if (PL_tainting) {
4386         while (++MARK <= SP) {
4387             if (SvTAINTED(*MARK)) {
4388                 TAINT;
4389                 break;
4390             }
4391         }
4392         MARK = ORIGMARK;
4393         TAINT_PROPER("syscall");
4394     }
4395
4396     /* This probably won't work on machines where sizeof(long) != sizeof(int)
4397      * or where sizeof(long) != sizeof(char*).  But such machines will
4398      * not likely have syscall implemented either, so who cares?
4399      */
4400     while (++MARK <= SP) {
4401         if (SvNIOK(*MARK) || !i)
4402             a[i++] = SvIV(*MARK);
4403         else if (*MARK == &PL_sv_undef)
4404             a[i++] = 0;
4405         else 
4406             a[i++] = (unsigned long)SvPV_force(*MARK, PL_na);
4407         if (i > 15)
4408             break;
4409     }
4410     switch (items) {
4411     default:
4412         DIE("Too many args to syscall");
4413     case 0:
4414         DIE("Too few args to syscall");
4415     case 1:
4416         retval = syscall(a[0]);
4417         break;
4418     case 2:
4419         retval = syscall(a[0],a[1]);
4420         break;
4421     case 3:
4422         retval = syscall(a[0],a[1],a[2]);
4423         break;
4424     case 4:
4425         retval = syscall(a[0],a[1],a[2],a[3]);
4426         break;
4427     case 5:
4428         retval = syscall(a[0],a[1],a[2],a[3],a[4]);
4429         break;
4430     case 6:
4431         retval = syscall(a[0],a[1],a[2],a[3],a[4],a[5]);
4432         break;
4433     case 7:
4434         retval = syscall(a[0],a[1],a[2],a[3],a[4],a[5],a[6]);
4435         break;
4436     case 8:
4437         retval = syscall(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7]);
4438         break;
4439 #ifdef atarist
4440     case 9:
4441         retval = syscall(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8]);
4442         break;
4443     case 10:
4444         retval = syscall(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9]);
4445         break;
4446     case 11:
4447         retval = syscall(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9],
4448           a[10]);
4449         break;
4450     case 12:
4451         retval = syscall(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9],
4452           a[10],a[11]);
4453         break;
4454     case 13:
4455         retval = syscall(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9],
4456           a[10],a[11],a[12]);
4457         break;
4458     case 14:
4459         retval = syscall(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9],
4460           a[10],a[11],a[12],a[13]);
4461         break;
4462 #endif /* atarist */
4463     }
4464     SP = ORIGMARK;
4465     PUSHi(retval);
4466     RETURN;
4467 #else
4468     DIE(no_func, "syscall");
4469 #endif
4470 }
4471
4472 #ifdef FCNTL_EMULATE_FLOCK
4473  
4474 /*  XXX Emulate flock() with fcntl().
4475     What's really needed is a good file locking module.
4476 */
4477
4478 static int
4479 fcntl_emulate_flock(int fd, int operation)
4480 {
4481     struct flock flock;
4482  
4483     switch (operation & ~LOCK_NB) {
4484     case LOCK_SH:
4485         flock.l_type = F_RDLCK;
4486         break;
4487     case LOCK_EX:
4488         flock.l_type = F_WRLCK;
4489         break;
4490     case LOCK_UN:
4491         flock.l_type = F_UNLCK;
4492         break;
4493     default:
4494         errno = EINVAL;
4495         return -1;
4496     }
4497     flock.l_whence = SEEK_SET;
4498     flock.l_start = flock.l_len = 0L;
4499  
4500     return fcntl(fd, (operation & LOCK_NB) ? F_SETLK : F_SETLKW, &flock);
4501 }
4502
4503 #endif /* FCNTL_EMULATE_FLOCK */
4504
4505 #ifdef LOCKF_EMULATE_FLOCK
4506
4507 /*  XXX Emulate flock() with lockf().  This is just to increase
4508     portability of scripts.  The calls are not completely
4509     interchangeable.  What's really needed is a good file
4510     locking module.
4511 */
4512
4513 /*  The lockf() constants might have been defined in <unistd.h>.
4514     Unfortunately, <unistd.h> causes troubles on some mixed
4515     (BSD/POSIX) systems, such as SunOS 4.1.3.
4516
4517    Further, the lockf() constants aren't POSIX, so they might not be
4518    visible if we're compiling with _POSIX_SOURCE defined.  Thus, we'll
4519    just stick in the SVID values and be done with it.  Sigh.
4520 */
4521
4522 # ifndef F_ULOCK
4523 #  define F_ULOCK       0       /* Unlock a previously locked region */
4524 # endif
4525 # ifndef F_LOCK
4526 #  define F_LOCK        1       /* Lock a region for exclusive use */
4527 # endif
4528 # ifndef F_TLOCK
4529 #  define F_TLOCK       2       /* Test and lock a region for exclusive use */
4530 # endif
4531 # ifndef F_TEST
4532 #  define F_TEST        3       /* Test a region for other processes locks */
4533 # endif
4534
4535 static int
4536 lockf_emulate_flock (fd, operation)
4537 int fd;
4538 int operation;
4539 {
4540     int i;
4541     int save_errno;
4542     Off_t pos;
4543
4544     /* flock locks entire file so for lockf we need to do the same      */
4545     save_errno = errno;
4546     pos = PerlLIO_lseek(fd, (Off_t)0, SEEK_CUR);    /* get pos to restore later */
4547     if (pos > 0)        /* is seekable and needs to be repositioned     */
4548         if (PerlLIO_lseek(fd, (Off_t)0, SEEK_SET) < 0)
4549             pos = -1;   /* seek failed, so don't seek back afterwards   */
4550     errno = save_errno;
4551
4552     switch (operation) {
4553
4554         /* LOCK_SH - get a shared lock */
4555         case LOCK_SH:
4556         /* LOCK_EX - get an exclusive lock */
4557         case LOCK_EX:
4558             i = lockf (fd, F_LOCK, 0);
4559             break;
4560
4561         /* LOCK_SH|LOCK_NB - get a non-blocking shared lock */
4562         case LOCK_SH|LOCK_NB:
4563         /* LOCK_EX|LOCK_NB - get a non-blocking exclusive lock */
4564         case LOCK_EX|LOCK_NB:
4565             i = lockf (fd, F_TLOCK, 0);
4566             if (i == -1)
4567                 if ((errno == EAGAIN) || (errno == EACCES))
4568                     errno = EWOULDBLOCK;
4569             break;
4570
4571         /* LOCK_UN - unlock (non-blocking is a no-op) */
4572         case LOCK_UN:
4573         case LOCK_UN|LOCK_NB:
4574             i = lockf (fd, F_ULOCK, 0);
4575             break;
4576
4577         /* Default - can't decipher operation */
4578         default:
4579             i = -1;
4580             errno = EINVAL;
4581             break;
4582     }
4583
4584     if (pos > 0)      /* need to restore position of the handle */
4585         PerlLIO_lseek(fd, pos, SEEK_SET);       /* ignore error here    */
4586
4587     return (i);
4588 }
4589
4590 #endif /* LOCKF_EMULATE_FLOCK */