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