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