ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/staticperl/perl/pp_sys.c
Revision: 1.1
Committed: Thu Jun 30 14:26:42 2005 UTC (21 years, 3 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: PERL-5-8-7, HEAD
Branch point for: PERL
Log Message:
*** empty log message ***

File Contents

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