summaryrefslogtreecommitdiffstats
path: root/contrib/perl5/pp_sys.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/perl5/pp_sys.c')
-rw-r--r--contrib/perl5/pp_sys.c5382
1 files changed, 0 insertions, 5382 deletions
diff --git a/contrib/perl5/pp_sys.c b/contrib/perl5/pp_sys.c
deleted file mode 100644
index 8423bd0..0000000
--- a/contrib/perl5/pp_sys.c
+++ /dev/null
@@ -1,5382 +0,0 @@
-/* pp_sys.c
- *
- * Copyright (c) 1991-2001, Larry Wall
- *
- * You may distribute under the terms of either the GNU General Public
- * License or the Artistic License, as specified in the README file.
- *
- */
-
-/*
- * But only a short way ahead its floor and the walls on either side were
- * cloven by a great fissure, out of which the red glare came, now leaping
- * up, now dying down into darkness; and all the while far below there was
- * a rumour and a trouble as of great engines throbbing and labouring.
- */
-
-#include "EXTERN.h"
-#define PERL_IN_PP_SYS_C
-#include "perl.h"
-
-#ifdef I_SHADOW
-/* Shadow password support for solaris - pdo@cs.umd.edu
- * Not just Solaris: at least HP-UX, IRIX, Linux.
- * The API is from SysV.
- *
- * There are at least two more shadow interfaces,
- * see the comments in pp_gpwent().
- *
- * --jhi */
-# ifdef __hpux__
-/* There is a MAXINT coming from <shadow.h> <- <hpsecurity.h> <- <values.h>
- * and another MAXINT from "perl.h" <- <sys/param.h>. */
-# undef MAXINT
-# endif
-# include <shadow.h>
-#endif
-
-#ifdef HAS_SYSCALL
-#ifdef __cplusplus
-extern "C" int syscall(unsigned long,...);
-#endif
-#endif
-
-#ifdef I_SYS_WAIT
-# include <sys/wait.h>
-#endif
-
-#ifdef I_SYS_RESOURCE
-# include <sys/resource.h>
-#endif
-
-#ifdef HAS_SELECT
-# ifdef I_SYS_SELECT
-# include <sys/select.h>
-# endif
-#endif
-
-/* XXX Configure test needed.
- h_errno might not be a simple 'int', especially for multi-threaded
- applications, see "extern int errno in perl.h". Creating such
- a test requires taking into account the differences between
- compiling multithreaded and singlethreaded ($ccflags et al).
- HOST_NOT_FOUND is typically defined in <netdb.h>.
-*/
-#if defined(HOST_NOT_FOUND) && !defined(h_errno) && !defined(__CYGWIN__)
-extern int h_errno;
-#endif
-
-#ifdef HAS_PASSWD
-# ifdef I_PWD
-# include <pwd.h>
-# else
- struct passwd *getpwnam (char *);
- struct passwd *getpwuid (Uid_t);
-# endif
-# ifdef HAS_GETPWENT
- struct passwd *getpwent (void);
-# endif
-#endif
-
-#ifdef HAS_GROUP
-# ifdef I_GRP
-# include <grp.h>
-# else
- struct group *getgrnam (char *);
- struct group *getgrgid (Gid_t);
-# endif
-# ifdef HAS_GETGRENT
- struct group *getgrent (void);
-# endif
-#endif
-
-#ifdef I_UTIME
-# if defined(_MSC_VER) || defined(__MINGW32__)
-# include <sys/utime.h>
-# else
-# include <utime.h>
-# endif
-#endif
-
-/* Put this after #includes because fork and vfork prototypes may conflict. */
-#ifndef HAS_VFORK
-# define vfork fork
-#endif
-
-#ifdef HAS_CHSIZE
-# ifdef my_chsize /* Probably #defined to Perl_my_chsize in embed.h */
-# undef my_chsize
-# endif
-# define my_chsize PerlLIO_chsize
-#endif
-
-#ifdef HAS_FLOCK
-# define FLOCK flock
-#else /* no flock() */
-
- /* fcntl.h might not have been included, even if it exists, because
- the current Configure only sets I_FCNTL if it's needed to pick up
- the *_OK constants. Make sure it has been included before testing
- the fcntl() locking constants. */
-# if defined(HAS_FCNTL) && !defined(I_FCNTL)
-# include <fcntl.h>
-# endif
-
-# if defined(HAS_FCNTL) && defined(FCNTL_CAN_LOCK)
-# define FLOCK fcntl_emulate_flock
-# define FCNTL_EMULATE_FLOCK
-# else /* no flock() or fcntl(F_SETLK,...) */
-# ifdef HAS_LOCKF
-# define FLOCK lockf_emulate_flock
-# define LOCKF_EMULATE_FLOCK
-# endif /* lockf */
-# endif /* no flock() or fcntl(F_SETLK,...) */
-
-# ifdef FLOCK
- static int FLOCK (int, int);
-
- /*
- * These are the flock() constants. Since this sytems doesn't have
- * flock(), the values of the constants are probably not available.
- */
-# ifndef LOCK_SH
-# define LOCK_SH 1
-# endif
-# ifndef LOCK_EX
-# define LOCK_EX 2
-# endif
-# ifndef LOCK_NB
-# define LOCK_NB 4
-# endif
-# ifndef LOCK_UN
-# define LOCK_UN 8
-# endif
-# endif /* emulating flock() */
-
-#endif /* no flock() */
-
-#define ZBTLEN 10
-static char zero_but_true[ZBTLEN + 1] = "0 but true";
-
-#if defined(I_SYS_ACCESS) && !defined(R_OK)
-# include <sys/access.h>
-#endif
-
-#if defined(HAS_FCNTL) && defined(F_SETFD) && !defined(FD_CLOEXEC)
-# define FD_CLOEXEC 1 /* NeXT needs this */
-#endif
-
-#undef PERL_EFF_ACCESS_R_OK /* EFFective uid/gid ACCESS R_OK */
-#undef PERL_EFF_ACCESS_W_OK
-#undef PERL_EFF_ACCESS_X_OK
-
-/* F_OK unused: if stat() cannot find it... */
-
-#if !defined(PERL_EFF_ACCESS_R_OK) && defined(HAS_ACCESS) && defined(EFF_ONLY_OK) && !defined(NO_EFF_ONLY_OK)
- /* Digital UNIX (when the EFF_ONLY_OK gets fixed), UnixWare */
-# define PERL_EFF_ACCESS_R_OK(p) (access((p), R_OK | EFF_ONLY_OK))
-# define PERL_EFF_ACCESS_W_OK(p) (access((p), W_OK | EFF_ONLY_OK))
-# define PERL_EFF_ACCESS_X_OK(p) (access((p), X_OK | EFF_ONLY_OK))
-#endif
-
-#if !defined(PERL_EFF_ACCESS_R_OK) && defined(HAS_EACCESS)
-# ifdef I_SYS_SECURITY
-# include <sys/security.h>
-# endif
-# ifdef ACC_SELF
- /* HP SecureWare */
-# define PERL_EFF_ACCESS_R_OK(p) (eaccess((p), R_OK, ACC_SELF))
-# define PERL_EFF_ACCESS_W_OK(p) (eaccess((p), W_OK, ACC_SELF))
-# define PERL_EFF_ACCESS_X_OK(p) (eaccess((p), X_OK, ACC_SELF))
-# else
- /* SCO */
-# define PERL_EFF_ACCESS_R_OK(p) (eaccess((p), R_OK))
-# define PERL_EFF_ACCESS_W_OK(p) (eaccess((p), W_OK))
-# define PERL_EFF_ACCESS_X_OK(p) (eaccess((p), X_OK))
-# endif
-#endif
-
-#if !defined(PERL_EFF_ACCESS_R_OK) && defined(HAS_ACCESSX) && defined(ACC_SELF)
- /* AIX */
-# define PERL_EFF_ACCESS_R_OK(p) (accessx((p), R_OK, ACC_SELF))
-# define PERL_EFF_ACCESS_W_OK(p) (accessx((p), W_OK, ACC_SELF))
-# define PERL_EFF_ACCESS_X_OK(p) (accessx((p), X_OK, ACC_SELF))
-#endif
-
-#if !defined(PERL_EFF_ACCESS_R_OK) && defined(HAS_ACCESS) \
- && (defined(HAS_SETREUID) || defined(HAS_SETRESUID) \
- || defined(HAS_SETREGID) || defined(HAS_SETRESGID))
-/* The Hard Way. */
-STATIC int
-S_emulate_eaccess(pTHX_ const char* path, Mode_t mode)
-{
- Uid_t ruid = getuid();
- Uid_t euid = geteuid();
- Gid_t rgid = getgid();
- Gid_t egid = getegid();
- int res;
-
- LOCK_CRED_MUTEX;
-#if !defined(HAS_SETREUID) && !defined(HAS_SETRESUID)
- Perl_croak(aTHX_ "switching effective uid is not implemented");
-#else
-#ifdef HAS_SETREUID
- if (setreuid(euid, ruid))
-#else
-#ifdef HAS_SETRESUID
- if (setresuid(euid, ruid, (Uid_t)-1))
-#endif
-#endif
- Perl_croak(aTHX_ "entering effective uid failed");
-#endif
-
-#if !defined(HAS_SETREGID) && !defined(HAS_SETRESGID)
- Perl_croak(aTHX_ "switching effective gid is not implemented");
-#else
-#ifdef HAS_SETREGID
- if (setregid(egid, rgid))
-#else
-#ifdef HAS_SETRESGID
- if (setresgid(egid, rgid, (Gid_t)-1))
-#endif
-#endif
- Perl_croak(aTHX_ "entering effective gid failed");
-#endif
-
- res = access(path, mode);
-
-#ifdef HAS_SETREUID
- if (setreuid(ruid, euid))
-#else
-#ifdef HAS_SETRESUID
- if (setresuid(ruid, euid, (Uid_t)-1))
-#endif
-#endif
- Perl_croak(aTHX_ "leaving effective uid failed");
-
-#ifdef HAS_SETREGID
- if (setregid(rgid, egid))
-#else
-#ifdef HAS_SETRESGID
- if (setresgid(rgid, egid, (Gid_t)-1))
-#endif
-#endif
- Perl_croak(aTHX_ "leaving effective gid failed");
- UNLOCK_CRED_MUTEX;
-
- return res;
-}
-# define PERL_EFF_ACCESS_R_OK(p) (emulate_eaccess((p), R_OK))
-# define PERL_EFF_ACCESS_W_OK(p) (emulate_eaccess((p), W_OK))
-# define PERL_EFF_ACCESS_X_OK(p) (emulate_eaccess((p), X_OK))
-#endif
-
-#if !defined(PERL_EFF_ACCESS_R_OK)
-STATIC int
-S_emulate_eaccess(pTHX_ const char* path, Mode_t mode)
-{
- Perl_croak(aTHX_ "switching effective uid is not implemented");
- /*NOTREACHED*/
- return -1;
-}
-#endif
-
-PP(pp_backtick)
-{
- dSP; dTARGET;
- PerlIO *fp;
- STRLEN n_a;
- char *tmps = POPpx;
- I32 gimme = GIMME_V;
- char *mode = "r";
-
- TAINT_PROPER("``");
- if (PL_op->op_private & OPpOPEN_IN_RAW)
- mode = "rb";
- else if (PL_op->op_private & OPpOPEN_IN_CRLF)
- mode = "rt";
- fp = PerlProc_popen(tmps, mode);
- if (fp) {
- if (gimme == G_VOID) {
- char tmpbuf[256];
- while (PerlIO_read(fp, tmpbuf, sizeof tmpbuf) > 0)
- /*SUPPRESS 530*/
- ;
- }
- else if (gimme == G_SCALAR) {
- sv_setpv(TARG, ""); /* note that this preserves previous buffer */
- while (sv_gets(TARG, fp, SvCUR(TARG)) != Nullch)
- /*SUPPRESS 530*/
- ;
- XPUSHs(TARG);
- SvTAINTED_on(TARG);
- }
- else {
- SV *sv;
-
- for (;;) {
- sv = NEWSV(56, 79);
- if (sv_gets(sv, fp, 0) == Nullch) {
- SvREFCNT_dec(sv);
- break;
- }
- XPUSHs(sv_2mortal(sv));
- if (SvLEN(sv) - SvCUR(sv) > 20) {
- SvLEN_set(sv, SvCUR(sv)+1);
- Renew(SvPVX(sv), SvLEN(sv), char);
- }
- SvTAINTED_on(sv);
- }
- }
- STATUS_NATIVE_SET(PerlProc_pclose(fp));
- TAINT; /* "I believe that this is not gratuitous!" */
- }
- else {
- STATUS_NATIVE_SET(-1);
- if (gimme == G_SCALAR)
- RETPUSHUNDEF;
- }
-
- RETURN;
-}
-
-PP(pp_glob)
-{
- OP *result;
- tryAMAGICunTARGET(iter, -1);
-
- /* Note that we only ever get here if File::Glob fails to load
- * without at the same time croaking, for some reason, or if
- * perl was built with PERL_EXTERNAL_GLOB */
-
- ENTER;
-
-#ifndef VMS
- if (PL_tainting) {
- /*
- * The external globbing program may use things we can't control,
- * so for security reasons we must assume the worst.
- */
- TAINT;
- taint_proper(PL_no_security, "glob");
- }
-#endif /* !VMS */
-
- SAVESPTR(PL_last_in_gv); /* We don't want this to be permanent. */
- PL_last_in_gv = (GV*)*PL_stack_sp--;
-
- SAVESPTR(PL_rs); /* This is not permanent, either. */
- PL_rs = sv_2mortal(newSVpvn("\000", 1));
-#ifndef DOSISH
-#ifndef CSH
- *SvPVX(PL_rs) = '\n';
-#endif /* !CSH */
-#endif /* !DOSISH */
-
- result = do_readline();
- LEAVE;
- return result;
-}
-
-#if 0 /* XXX never used! */
-PP(pp_indread)
-{
- STRLEN n_a;
- PL_last_in_gv = gv_fetchpv(SvPVx(GvSV((GV*)(*PL_stack_sp--)), n_a), TRUE,SVt_PVIO);
- return do_readline();
-}
-#endif
-
-PP(pp_rcatline)
-{
- PL_last_in_gv = cGVOP_gv;
- return do_readline();
-}
-
-PP(pp_warn)
-{
- dSP; dMARK;
- SV *tmpsv;
- char *tmps;
- STRLEN len;
- if (SP - MARK != 1) {
- dTARGET;
- do_join(TARG, &PL_sv_no, MARK, SP);
- tmpsv = TARG;
- SP = MARK + 1;
- }
- else {
- tmpsv = TOPs;
- }
- tmps = SvPV(tmpsv, len);
- if (!tmps || !len) {
- SV *error = ERRSV;
- (void)SvUPGRADE(error, SVt_PV);
- if (SvPOK(error) && SvCUR(error))
- sv_catpv(error, "\t...caught");
- tmpsv = error;
- tmps = SvPV(tmpsv, len);
- }
- if (!tmps || !len)
- tmpsv = sv_2mortal(newSVpvn("Warning: something's wrong", 26));
-
- Perl_warn(aTHX_ "%"SVf, tmpsv);
- RETSETYES;
-}
-
-PP(pp_die)
-{
- dSP; dMARK;
- char *tmps;
- SV *tmpsv;
- STRLEN len;
- bool multiarg = 0;
- if (SP - MARK != 1) {
- dTARGET;
- do_join(TARG, &PL_sv_no, MARK, SP);
- tmpsv = TARG;
- tmps = SvPV(tmpsv, len);
- multiarg = 1;
- SP = MARK + 1;
- }
- else {
- tmpsv = TOPs;
- tmps = SvROK(tmpsv) ? Nullch : SvPV(tmpsv, len);
- }
- if (!tmps || !len) {
- SV *error = ERRSV;
- (void)SvUPGRADE(error, SVt_PV);
- if (multiarg ? SvROK(error) : SvROK(tmpsv)) {
- if (!multiarg)
- SvSetSV(error,tmpsv);
- else if (sv_isobject(error)) {
- HV *stash = SvSTASH(SvRV(error));
- GV *gv = gv_fetchmethod(stash, "PROPAGATE");
- if (gv) {
- SV *file = sv_2mortal(newSVpv(CopFILE(PL_curcop),0));
- SV *line = sv_2mortal(newSVuv(CopLINE(PL_curcop)));
- EXTEND(SP, 3);
- PUSHMARK(SP);
- PUSHs(error);
- PUSHs(file);
- PUSHs(line);
- PUTBACK;
- call_sv((SV*)GvCV(gv),
- G_SCALAR|G_EVAL|G_KEEPERR);
- sv_setsv(error,*PL_stack_sp--);
- }
- }
- DIE(aTHX_ Nullch);
- }
- else {
- if (SvPOK(error) && SvCUR(error))
- sv_catpv(error, "\t...propagated");
- tmpsv = error;
- tmps = SvPV(tmpsv, len);
- }
- }
- if (!tmps || !len)
- tmpsv = sv_2mortal(newSVpvn("Died", 4));
-
- DIE(aTHX_ "%"SVf, tmpsv);
-}
-
-/* I/O. */
-
-PP(pp_open)
-{
- dSP; dTARGET;
- GV *gv;
- SV *sv;
- SV *name = Nullsv;
- I32 have_name = 0;
- char *tmps;
- STRLEN len;
- MAGIC *mg;
-
- if (MAXARG > 2) {
- name = POPs;
- have_name = 1;
- }
- if (MAXARG > 1)
- sv = POPs;
- if (!isGV(TOPs))
- DIE(aTHX_ PL_no_usym, "filehandle");
- if (MAXARG <= 1)
- sv = GvSV(TOPs);
- gv = (GV*)POPs;
- if (!isGV(gv))
- DIE(aTHX_ PL_no_usym, "filehandle");
- if (GvIOp(gv))
- IoFLAGS(GvIOp(gv)) &= ~IOf_UNTAINT;
-
- if ((mg = SvTIED_mg((SV*)gv, 'q'))) {
- PUSHMARK(SP);
- XPUSHs(SvTIED_obj((SV*)gv, mg));
- XPUSHs(sv);
- if (have_name)
- XPUSHs(name);
- PUTBACK;
- ENTER;
- call_method("OPEN", G_SCALAR);
- LEAVE;
- SPAGAIN;
- RETURN;
- }
-
- tmps = SvPV(sv, len);
- if (do_open9(gv, tmps, len, FALSE, O_RDONLY, 0, Nullfp, name, have_name))
- PUSHi( (I32)PL_forkprocess );
- else if (PL_forkprocess == 0) /* we are a new child */
- PUSHi(0);
- else
- RETPUSHUNDEF;
- RETURN;
-}
-
-PP(pp_close)
-{
- dSP;
- GV *gv;
- MAGIC *mg;
-
- if (MAXARG == 0)
- gv = PL_defoutgv;
- else
- gv = (GV*)POPs;
-
- if ((mg = SvTIED_mg((SV*)gv, 'q'))) {
- PUSHMARK(SP);
- XPUSHs(SvTIED_obj((SV*)gv, mg));
- PUTBACK;
- ENTER;
- call_method("CLOSE", G_SCALAR);
- LEAVE;
- SPAGAIN;
- RETURN;
- }
- EXTEND(SP, 1);
- PUSHs(boolSV(do_close(gv, TRUE)));
- RETURN;
-}
-
-PP(pp_pipe_op)
-{
- dSP;
-#ifdef HAS_PIPE
- GV *rgv;
- GV *wgv;
- register IO *rstio;
- register IO *wstio;
- int fd[2];
-
- wgv = (GV*)POPs;
- rgv = (GV*)POPs;
-
- if (!rgv || !wgv)
- goto badexit;
-
- if (SvTYPE(rgv) != SVt_PVGV || SvTYPE(wgv) != SVt_PVGV)
- DIE(aTHX_ PL_no_usym, "filehandle");
- rstio = GvIOn(rgv);
- wstio = GvIOn(wgv);
-
- if (IoIFP(rstio))
- do_close(rgv, FALSE);
- if (IoIFP(wstio))
- do_close(wgv, FALSE);
-
- if (PerlProc_pipe(fd) < 0)
- goto badexit;
-
- IoIFP(rstio) = PerlIO_fdopen(fd[0], "r");
- IoOFP(wstio) = PerlIO_fdopen(fd[1], "w");
- IoIFP(wstio) = IoOFP(wstio);
- IoTYPE(rstio) = IoTYPE_RDONLY;
- IoTYPE(wstio) = IoTYPE_WRONLY;
-
- if (!IoIFP(rstio) || !IoOFP(wstio)) {
- if (IoIFP(rstio)) PerlIO_close(IoIFP(rstio));
- else PerlLIO_close(fd[0]);
- if (IoOFP(wstio)) PerlIO_close(IoOFP(wstio));
- else PerlLIO_close(fd[1]);
- goto badexit;
- }
-#if defined(HAS_FCNTL) && defined(F_SETFD)
- fcntl(fd[0],F_SETFD,fd[0] > PL_maxsysfd); /* ensure close-on-exec */
- fcntl(fd[1],F_SETFD,fd[1] > PL_maxsysfd); /* ensure close-on-exec */
-#endif
- RETPUSHYES;
-
-badexit:
- RETPUSHUNDEF;
-#else
- DIE(aTHX_ PL_no_func, "pipe");
-#endif
-}
-
-PP(pp_fileno)
-{
- dSP; dTARGET;
- GV *gv;
- IO *io;
- PerlIO *fp;
- MAGIC *mg;
-
- if (MAXARG < 1)
- RETPUSHUNDEF;
- gv = (GV*)POPs;
-
- if (gv && (mg = SvTIED_mg((SV*)gv, 'q'))) {
- PUSHMARK(SP);
- XPUSHs(SvTIED_obj((SV*)gv, mg));
- PUTBACK;
- ENTER;
- call_method("FILENO", G_SCALAR);
- LEAVE;
- SPAGAIN;
- RETURN;
- }
-
- if (!gv || !(io = GvIO(gv)) || !(fp = IoIFP(io)))
- RETPUSHUNDEF;
- PUSHi(PerlIO_fileno(fp));
- RETURN;
-}
-
-PP(pp_umask)
-{
- dSP; dTARGET;
- Mode_t anum;
-
-#ifdef HAS_UMASK
- if (MAXARG < 1) {
- anum = PerlLIO_umask(0);
- (void)PerlLIO_umask(anum);
- }
- else
- anum = PerlLIO_umask(POPi);
- TAINT_PROPER("umask");
- XPUSHi(anum);
-#else
- /* Only DIE if trying to restrict permissions on `user' (self).
- * Otherwise it's harmless and more useful to just return undef
- * since 'group' and 'other' concepts probably don't exist here. */
- if (MAXARG >= 1 && (POPi & 0700))
- DIE(aTHX_ "umask not implemented");
- XPUSHs(&PL_sv_undef);
-#endif
- RETURN;
-}
-
-PP(pp_binmode)
-{
- dSP;
- GV *gv;
- IO *io;
- PerlIO *fp;
- MAGIC *mg;
- SV *discp = Nullsv;
-
- if (MAXARG < 1)
- RETPUSHUNDEF;
- if (MAXARG > 1)
- discp = POPs;
-
- gv = (GV*)POPs;
-
- if (gv && (mg = SvTIED_mg((SV*)gv, 'q'))) {
- PUSHMARK(SP);
- XPUSHs(SvTIED_obj((SV*)gv, mg));
- if (discp)
- XPUSHs(discp);
- PUTBACK;
- ENTER;
- call_method("BINMODE", G_SCALAR);
- LEAVE;
- SPAGAIN;
- RETURN;
- }
-
- EXTEND(SP, 1);
- if (!(io = GvIO(gv)) || !(fp = IoIFP(io)))
- RETPUSHUNDEF;
-
- if (do_binmode(fp,IoTYPE(io),mode_from_discipline(discp)))
- RETPUSHYES;
- else
- RETPUSHUNDEF;
-}
-
-PP(pp_tie)
-{
- dSP;
- dMARK;
- SV *varsv;
- HV* stash;
- GV *gv;
- SV *sv;
- I32 markoff = MARK - PL_stack_base;
- char *methname;
- int how = 'P';
- U32 items;
- STRLEN n_a;
-
- varsv = *++MARK;
- switch(SvTYPE(varsv)) {
- case SVt_PVHV:
- methname = "TIEHASH";
- break;
- case SVt_PVAV:
- methname = "TIEARRAY";
- break;
- case SVt_PVGV:
- methname = "TIEHANDLE";
- how = 'q';
- break;
- default:
- methname = "TIESCALAR";
- how = 'q';
- break;
- }
- items = SP - MARK++;
- if (sv_isobject(*MARK)) {
- ENTER;
- PUSHSTACKi(PERLSI_MAGIC);
- PUSHMARK(SP);
- EXTEND(SP,items);
- while (items--)
- PUSHs(*MARK++);
- PUTBACK;
- call_method(methname, G_SCALAR);
- }
- else {
- /* Not clear why we don't call call_method here too.
- * perhaps to get different error message ?
- */
- stash = gv_stashsv(*MARK, FALSE);
- if (!stash || !(gv = gv_fetchmethod(stash, methname))) {
- DIE(aTHX_ "Can't locate object method \"%s\" via package \"%s\"",
- methname, SvPV(*MARK,n_a));
- }
- ENTER;
- PUSHSTACKi(PERLSI_MAGIC);
- PUSHMARK(SP);
- EXTEND(SP,items);
- while (items--)
- PUSHs(*MARK++);
- PUTBACK;
- call_sv((SV*)GvCV(gv), G_SCALAR);
- }
- SPAGAIN;
-
- sv = TOPs;
- POPSTACK;
- if (sv_isobject(sv)) {
- sv_unmagic(varsv, how);
- sv_magic(varsv, (SvRV(sv) == varsv ? Nullsv : sv), how, Nullch, 0);
- }
- LEAVE;
- SP = PL_stack_base + markoff;
- PUSHs(sv);
- RETURN;
-}
-
-PP(pp_untie)
-{
- dSP;
- SV *sv = POPs;
- char how = (SvTYPE(sv) == SVt_PVHV || SvTYPE(sv) == SVt_PVAV) ? 'P' : 'q';
-
- MAGIC * mg ;
- if ((mg = SvTIED_mg(sv, how))) {
- SV *obj = SvRV(mg->mg_obj);
- GV *gv;
- CV *cv = NULL;
- if ((gv = gv_fetchmethod_autoload(SvSTASH(obj), "UNTIE", FALSE)) &&
- isGV(gv) && (cv = GvCV(gv))) {
- PUSHMARK(SP);
- XPUSHs(SvTIED_obj((SV*)gv, mg));
- XPUSHs(sv_2mortal(newSViv(SvREFCNT(obj)-1)));
- PUTBACK;
- ENTER;
- call_sv((SV *)cv, G_VOID);
- LEAVE;
- SPAGAIN;
- }
- else if (ckWARN(WARN_UNTIE)) {
- if (mg && SvREFCNT(obj) > 1)
- Perl_warner(aTHX_ WARN_UNTIE,
- "untie attempted while %"UVuf" inner references still exist",
- (UV)SvREFCNT(obj) - 1 ) ;
- }
- }
- sv_unmagic(sv, how);
- RETPUSHYES;
-}
-
-PP(pp_tied)
-{
- dSP;
- SV *sv = POPs;
- char how = (SvTYPE(sv) == SVt_PVHV || SvTYPE(sv) == SVt_PVAV) ? 'P' : 'q';
- MAGIC *mg;
-
- if ((mg = SvTIED_mg(sv, how))) {
- SV *osv = SvTIED_obj(sv, mg);
- if (osv == mg->mg_obj)
- osv = sv_mortalcopy(osv);
- PUSHs(osv);
- RETURN;
- }
- RETPUSHUNDEF;
-}
-
-PP(pp_dbmopen)
-{
- dSP;
- HV *hv;
- dPOPPOPssrl;
- HV* stash;
- GV *gv;
- SV *sv;
-
- hv = (HV*)POPs;
-
- sv = sv_mortalcopy(&PL_sv_no);
- sv_setpv(sv, "AnyDBM_File");
- stash = gv_stashsv(sv, FALSE);
- if (!stash || !(gv = gv_fetchmethod(stash, "TIEHASH"))) {
- PUTBACK;
- require_pv("AnyDBM_File.pm");
- SPAGAIN;
- if (!(gv = gv_fetchmethod(stash, "TIEHASH")))
- DIE(aTHX_ "No dbm on this machine");
- }
-
- ENTER;
- PUSHMARK(SP);
-
- EXTEND(SP, 5);
- PUSHs(sv);
- PUSHs(left);
- if (SvIV(right))
- PUSHs(sv_2mortal(newSVuv(O_RDWR|O_CREAT)));
- else
- PUSHs(sv_2mortal(newSVuv(O_RDWR)));
- PUSHs(right);
- PUTBACK;
- call_sv((SV*)GvCV(gv), G_SCALAR);
- SPAGAIN;
-
- if (!sv_isobject(TOPs)) {
- SP--;
- PUSHMARK(SP);
- PUSHs(sv);
- PUSHs(left);
- PUSHs(sv_2mortal(newSVuv(O_RDONLY)));
- PUSHs(right);
- PUTBACK;
- call_sv((SV*)GvCV(gv), G_SCALAR);
- SPAGAIN;
- }
-
- if (sv_isobject(TOPs)) {
- sv_unmagic((SV *) hv, 'P');
- sv_magic((SV*)hv, TOPs, 'P', Nullch, 0);
- }
- LEAVE;
- RETURN;
-}
-
-PP(pp_dbmclose)
-{
- return pp_untie();
-}
-
-PP(pp_sselect)
-{
- dSP; dTARGET;
-#ifdef HAS_SELECT
- register I32 i;
- register I32 j;
- register char *s;
- register SV *sv;
- NV value;
- I32 maxlen = 0;
- I32 nfound;
- struct timeval timebuf;
- struct timeval *tbuf = &timebuf;
- I32 growsize;
- char *fd_sets[4];
- STRLEN n_a;
-#if BYTEORDER != 0x1234 && BYTEORDER != 0x12345678
- I32 masksize;
- I32 offset;
- I32 k;
-
-# if BYTEORDER & 0xf0000
-# define ORDERBYTE (0x88888888 - BYTEORDER)
-# else
-# define ORDERBYTE (0x4444 - BYTEORDER)
-# endif
-
-#endif
-
- SP -= 4;
- for (i = 1; i <= 3; i++) {
- if (!SvPOK(SP[i]))
- continue;
- j = SvCUR(SP[i]);
- if (maxlen < j)
- maxlen = j;
- }
-
-/* little endians can use vecs directly */
-#if BYTEORDER == 0x1234 || BYTEORDER == 0x12345678
-# if SELECT_MIN_BITS > 1
- /* If SELECT_MIN_BITS is greater than one we most probably will want
- * to align the sizes with SELECT_MIN_BITS/8 because for example
- * in many little-endian (Intel, Alpha) systems (Linux, OS/2, Digital
- * UNIX, Solaris, NeXT, Darwin) the smallest quantum select() operates
- * on (sets/tests/clears bits) is 32 bits. */
- growsize = maxlen + (SELECT_MIN_BITS/8 - (maxlen % (SELECT_MIN_BITS/8)));
-# else
- growsize = sizeof(fd_set);
-# endif
-# else
-# ifdef NFDBITS
-
-# ifndef NBBY
-# define NBBY 8
-# endif
-
- masksize = NFDBITS / NBBY;
-# else
- masksize = sizeof(long); /* documented int, everyone seems to use long */
-# endif
- growsize = maxlen + (masksize - (maxlen % masksize));
- Zero(&fd_sets[0], 4, char*);
-#endif
-
- sv = SP[4];
- if (SvOK(sv)) {
- value = SvNV(sv);
- if (value < 0.0)
- value = 0.0;
- timebuf.tv_sec = (long)value;
- value -= (NV)timebuf.tv_sec;
- timebuf.tv_usec = (long)(value * 1000000.0);
- }
- else
- tbuf = Null(struct timeval*);
-
- for (i = 1; i <= 3; i++) {
- sv = SP[i];
- if (!SvOK(sv)) {
- fd_sets[i] = 0;
- continue;
- }
- else if (!SvPOK(sv))
- SvPV_force(sv,n_a); /* force string conversion */
- j = SvLEN(sv);
- if (j < growsize) {
- Sv_Grow(sv, growsize);
- }
- j = SvCUR(sv);
- s = SvPVX(sv) + j;
- while (++j <= growsize) {
- *s++ = '\0';
- }
-
-#if BYTEORDER != 0x1234 && BYTEORDER != 0x12345678
- s = SvPVX(sv);
- New(403, fd_sets[i], growsize, char);
- for (offset = 0; offset < growsize; offset += masksize) {
- for (j = 0, k=ORDERBYTE; j < masksize; j++, (k >>= 4))
- fd_sets[i][j+offset] = s[(k % masksize) + offset];
- }
-#else
- fd_sets[i] = SvPVX(sv);
-#endif
- }
-
- nfound = PerlSock_select(
- maxlen * 8,
- (Select_fd_set_t) fd_sets[1],
- (Select_fd_set_t) fd_sets[2],
- (Select_fd_set_t) fd_sets[3],
- tbuf);
- for (i = 1; i <= 3; i++) {
- if (fd_sets[i]) {
- sv = SP[i];
-#if BYTEORDER != 0x1234 && BYTEORDER != 0x12345678
- s = SvPVX(sv);
- for (offset = 0; offset < growsize; offset += masksize) {
- for (j = 0, k=ORDERBYTE; j < masksize; j++, (k >>= 4))
- s[(k % masksize) + offset] = fd_sets[i][j+offset];
- }
- Safefree(fd_sets[i]);
-#endif
- SvSETMAGIC(sv);
- }
- }
-
- PUSHi(nfound);
- if (GIMME == G_ARRAY && tbuf) {
- value = (NV)(timebuf.tv_sec) +
- (NV)(timebuf.tv_usec) / 1000000.0;
- PUSHs(sv = sv_mortalcopy(&PL_sv_no));
- sv_setnv(sv, value);
- }
- RETURN;
-#else
- DIE(aTHX_ "select not implemented");
-#endif
-}
-
-void
-Perl_setdefout(pTHX_ GV *gv)
-{
- if (gv)
- (void)SvREFCNT_inc(gv);
- if (PL_defoutgv)
- SvREFCNT_dec(PL_defoutgv);
- PL_defoutgv = gv;
-}
-
-PP(pp_select)
-{
- dSP; dTARGET;
- GV *newdefout, *egv;
- HV *hv;
-
- newdefout = (PL_op->op_private > 0) ? ((GV *) POPs) : (GV *) NULL;
-
- egv = GvEGV(PL_defoutgv);
- if (!egv)
- egv = PL_defoutgv;
- hv = GvSTASH(egv);
- if (! hv)
- XPUSHs(&PL_sv_undef);
- else {
- GV **gvp = (GV**)hv_fetch(hv, GvNAME(egv), GvNAMELEN(egv), FALSE);
- if (gvp && *gvp == egv) {
- gv_efullname4(TARG, PL_defoutgv, Nullch, TRUE);
- XPUSHTARG;
- }
- else {
- XPUSHs(sv_2mortal(newRV((SV*)egv)));
- }
- }
-
- if (newdefout) {
- if (!GvIO(newdefout))
- gv_IOadd(newdefout);
- setdefout(newdefout);
- }
-
- RETURN;
-}
-
-PP(pp_getc)
-{
- dSP; dTARGET;
- GV *gv;
- MAGIC *mg;
-
- if (MAXARG == 0)
- gv = PL_stdingv;
- else
- gv = (GV*)POPs;
-
- if ((mg = SvTIED_mg((SV*)gv, 'q'))) {
- I32 gimme = GIMME_V;
- PUSHMARK(SP);
- XPUSHs(SvTIED_obj((SV*)gv, mg));
- PUTBACK;
- ENTER;
- call_method("GETC", gimme);
- LEAVE;
- SPAGAIN;
- if (gimme == G_SCALAR)
- SvSetMagicSV_nosteal(TARG, TOPs);
- RETURN;
- }
- if (!gv || do_eof(gv)) /* make sure we have fp with something */
- RETPUSHUNDEF;
- TAINT;
- sv_setpv(TARG, " ");
- *SvPVX(TARG) = PerlIO_getc(IoIFP(GvIOp(gv))); /* should never be EOF */
- PUSHTARG;
- RETURN;
-}
-
-PP(pp_read)
-{
- return pp_sysread();
-}
-
-STATIC OP *
-S_doform(pTHX_ CV *cv, GV *gv, OP *retop)
-{
- register PERL_CONTEXT *cx;
- I32 gimme = GIMME_V;
- AV* padlist = CvPADLIST(cv);
- SV** svp = AvARRAY(padlist);
-
- ENTER;
- SAVETMPS;
-
- push_return(retop);
- PUSHBLOCK(cx, CXt_FORMAT, PL_stack_sp);
- PUSHFORMAT(cx);
- SAVEVPTR(PL_curpad);
- PL_curpad = AvARRAY((AV*)svp[1]);
-
- setdefout(gv); /* locally select filehandle so $% et al work */
- return CvSTART(cv);
-}
-
-PP(pp_enterwrite)
-{
- dSP;
- register GV *gv;
- register IO *io;
- GV *fgv;
- CV *cv;
-
- if (MAXARG == 0)
- gv = PL_defoutgv;
- else {
- gv = (GV*)POPs;
- if (!gv)
- gv = PL_defoutgv;
- }
- EXTEND(SP, 1);
- io = GvIO(gv);
- if (!io) {
- RETPUSHNO;
- }
- if (IoFMT_GV(io))
- fgv = IoFMT_GV(io);
- else
- fgv = gv;
-
- cv = GvFORM(fgv);
- if (!cv) {
- char *name = NULL;
- if (fgv) {
- SV *tmpsv = sv_newmortal();
- gv_efullname4(tmpsv, fgv, Nullch, FALSE);
- name = SvPV_nolen(tmpsv);
- }
- if (name && *name)
- DIE(aTHX_ "Undefined format \"%s\" called", name);
- DIE(aTHX_ "Not a format reference");
- }
- if (CvCLONE(cv))
- cv = (CV*)sv_2mortal((SV*)cv_clone(cv));
-
- IoFLAGS(io) &= ~IOf_DIDTOP;
- return doform(cv,gv,PL_op->op_next);
-}
-
-PP(pp_leavewrite)
-{
- dSP;
- GV *gv = cxstack[cxstack_ix].blk_sub.gv;
- register IO *io = GvIOp(gv);
- PerlIO *ofp = IoOFP(io);
- PerlIO *fp;
- SV **newsp;
- I32 gimme;
- register PERL_CONTEXT *cx;
-
- DEBUG_f(PerlIO_printf(Perl_debug_log, "left=%ld, todo=%ld\n",
- (long)IoLINES_LEFT(io), (long)FmLINES(PL_formtarget)));
- if (IoLINES_LEFT(io) < FmLINES(PL_formtarget) &&
- PL_formtarget != PL_toptarget)
- {
- GV *fgv;
- CV *cv;
- if (!IoTOP_GV(io)) {
- GV *topgv;
- SV *topname;
-
- if (!IoTOP_NAME(io)) {
- if (!IoFMT_NAME(io))
- IoFMT_NAME(io) = savepv(GvNAME(gv));
- topname = sv_2mortal(Perl_newSVpvf(aTHX_ "%s_TOP", IoFMT_NAME(io)));
- topgv = gv_fetchpv(SvPVX(topname), FALSE, SVt_PVFM);
- if ((topgv && GvFORM(topgv)) ||
- !gv_fetchpv("top",FALSE,SVt_PVFM))
- IoTOP_NAME(io) = savepv(SvPVX(topname));
- else
- IoTOP_NAME(io) = savepv("top");
- }
- topgv = gv_fetchpv(IoTOP_NAME(io),FALSE, SVt_PVFM);
- if (!topgv || !GvFORM(topgv)) {
- IoLINES_LEFT(io) = 100000000;
- goto forget_top;
- }
- IoTOP_GV(io) = topgv;
- }
- if (IoFLAGS(io) & IOf_DIDTOP) { /* Oh dear. It still doesn't fit. */
- I32 lines = IoLINES_LEFT(io);
- char *s = SvPVX(PL_formtarget);
- if (lines <= 0) /* Yow, header didn't even fit!!! */
- goto forget_top;
- while (lines-- > 0) {
- s = strchr(s, '\n');
- if (!s)
- break;
- s++;
- }
- if (s) {
- PerlIO_write(ofp, SvPVX(PL_formtarget), s - SvPVX(PL_formtarget));
- sv_chop(PL_formtarget, s);
- FmLINES(PL_formtarget) -= IoLINES_LEFT(io);
- }
- }
- if (IoLINES_LEFT(io) >= 0 && IoPAGE(io) > 0)
- PerlIO_write(ofp, SvPVX(PL_formfeed), SvCUR(PL_formfeed));
- IoLINES_LEFT(io) = IoPAGE_LEN(io);
- IoPAGE(io)++;
- PL_formtarget = PL_toptarget;
- IoFLAGS(io) |= IOf_DIDTOP;
- fgv = IoTOP_GV(io);
- if (!fgv)
- DIE(aTHX_ "bad top format reference");
- cv = GvFORM(fgv);
- {
- char *name = NULL;
- if (!cv) {
- SV *sv = sv_newmortal();
- gv_efullname4(sv, fgv, Nullch, FALSE);
- name = SvPV_nolen(sv);
- }
- if (name && *name)
- DIE(aTHX_ "Undefined top format \"%s\" called",name);
- /* why no:
- else
- DIE(aTHX_ "Undefined top format called");
- ?*/
- }
- if (CvCLONE(cv))
- cv = (CV*)sv_2mortal((SV*)cv_clone(cv));
- return doform(cv,gv,PL_op);
- }
-
- forget_top:
- POPBLOCK(cx,PL_curpm);
- POPFORMAT(cx);
- LEAVE;
-
- fp = IoOFP(io);
- if (!fp) {
- if (ckWARN2(WARN_CLOSED,WARN_IO)) {
- if (IoIFP(io)) {
- /* integrate with report_evil_fh()? */
- char *name = NULL;
- if (isGV(gv)) {
- SV* sv = sv_newmortal();
- gv_efullname4(sv, gv, Nullch, FALSE);
- name = SvPV_nolen(sv);
- }
- if (name && *name)
- Perl_warner(aTHX_ WARN_IO,
- "Filehandle %s opened only for input", name);
- else
- Perl_warner(aTHX_ WARN_IO,
- "Filehandle opened only for input");
- }
- else if (ckWARN(WARN_CLOSED))
- report_evil_fh(gv, io, PL_op->op_type);
- }
- PUSHs(&PL_sv_no);
- }
- else {
- if ((IoLINES_LEFT(io) -= FmLINES(PL_formtarget)) < 0) {
- if (ckWARN(WARN_IO))
- Perl_warner(aTHX_ WARN_IO, "page overflow");
- }
- if (!PerlIO_write(ofp, SvPVX(PL_formtarget), SvCUR(PL_formtarget)) ||
- PerlIO_error(fp))
- PUSHs(&PL_sv_no);
- else {
- FmLINES(PL_formtarget) = 0;
- SvCUR_set(PL_formtarget, 0);
- *SvEND(PL_formtarget) = '\0';
- if (IoFLAGS(io) & IOf_FLUSH)
- (void)PerlIO_flush(fp);
- PUSHs(&PL_sv_yes);
- }
- }
- PL_formtarget = PL_bodytarget;
- PUTBACK;
- return pop_return();
-}
-
-PP(pp_prtf)
-{
- dSP; dMARK; dORIGMARK;
- GV *gv;
- IO *io;
- PerlIO *fp;
- SV *sv;
- MAGIC *mg;
- STRLEN n_a;
-
- if (PL_op->op_flags & OPf_STACKED)
- gv = (GV*)*++MARK;
- else
- gv = PL_defoutgv;
-
- if ((mg = SvTIED_mg((SV*)gv, 'q'))) {
- if (MARK == ORIGMARK) {
- MEXTEND(SP, 1);
- ++MARK;
- Move(MARK, MARK + 1, (SP - MARK) + 1, SV*);
- ++SP;
- }
- PUSHMARK(MARK - 1);
- *MARK = SvTIED_obj((SV*)gv, mg);
- PUTBACK;
- ENTER;
- call_method("PRINTF", G_SCALAR);
- LEAVE;
- SPAGAIN;
- MARK = ORIGMARK + 1;
- *MARK = *SP;
- SP = MARK;
- RETURN;
- }
-
- sv = NEWSV(0,0);
- if (!(io = GvIO(gv))) {
- if (ckWARN2(WARN_UNOPENED,WARN_CLOSED))
- report_evil_fh(gv, io, PL_op->op_type);
- SETERRNO(EBADF,RMS$_IFI);
- goto just_say_no;
- }
- else if (!(fp = IoOFP(io))) {
- if (ckWARN2(WARN_CLOSED,WARN_IO)) {
- /* integrate with report_evil_fh()? */
- if (IoIFP(io)) {
- char *name = NULL;
- if (isGV(gv)) {
- gv_efullname4(sv, gv, Nullch, FALSE);
- name = SvPV_nolen(sv);
- }
- if (name && *name)
- Perl_warner(aTHX_ WARN_IO,
- "Filehandle %s opened only for input", name);
- else
- Perl_warner(aTHX_ WARN_IO,
- "Filehandle opened only for input");
- }
- else if (ckWARN(WARN_CLOSED))
- report_evil_fh(gv, io, PL_op->op_type);
- }
- SETERRNO(EBADF,IoIFP(io)?RMS$_FAC:RMS$_IFI);
- goto just_say_no;
- }
- else {
- do_sprintf(sv, SP - MARK, MARK + 1);
- if (!do_print(sv, fp))
- goto just_say_no;
-
- if (IoFLAGS(io) & IOf_FLUSH)
- if (PerlIO_flush(fp) == EOF)
- goto just_say_no;
- }
- SvREFCNT_dec(sv);
- SP = ORIGMARK;
- PUSHs(&PL_sv_yes);
- RETURN;
-
- just_say_no:
- SvREFCNT_dec(sv);
- SP = ORIGMARK;
- PUSHs(&PL_sv_undef);
- RETURN;
-}
-
-PP(pp_sysopen)
-{
- dSP;
- GV *gv;
- SV *sv;
- char *tmps;
- STRLEN len;
- int mode, perm;
-
- if (MAXARG > 3)
- perm = POPi;
- else
- perm = 0666;
- mode = POPi;
- sv = POPs;
- gv = (GV *)POPs;
-
- /* Need TIEHANDLE method ? */
-
- tmps = SvPV(sv, len);
- if (do_open(gv, tmps, len, TRUE, mode, perm, Nullfp)) {
- IoLINES(GvIOp(gv)) = 0;
- PUSHs(&PL_sv_yes);
- }
- else {
- PUSHs(&PL_sv_undef);
- }
- RETURN;
-}
-
-PP(pp_sysread)
-{
- dSP; dMARK; dORIGMARK; dTARGET;
- int offset;
- GV *gv;
- IO *io;
- char *buffer;
- SSize_t length;
- Sock_size_t bufsize;
- SV *bufsv;
- STRLEN blen;
- MAGIC *mg;
-
- gv = (GV*)*++MARK;
- if ((PL_op->op_type == OP_READ || PL_op->op_type == OP_SYSREAD) &&
- (mg = SvTIED_mg((SV*)gv, 'q')))
- {
- SV *sv;
-
- PUSHMARK(MARK-1);
- *MARK = SvTIED_obj((SV*)gv, mg);
- ENTER;
- call_method("READ", G_SCALAR);
- LEAVE;
- SPAGAIN;
- sv = POPs;
- SP = ORIGMARK;
- PUSHs(sv);
- RETURN;
- }
-
- if (!gv)
- goto say_undef;
- bufsv = *++MARK;
- if (! SvOK(bufsv))
- sv_setpvn(bufsv, "", 0);
- buffer = SvPV_force(bufsv, blen);
- length = SvIVx(*++MARK);
- if (length < 0)
- DIE(aTHX_ "Negative length");
- SETERRNO(0,0);
- if (MARK < SP)
- offset = SvIVx(*++MARK);
- else
- offset = 0;
- io = GvIO(gv);
- if (!io || !IoIFP(io))
- goto say_undef;
-#ifdef HAS_SOCKET
- if (PL_op->op_type == OP_RECV) {
- char namebuf[MAXPATHLEN];
-#if (defined(VMS_DO_SOCKETS) && defined(DECCRTL_SOCKETS)) || defined(MPE)
- bufsize = sizeof (struct sockaddr_in);
-#else
- bufsize = sizeof namebuf;
-#endif
-#ifdef OS2 /* At least Warp3+IAK: only the first byte of bufsize set */
- if (bufsize >= 256)
- bufsize = 255;
-#endif
- buffer = SvGROW(bufsv, length+1);
- /* 'offset' means 'flags' here */
- length = PerlSock_recvfrom(PerlIO_fileno(IoIFP(io)), buffer, length, offset,
- (struct sockaddr *)namebuf, &bufsize);
- if (length < 0)
- RETPUSHUNDEF;
-#ifdef EPOC
- /* Bogus return without padding */
- bufsize = sizeof (struct sockaddr_in);
-#endif
- SvCUR_set(bufsv, length);
- *SvEND(bufsv) = '\0';
- (void)SvPOK_only(bufsv);
- SvSETMAGIC(bufsv);
- /* This should not be marked tainted if the fp is marked clean */
- if (!(IoFLAGS(io) & IOf_UNTAINT))
- SvTAINTED_on(bufsv);
- SP = ORIGMARK;
- sv_setpvn(TARG, namebuf, bufsize);
- PUSHs(TARG);
- RETURN;
- }
-#else
- if (PL_op->op_type == OP_RECV)
- DIE(aTHX_ PL_no_sock_func, "recv");
-#endif
- if (offset < 0) {
- if (-offset > blen)
- DIE(aTHX_ "Offset outside string");
- offset += blen;
- }
- bufsize = SvCUR(bufsv);
- buffer = SvGROW(bufsv, length+offset+1);
- if (offset > bufsize) { /* Zero any newly allocated space */
- Zero(buffer+bufsize, offset-bufsize, char);
- }
- if (PL_op->op_type == OP_SYSREAD) {
-#ifdef PERL_SOCK_SYSREAD_IS_RECV
- if (IoTYPE(io) == IoTYPE_SOCKET) {
- length = PerlSock_recv(PerlIO_fileno(IoIFP(io)),
- buffer+offset, length, 0);
- }
- else
-#endif
- {
- length = PerlLIO_read(PerlIO_fileno(IoIFP(io)),
- buffer+offset, length);
- }
- }
- else
-#ifdef HAS_SOCKET__bad_code_maybe
- if (IoTYPE(io) == IoTYPE_SOCKET) {
- char namebuf[MAXPATHLEN];
-#if defined(VMS_DO_SOCKETS) && defined(DECCRTL_SOCKETS)
- bufsize = sizeof (struct sockaddr_in);
-#else
- bufsize = sizeof namebuf;
-#endif
- length = PerlSock_recvfrom(PerlIO_fileno(IoIFP(io)), buffer+offset, length, 0,
- (struct sockaddr *)namebuf, &bufsize);
- }
- else
-#endif
- {
- length = PerlIO_read(IoIFP(io), buffer+offset, length);
- /* fread() returns 0 on both error and EOF */
- if (length == 0 && PerlIO_error(IoIFP(io)))
- length = -1;
- }
- if (length < 0) {
- if ((IoTYPE(io) == IoTYPE_WRONLY || IoIFP(io) == PerlIO_stdout()
- || IoIFP(io) == PerlIO_stderr()) && ckWARN(WARN_IO))
- {
- /* integrate with report_evil_fh()? */
- char *name = NULL;
- if (isGV(gv)) {
- SV* sv = sv_newmortal();
- gv_efullname4(sv, gv, Nullch, FALSE);
- name = SvPV_nolen(sv);
- }
- if (name && *name)
- Perl_warner(aTHX_ WARN_IO,
- "Filehandle %s opened only for output", name);
- else
- Perl_warner(aTHX_ WARN_IO,
- "Filehandle opened only for output");
- }
- goto say_undef;
- }
- SvCUR_set(bufsv, length+offset);
- *SvEND(bufsv) = '\0';
- (void)SvPOK_only(bufsv);
- SvSETMAGIC(bufsv);
- /* This should not be marked tainted if the fp is marked clean */
- if (!(IoFLAGS(io) & IOf_UNTAINT))
- SvTAINTED_on(bufsv);
- SP = ORIGMARK;
- PUSHi(length);
- RETURN;
-
- say_undef:
- SP = ORIGMARK;
- RETPUSHUNDEF;
-}
-
-PP(pp_syswrite)
-{
- dSP;
- int items = (SP - PL_stack_base) - TOPMARK;
- if (items == 2) {
- SV *sv;
- EXTEND(SP, 1);
- sv = sv_2mortal(newSViv(sv_len(*SP)));
- PUSHs(sv);
- PUTBACK;
- }
- return pp_send();
-}
-
-PP(pp_send)
-{
- dSP; dMARK; dORIGMARK; dTARGET;
- GV *gv;
- IO *io;
- SV *bufsv;
- char *buffer;
- Size_t length;
- SSize_t retval;
- IV offset;
- STRLEN blen;
- MAGIC *mg;
-
- gv = (GV*)*++MARK;
- if (PL_op->op_type == OP_SYSWRITE && (mg = SvTIED_mg((SV*)gv, 'q'))) {
- SV *sv;
-
- PUSHMARK(MARK-1);
- *MARK = SvTIED_obj((SV*)gv, mg);
- ENTER;
- call_method("WRITE", G_SCALAR);
- LEAVE;
- SPAGAIN;
- sv = POPs;
- SP = ORIGMARK;
- PUSHs(sv);
- RETURN;
- }
- if (!gv)
- goto say_undef;
- bufsv = *++MARK;
- buffer = SvPV(bufsv, blen);
-#if Size_t_size > IVSIZE
- length = (Size_t)SvNVx(*++MARK);
-#else
- length = (Size_t)SvIVx(*++MARK);
-#endif
- if ((SSize_t)length < 0)
- DIE(aTHX_ "Negative length");
- SETERRNO(0,0);
- io = GvIO(gv);
- if (!io || !IoIFP(io)) {
- retval = -1;
- if (ckWARN(WARN_CLOSED))
- report_evil_fh(gv, io, PL_op->op_type);
- }
- else if (PL_op->op_type == OP_SYSWRITE) {
- if (MARK < SP) {
- offset = SvIVx(*++MARK);
- if (offset < 0) {
- if (-offset > blen)
- DIE(aTHX_ "Offset outside string");
- offset += blen;
- } else if (offset >= blen && blen > 0)
- DIE(aTHX_ "Offset outside string");
- } else
- offset = 0;
- if (length > blen - offset)
- length = blen - offset;
-#ifdef PERL_SOCK_SYSWRITE_IS_SEND
- if (IoTYPE(io) == IoTYPE_SOCKET) {
- retval = PerlSock_send(PerlIO_fileno(IoIFP(io)),
- buffer+offset, length, 0);
- }
- else
-#endif
- {
- /* See the note at doio.c:do_print about filesize limits. --jhi */
- retval = PerlLIO_write(PerlIO_fileno(IoIFP(io)),
- buffer+offset, length);
- }
- }
-#ifdef HAS_SOCKET
- else if (SP > MARK) {
- char *sockbuf;
- STRLEN mlen;
- sockbuf = SvPVx(*++MARK, mlen);
- retval = PerlSock_sendto(PerlIO_fileno(IoIFP(io)), buffer, blen,
- length, (struct sockaddr *)sockbuf, mlen);
- }
- else
- retval = PerlSock_send(PerlIO_fileno(IoIFP(io)), buffer, blen, length);
-
-#else
- else
- DIE(aTHX_ PL_no_sock_func, "send");
-#endif
- if (retval < 0)
- goto say_undef;
- SP = ORIGMARK;
-#if Size_t_size > IVSIZE
- PUSHn(retval);
-#else
- PUSHi(retval);
-#endif
- RETURN;
-
- say_undef:
- SP = ORIGMARK;
- RETPUSHUNDEF;
-}
-
-PP(pp_recv)
-{
- return pp_sysread();
-}
-
-PP(pp_eof)
-{
- dSP;
- GV *gv;
- MAGIC *mg;
-
- if (MAXARG == 0) {
- if (PL_op->op_flags & OPf_SPECIAL) { /* eof() */
- IO *io;
- gv = PL_last_in_gv = PL_argvgv;
- io = GvIO(gv);
- if (io && !IoIFP(io)) {
- if ((IoFLAGS(io) & IOf_START) && av_len(GvAVn(gv)) < 0) {
- IoLINES(io) = 0;
- IoFLAGS(io) &= ~IOf_START;
- do_open(gv, "-", 1, FALSE, O_RDONLY, 0, Nullfp);
- sv_setpvn(GvSV(gv), "-", 1);
- SvSETMAGIC(GvSV(gv));
- }
- else if (!nextargv(gv))
- RETPUSHYES;
- }
- }
- else
- gv = PL_last_in_gv; /* eof */
- }
- else
- gv = PL_last_in_gv = (GV*)POPs; /* eof(FH) */
-
- if (gv && (mg = SvTIED_mg((SV*)gv, 'q'))) {
- PUSHMARK(SP);
- XPUSHs(SvTIED_obj((SV*)gv, mg));
- PUTBACK;
- ENTER;
- call_method("EOF", G_SCALAR);
- LEAVE;
- SPAGAIN;
- RETURN;
- }
-
- PUSHs(boolSV(!gv || do_eof(gv)));
- RETURN;
-}
-
-PP(pp_tell)
-{
- dSP; dTARGET;
- GV *gv;
- MAGIC *mg;
-
- if (MAXARG == 0)
- gv = PL_last_in_gv;
- else
- gv = PL_last_in_gv = (GV*)POPs;
-
- if (gv && (mg = SvTIED_mg((SV*)gv, 'q'))) {
- PUSHMARK(SP);
- XPUSHs(SvTIED_obj((SV*)gv, mg));
- PUTBACK;
- ENTER;
- call_method("TELL", G_SCALAR);
- LEAVE;
- SPAGAIN;
- RETURN;
- }
-
-#if LSEEKSIZE > IVSIZE
- PUSHn( do_tell(gv) );
-#else
- PUSHi( do_tell(gv) );
-#endif
- RETURN;
-}
-
-PP(pp_seek)
-{
- return pp_sysseek();
-}
-
-PP(pp_sysseek)
-{
- dSP;
- GV *gv;
- int whence = POPi;
-#if LSEEKSIZE > IVSIZE
- Off_t offset = (Off_t)SvNVx(POPs);
-#else
- Off_t offset = (Off_t)SvIVx(POPs);
-#endif
- MAGIC *mg;
-
- gv = PL_last_in_gv = (GV*)POPs;
-
- if (gv && (mg = SvTIED_mg((SV*)gv, 'q'))) {
- PUSHMARK(SP);
- XPUSHs(SvTIED_obj((SV*)gv, mg));
-#if LSEEKSIZE > IVSIZE
- XPUSHs(sv_2mortal(newSVnv((NV) offset)));
-#else
- XPUSHs(sv_2mortal(newSViv(offset)));
-#endif
- XPUSHs(sv_2mortal(newSViv(whence)));
- PUTBACK;
- ENTER;
- call_method("SEEK", G_SCALAR);
- LEAVE;
- SPAGAIN;
- RETURN;
- }
-
- if (PL_op->op_type == OP_SEEK)
- PUSHs(boolSV(do_seek(gv, offset, whence)));
- else {
- Off_t sought = do_sysseek(gv, offset, whence);
- if (sought < 0)
- PUSHs(&PL_sv_undef);
- else {
- SV* sv = sought ?
-#if LSEEKSIZE > IVSIZE
- newSVnv((NV)sought)
-#else
- newSViv(sought)
-#endif
- : newSVpvn(zero_but_true, ZBTLEN);
- PUSHs(sv_2mortal(sv));
- }
- }
- RETURN;
-}
-
-PP(pp_truncate)
-{
- dSP;
- /* There seems to be no consensus on the length type of truncate()
- * and ftruncate(), both off_t and size_t have supporters. In
- * general one would think that when using large files, off_t is
- * at least as wide as size_t, so using an off_t should be okay. */
- /* XXX Configure probe for the length type of *truncate() needed XXX */
- Off_t len;
- int result = 1;
- GV *tmpgv;
- STRLEN n_a;
-
-#if Size_t_size > IVSIZE
- len = (Off_t)POPn;
-#else
- len = (Off_t)POPi;
-#endif
- /* Checking for length < 0 is problematic as the type might or
- * might not be signed: if it is not, clever compilers will moan. */
- /* XXX Configure probe for the signedness of the length type of *truncate() needed? XXX */
- SETERRNO(0,0);
-#if defined(HAS_TRUNCATE) || defined(HAS_CHSIZE) || defined(F_FREESP)
- if (PL_op->op_flags & OPf_SPECIAL) {
- tmpgv = gv_fetchpv(POPpx, FALSE, SVt_PVIO);
- do_ftruncate:
- TAINT_PROPER("truncate");
- if (!GvIO(tmpgv) || !IoIFP(GvIOp(tmpgv)))
- result = 0;
- else {
- PerlIO_flush(IoIFP(GvIOp(tmpgv)));
-#ifdef HAS_TRUNCATE
- if (ftruncate(PerlIO_fileno(IoIFP(GvIOn(tmpgv))), len) < 0)
-#else
- if (my_chsize(PerlIO_fileno(IoIFP(GvIOn(tmpgv))), len) < 0)
-#endif
- result = 0;
- }
- }
- else {
- SV *sv = POPs;
- char *name;
- STRLEN n_a;
-
- if (SvTYPE(sv) == SVt_PVGV) {
- tmpgv = (GV*)sv; /* *main::FRED for example */
- goto do_ftruncate;
- }
- else if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVGV) {
- tmpgv = (GV*) SvRV(sv); /* \*main::FRED for example */
- goto do_ftruncate;
- }
-
- name = SvPV(sv, n_a);
- TAINT_PROPER("truncate");
-#ifdef HAS_TRUNCATE
- if (truncate(name, len) < 0)
- result = 0;
-#else
- {
- int tmpfd;
- if ((tmpfd = PerlLIO_open(name, O_RDWR)) < 0)
- result = 0;
- else {
- if (my_chsize(tmpfd, len) < 0)
- result = 0;
- PerlLIO_close(tmpfd);
- }
- }
-#endif
- }
-
- if (result)
- RETPUSHYES;
- if (!errno)
- SETERRNO(EBADF,RMS$_IFI);
- RETPUSHUNDEF;
-#else
- DIE(aTHX_ "truncate not implemented");
-#endif
-}
-
-PP(pp_fcntl)
-{
- return pp_ioctl();
-}
-
-PP(pp_ioctl)
-{
- dSP; dTARGET;
- SV *argsv = POPs;
- unsigned int func = U_I(POPn);
- int optype = PL_op->op_type;
- char *s;
- IV retval;
- GV *gv = (GV*)POPs;
- IO *io = GvIOn(gv);
-
- if (!io || !argsv || !IoIFP(io)) {
- SETERRNO(EBADF,RMS$_IFI); /* well, sort of... */
- RETPUSHUNDEF;
- }
-
- if (SvPOK(argsv) || !SvNIOK(argsv)) {
- STRLEN len;
- STRLEN need;
- s = SvPV_force(argsv, len);
- need = IOCPARM_LEN(func);
- if (len < need) {
- s = Sv_Grow(argsv, need + 1);
- SvCUR_set(argsv, need);
- }
-
- s[SvCUR(argsv)] = 17; /* a little sanity check here */
- }
- else {
- retval = SvIV(argsv);
- s = INT2PTR(char*,retval); /* ouch */
- }
-
- TAINT_PROPER(optype == OP_IOCTL ? "ioctl" : "fcntl");
-
- if (optype == OP_IOCTL)
-#ifdef HAS_IOCTL
- retval = PerlLIO_ioctl(PerlIO_fileno(IoIFP(io)), func, s);
-#else
- DIE(aTHX_ "ioctl is not implemented");
-#endif
- else
-#ifdef HAS_FCNTL
-#if defined(OS2) && defined(__EMX__)
- retval = fcntl(PerlIO_fileno(IoIFP(io)), func, (int)s);
-#else
- retval = fcntl(PerlIO_fileno(IoIFP(io)), func, s);
-#endif
-#else
- DIE(aTHX_ "fcntl is not implemented");
-#endif
-
- if (SvPOK(argsv)) {
- if (s[SvCUR(argsv)] != 17)
- DIE(aTHX_ "Possible memory corruption: %s overflowed 3rd argument",
- PL_op_name[optype]);
- s[SvCUR(argsv)] = 0; /* put our null back */
- SvSETMAGIC(argsv); /* Assume it has changed */
- }
-
- if (retval == -1)
- RETPUSHUNDEF;
- if (retval != 0) {
- PUSHi(retval);
- }
- else {
- PUSHp(zero_but_true, ZBTLEN);
- }
- RETURN;
-}
-
-PP(pp_flock)
-{
- dSP; dTARGET;
- I32 value;
- int argtype;
- GV *gv;
- IO *io = NULL;
- PerlIO *fp;
-
-#ifdef FLOCK
- argtype = POPi;
- if (MAXARG == 0)
- gv = PL_last_in_gv;
- else
- gv = (GV*)POPs;
- if (gv && (io = GvIO(gv)))
- fp = IoIFP(io);
- else {
- fp = Nullfp;
- io = NULL;
- }
- if (fp) {
- (void)PerlIO_flush(fp);
- value = (I32)(PerlLIO_flock(PerlIO_fileno(fp), argtype) >= 0);
- }
- else {
- if (ckWARN2(WARN_UNOPENED,WARN_CLOSED))
- report_evil_fh(gv, io, PL_op->op_type);
- value = 0;
- SETERRNO(EBADF,RMS$_IFI);
- }
- PUSHi(value);
- RETURN;
-#else
- DIE(aTHX_ PL_no_func, "flock()");
-#endif
-}
-
-/* Sockets. */
-
-PP(pp_socket)
-{
- dSP;
-#ifdef HAS_SOCKET
- GV *gv;
- register IO *io;
- int protocol = POPi;
- int type = POPi;
- int domain = POPi;
- int fd;
-
- gv = (GV*)POPs;
-
- if (!gv) {
- SETERRNO(EBADF,LIB$_INVARG);
- RETPUSHUNDEF;
- }
-
- io = GvIOn(gv);
- if (IoIFP(io))
- do_close(gv, FALSE);
-
- TAINT_PROPER("socket");
- fd = PerlSock_socket(domain, type, protocol);
- if (fd < 0)
- RETPUSHUNDEF;
- IoIFP(io) = PerlIO_fdopen(fd, "r"); /* stdio gets confused about sockets */
- IoOFP(io) = PerlIO_fdopen(fd, "w");
- IoTYPE(io) = IoTYPE_SOCKET;
- if (!IoIFP(io) || !IoOFP(io)) {
- if (IoIFP(io)) PerlIO_close(IoIFP(io));
- if (IoOFP(io)) PerlIO_close(IoOFP(io));
- if (!IoIFP(io) && !IoOFP(io)) PerlLIO_close(fd);
- RETPUSHUNDEF;
- }
-#if defined(HAS_FCNTL) && defined(F_SETFD)
- fcntl(fd, F_SETFD, fd > PL_maxsysfd); /* ensure close-on-exec */
-#endif
-
-#ifdef EPOC
- setbuf( IoIFP(io), NULL); /* EPOC gets confused about sockets */
-#endif
-
- RETPUSHYES;
-#else
- DIE(aTHX_ PL_no_sock_func, "socket");
-#endif
-}
-
-PP(pp_sockpair)
-{
- dSP;
-#ifdef HAS_SOCKETPAIR
- GV *gv1;
- GV *gv2;
- register IO *io1;
- register IO *io2;
- int protocol = POPi;
- int type = POPi;
- int domain = POPi;
- int fd[2];
-
- gv2 = (GV*)POPs;
- gv1 = (GV*)POPs;
- if (!gv1 || !gv2)
- RETPUSHUNDEF;
-
- io1 = GvIOn(gv1);
- io2 = GvIOn(gv2);
- if (IoIFP(io1))
- do_close(gv1, FALSE);
- if (IoIFP(io2))
- do_close(gv2, FALSE);
-
- TAINT_PROPER("socketpair");
- if (PerlSock_socketpair(domain, type, protocol, fd) < 0)
- RETPUSHUNDEF;
- IoIFP(io1) = PerlIO_fdopen(fd[0], "r");
- IoOFP(io1) = PerlIO_fdopen(fd[0], "w");
- IoTYPE(io1) = IoTYPE_SOCKET;
- IoIFP(io2) = PerlIO_fdopen(fd[1], "r");
- IoOFP(io2) = PerlIO_fdopen(fd[1], "w");
- IoTYPE(io2) = IoTYPE_SOCKET;
- if (!IoIFP(io1) || !IoOFP(io1) || !IoIFP(io2) || !IoOFP(io2)) {
- if (IoIFP(io1)) PerlIO_close(IoIFP(io1));
- if (IoOFP(io1)) PerlIO_close(IoOFP(io1));
- if (!IoIFP(io1) && !IoOFP(io1)) PerlLIO_close(fd[0]);
- if (IoIFP(io2)) PerlIO_close(IoIFP(io2));
- if (IoOFP(io2)) PerlIO_close(IoOFP(io2));
- if (!IoIFP(io2) && !IoOFP(io2)) PerlLIO_close(fd[1]);
- RETPUSHUNDEF;
- }
-#if defined(HAS_FCNTL) && defined(F_SETFD)
- fcntl(fd[0],F_SETFD,fd[0] > PL_maxsysfd); /* ensure close-on-exec */
- fcntl(fd[1],F_SETFD,fd[1] > PL_maxsysfd); /* ensure close-on-exec */
-#endif
-
- RETPUSHYES;
-#else
- DIE(aTHX_ PL_no_sock_func, "socketpair");
-#endif
-}
-
-PP(pp_bind)
-{
- dSP;
-#ifdef HAS_SOCKET
-#ifdef MPE /* Requires PRIV mode to bind() to ports < 1024 */
- extern GETPRIVMODE();
- extern GETUSERMODE();
-#endif
- SV *addrsv = POPs;
- char *addr;
- GV *gv = (GV*)POPs;
- register IO *io = GvIOn(gv);
- STRLEN len;
- int bind_ok = 0;
-#ifdef MPE
- int mpeprivmode = 0;
-#endif
-
- if (!io || !IoIFP(io))
- goto nuts;
-
- addr = SvPV(addrsv, len);
- TAINT_PROPER("bind");
-#ifdef MPE /* Deal with MPE bind() peculiarities */
- if (((struct sockaddr *)addr)->sa_family == AF_INET) {
- /* The address *MUST* stupidly be zero. */
- ((struct sockaddr_in *)addr)->sin_addr.s_addr = INADDR_ANY;
- /* PRIV mode is required to bind() to ports < 1024. */
- if (((struct sockaddr_in *)addr)->sin_port < 1024 &&
- ((struct sockaddr_in *)addr)->sin_port > 0) {
- GETPRIVMODE(); /* If this fails, we are aborted by MPE/iX. */
- mpeprivmode = 1;
- }
- }
-#endif /* MPE */
- if (PerlSock_bind(PerlIO_fileno(IoIFP(io)),
- (struct sockaddr *)addr, len) >= 0)
- bind_ok = 1;
-
-#ifdef MPE /* Switch back to USER mode */
- if (mpeprivmode)
- GETUSERMODE();
-#endif /* MPE */
-
- if (bind_ok)
- RETPUSHYES;
- else
- RETPUSHUNDEF;
-
-nuts:
- if (ckWARN(WARN_CLOSED))
- report_evil_fh(gv, io, PL_op->op_type);
- SETERRNO(EBADF,SS$_IVCHAN);
- RETPUSHUNDEF;
-#else
- DIE(aTHX_ PL_no_sock_func, "bind");
-#endif
-}
-
-PP(pp_connect)
-{
- dSP;
-#ifdef HAS_SOCKET
- SV *addrsv = POPs;
- char *addr;
- GV *gv = (GV*)POPs;
- register IO *io = GvIOn(gv);
- STRLEN len;
-
- if (!io || !IoIFP(io))
- goto nuts;
-
- addr = SvPV(addrsv, len);
- TAINT_PROPER("connect");
- if (PerlSock_connect(PerlIO_fileno(IoIFP(io)), (struct sockaddr *)addr, len) >= 0)
- RETPUSHYES;
- else
- RETPUSHUNDEF;
-
-nuts:
- if (ckWARN(WARN_CLOSED))
- report_evil_fh(gv, io, PL_op->op_type);
- SETERRNO(EBADF,SS$_IVCHAN);
- RETPUSHUNDEF;
-#else
- DIE(aTHX_ PL_no_sock_func, "connect");
-#endif
-}
-
-PP(pp_listen)
-{
- dSP;
-#ifdef HAS_SOCKET
- int backlog = POPi;
- GV *gv = (GV*)POPs;
- register IO *io = GvIOn(gv);
-
- if (!io || !IoIFP(io))
- goto nuts;
-
- if (PerlSock_listen(PerlIO_fileno(IoIFP(io)), backlog) >= 0)
- RETPUSHYES;
- else
- RETPUSHUNDEF;
-
-nuts:
- if (ckWARN(WARN_CLOSED))
- report_evil_fh(gv, io, PL_op->op_type);
- SETERRNO(EBADF,SS$_IVCHAN);
- RETPUSHUNDEF;
-#else
- DIE(aTHX_ PL_no_sock_func, "listen");
-#endif
-}
-
-PP(pp_accept)
-{
- dSP; dTARGET;
-#ifdef HAS_SOCKET
- GV *ngv;
- GV *ggv;
- register IO *nstio;
- register IO *gstio;
- struct sockaddr saddr; /* use a struct to avoid alignment problems */
- Sock_size_t len = sizeof saddr;
- int fd;
-
- ggv = (GV*)POPs;
- ngv = (GV*)POPs;
-
- if (!ngv)
- goto badexit;
- if (!ggv)
- goto nuts;
-
- gstio = GvIO(ggv);
- if (!gstio || !IoIFP(gstio))
- goto nuts;
-
- nstio = GvIOn(ngv);
- if (IoIFP(nstio))
- do_close(ngv, FALSE);
-
- fd = PerlSock_accept(PerlIO_fileno(IoIFP(gstio)), (struct sockaddr *)&saddr, &len);
- if (fd < 0)
- goto badexit;
- IoIFP(nstio) = PerlIO_fdopen(fd, "r");
- IoOFP(nstio) = PerlIO_fdopen(fd, "w");
- IoTYPE(nstio) = IoTYPE_SOCKET;
- if (!IoIFP(nstio) || !IoOFP(nstio)) {
- if (IoIFP(nstio)) PerlIO_close(IoIFP(nstio));
- if (IoOFP(nstio)) PerlIO_close(IoOFP(nstio));
- if (!IoIFP(nstio) && !IoOFP(nstio)) PerlLIO_close(fd);
- goto badexit;
- }
-#if defined(HAS_FCNTL) && defined(F_SETFD)
- fcntl(fd, F_SETFD, fd > PL_maxsysfd); /* ensure close-on-exec */
-#endif
-
-#ifdef EPOC
- len = sizeof saddr; /* EPOC somehow truncates info */
- setbuf( IoIFP(nstio), NULL); /* EPOC gets confused about sockets */
-#endif
-
- PUSHp((char *)&saddr, len);
- RETURN;
-
-nuts:
- if (ckWARN(WARN_CLOSED))
- report_evil_fh(ggv, ggv ? GvIO(ggv) : 0, PL_op->op_type);
- SETERRNO(EBADF,SS$_IVCHAN);
-
-badexit:
- RETPUSHUNDEF;
-
-#else
- DIE(aTHX_ PL_no_sock_func, "accept");
-#endif
-}
-
-PP(pp_shutdown)
-{
- dSP; dTARGET;
-#ifdef HAS_SOCKET
- int how = POPi;
- GV *gv = (GV*)POPs;
- register IO *io = GvIOn(gv);
-
- if (!io || !IoIFP(io))
- goto nuts;
-
- PUSHi( PerlSock_shutdown(PerlIO_fileno(IoIFP(io)), how) >= 0 );
- RETURN;
-
-nuts:
- if (ckWARN(WARN_CLOSED))
- report_evil_fh(gv, io, PL_op->op_type);
- SETERRNO(EBADF,SS$_IVCHAN);
- RETPUSHUNDEF;
-#else
- DIE(aTHX_ PL_no_sock_func, "shutdown");
-#endif
-}
-
-PP(pp_gsockopt)
-{
-#ifdef HAS_SOCKET
- return pp_ssockopt();
-#else
- DIE(aTHX_ PL_no_sock_func, "getsockopt");
-#endif
-}
-
-PP(pp_ssockopt)
-{
- dSP;
-#ifdef HAS_SOCKET
- int optype = PL_op->op_type;
- SV *sv;
- int fd;
- unsigned int optname;
- unsigned int lvl;
- GV *gv;
- register IO *io;
- Sock_size_t len;
-
- if (optype == OP_GSOCKOPT)
- sv = sv_2mortal(NEWSV(22, 257));
- else
- sv = POPs;
- optname = (unsigned int) POPi;
- lvl = (unsigned int) POPi;
-
- gv = (GV*)POPs;
- io = GvIOn(gv);
- if (!io || !IoIFP(io))
- goto nuts;
-
- fd = PerlIO_fileno(IoIFP(io));
- switch (optype) {
- case OP_GSOCKOPT:
- SvGROW(sv, 257);
- (void)SvPOK_only(sv);
- SvCUR_set(sv,256);
- *SvEND(sv) ='\0';
- len = SvCUR(sv);
- if (PerlSock_getsockopt(fd, lvl, optname, SvPVX(sv), &len) < 0)
- goto nuts2;
- SvCUR_set(sv, len);
- *SvEND(sv) ='\0';
- PUSHs(sv);
- break;
- case OP_SSOCKOPT: {
- char *buf;
- int aint;
- if (SvPOKp(sv)) {
- STRLEN l;
- buf = SvPV(sv, l);
- len = l;
- }
- else {
- aint = (int)SvIV(sv);
- buf = (char*)&aint;
- len = sizeof(int);
- }
- if (PerlSock_setsockopt(fd, lvl, optname, buf, len) < 0)
- goto nuts2;
- PUSHs(&PL_sv_yes);
- }
- break;
- }
- RETURN;
-
-nuts:
- if (ckWARN(WARN_CLOSED))
- report_evil_fh(gv, io, optype);
- SETERRNO(EBADF,SS$_IVCHAN);
-nuts2:
- RETPUSHUNDEF;
-
-#else
- DIE(aTHX_ PL_no_sock_func, "setsockopt");
-#endif
-}
-
-PP(pp_getsockname)
-{
-#ifdef HAS_SOCKET
- return pp_getpeername();
-#else
- DIE(aTHX_ PL_no_sock_func, "getsockname");
-#endif
-}
-
-PP(pp_getpeername)
-{
- dSP;
-#ifdef HAS_SOCKET
- int optype = PL_op->op_type;
- SV *sv;
- int fd;
- GV *gv = (GV*)POPs;
- register IO *io = GvIOn(gv);
- Sock_size_t len;
-
- if (!io || !IoIFP(io))
- goto nuts;
-
- sv = sv_2mortal(NEWSV(22, 257));
- (void)SvPOK_only(sv);
- len = 256;
- SvCUR_set(sv, len);
- *SvEND(sv) ='\0';
- fd = PerlIO_fileno(IoIFP(io));
- switch (optype) {
- case OP_GETSOCKNAME:
- if (PerlSock_getsockname(fd, (struct sockaddr *)SvPVX(sv), &len) < 0)
- goto nuts2;
- break;
- case OP_GETPEERNAME:
- if (PerlSock_getpeername(fd, (struct sockaddr *)SvPVX(sv), &len) < 0)
- goto nuts2;
-#if defined(VMS_DO_SOCKETS) && defined (DECCRTL_SOCKETS)
- {
- 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";
- /* If the call succeeded, make sure we don't have a zeroed port/addr */
- if (((struct sockaddr *)SvPVX(sv))->sa_family == AF_INET &&
- !memcmp((char *)SvPVX(sv) + sizeof(u_short), nowhere,
- sizeof(u_short) + sizeof(struct in_addr))) {
- goto nuts2;
- }
- }
-#endif
- break;
- }
-#ifdef BOGUS_GETNAME_RETURN
- /* Interactive Unix, getpeername() and getsockname()
- does not return valid namelen */
- if (len == BOGUS_GETNAME_RETURN)
- len = sizeof(struct sockaddr);
-#endif
- SvCUR_set(sv, len);
- *SvEND(sv) ='\0';
- PUSHs(sv);
- RETURN;
-
-nuts:
- if (ckWARN(WARN_CLOSED))
- report_evil_fh(gv, io, optype);
- SETERRNO(EBADF,SS$_IVCHAN);
-nuts2:
- RETPUSHUNDEF;
-
-#else
- DIE(aTHX_ PL_no_sock_func, "getpeername");
-#endif
-}
-
-/* Stat calls. */
-
-PP(pp_lstat)
-{
- return pp_stat();
-}
-
-PP(pp_stat)
-{
- dSP;
- GV *gv;
- I32 gimme;
- I32 max = 13;
- STRLEN n_a;
-
- if (PL_op->op_flags & OPf_REF) {
- gv = cGVOP_gv;
- do_fstat:
- if (gv != PL_defgv) {
- PL_laststype = OP_STAT;
- PL_statgv = gv;
- sv_setpv(PL_statname, "");
- PL_laststatval = (GvIO(gv) && IoIFP(GvIOp(gv))
- ? PerlLIO_fstat(PerlIO_fileno(IoIFP(GvIOn(gv))), &PL_statcache) : -1);
- }
- if (PL_laststatval < 0) {
- if (ckWARN2(WARN_UNOPENED,WARN_CLOSED))
- report_evil_fh(gv, GvIO(gv), PL_op->op_type);
- max = 0;
- }
- }
- else {
- SV* sv = POPs;
- if (SvTYPE(sv) == SVt_PVGV) {
- gv = (GV*)sv;
- goto do_fstat;
- }
- else if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVGV) {
- gv = (GV*)SvRV(sv);
- goto do_fstat;
- }
- sv_setpv(PL_statname, SvPV(sv,n_a));
- PL_statgv = Nullgv;
-#ifdef HAS_LSTAT
- PL_laststype = PL_op->op_type;
- if (PL_op->op_type == OP_LSTAT)
- PL_laststatval = PerlLIO_lstat(SvPV(PL_statname, n_a), &PL_statcache);
- else
-#endif
- PL_laststatval = PerlLIO_stat(SvPV(PL_statname, n_a), &PL_statcache);
- if (PL_laststatval < 0) {
- if (ckWARN(WARN_NEWLINE) && strchr(SvPV(PL_statname, n_a), '\n'))
- Perl_warner(aTHX_ WARN_NEWLINE, PL_warn_nl, "stat");
- max = 0;
- }
- }
-
- gimme = GIMME_V;
- if (gimme != G_ARRAY) {
- if (gimme != G_VOID)
- XPUSHs(boolSV(max));
- RETURN;
- }
- if (max) {
- EXTEND(SP, max);
- EXTEND_MORTAL(max);
- PUSHs(sv_2mortal(newSViv(PL_statcache.st_dev)));
- PUSHs(sv_2mortal(newSViv(PL_statcache.st_ino)));
- PUSHs(sv_2mortal(newSVuv(PL_statcache.st_mode)));
- PUSHs(sv_2mortal(newSVuv(PL_statcache.st_nlink)));
-#if Uid_t_size > IVSIZE
- PUSHs(sv_2mortal(newSVnv(PL_statcache.st_uid)));
-#else
-# if Uid_t_sign <= 0
- PUSHs(sv_2mortal(newSViv(PL_statcache.st_uid)));
-# else
- PUSHs(sv_2mortal(newSVuv(PL_statcache.st_uid)));
-# endif
-#endif
-#if Gid_t_size > IVSIZE
- PUSHs(sv_2mortal(newSVnv(PL_statcache.st_gid)));
-#else
-# if Gid_t_sign <= 0
- PUSHs(sv_2mortal(newSViv(PL_statcache.st_gid)));
-# else
- PUSHs(sv_2mortal(newSVuv(PL_statcache.st_gid)));
-# endif
-#endif
-#ifdef USE_STAT_RDEV
- PUSHs(sv_2mortal(newSViv(PL_statcache.st_rdev)));
-#else
- PUSHs(sv_2mortal(newSVpvn("", 0)));
-#endif
-#if Off_t_size > IVSIZE
- PUSHs(sv_2mortal(newSVnv(PL_statcache.st_size)));
-#else
- PUSHs(sv_2mortal(newSViv(PL_statcache.st_size)));
-#endif
-#ifdef BIG_TIME
- PUSHs(sv_2mortal(newSVnv(PL_statcache.st_atime)));
- PUSHs(sv_2mortal(newSVnv(PL_statcache.st_mtime)));
- PUSHs(sv_2mortal(newSVnv(PL_statcache.st_ctime)));
-#else
- PUSHs(sv_2mortal(newSViv(PL_statcache.st_atime)));
- PUSHs(sv_2mortal(newSViv(PL_statcache.st_mtime)));
- PUSHs(sv_2mortal(newSViv(PL_statcache.st_ctime)));
-#endif
-#ifdef USE_STAT_BLOCKS
- PUSHs(sv_2mortal(newSVuv(PL_statcache.st_blksize)));
- PUSHs(sv_2mortal(newSVuv(PL_statcache.st_blocks)));
-#else
- PUSHs(sv_2mortal(newSVpvn("", 0)));
- PUSHs(sv_2mortal(newSVpvn("", 0)));
-#endif
- }
- RETURN;
-}
-
-PP(pp_ftrread)
-{
- I32 result;
- dSP;
-#if defined(HAS_ACCESS) && defined(R_OK)
- STRLEN n_a;
- if ((PL_hints & HINT_FILETEST_ACCESS) && SvPOK(TOPs)) {
- result = access(TOPpx, R_OK);
- if (result == 0)
- RETPUSHYES;
- if (result < 0)
- RETPUSHUNDEF;
- RETPUSHNO;
- }
- else
- result = my_stat();
-#else
- result = my_stat();
-#endif
- SPAGAIN;
- if (result < 0)
- RETPUSHUNDEF;
- if (cando(S_IRUSR, 0, &PL_statcache))
- RETPUSHYES;
- RETPUSHNO;
-}
-
-PP(pp_ftrwrite)
-{
- I32 result;
- dSP;
-#if defined(HAS_ACCESS) && defined(W_OK)
- STRLEN n_a;
- if ((PL_hints & HINT_FILETEST_ACCESS) && SvPOK(TOPs)) {
- result = access(TOPpx, W_OK);
- if (result == 0)
- RETPUSHYES;
- if (result < 0)
- RETPUSHUNDEF;
- RETPUSHNO;
- }
- else
- result = my_stat();
-#else
- result = my_stat();
-#endif
- SPAGAIN;
- if (result < 0)
- RETPUSHUNDEF;
- if (cando(S_IWUSR, 0, &PL_statcache))
- RETPUSHYES;
- RETPUSHNO;
-}
-
-PP(pp_ftrexec)
-{
- I32 result;
- dSP;
-#if defined(HAS_ACCESS) && defined(X_OK)
- STRLEN n_a;
- if ((PL_hints & HINT_FILETEST_ACCESS) && SvPOK(TOPs)) {
- result = access(TOPpx, X_OK);
- if (result == 0)
- RETPUSHYES;
- if (result < 0)
- RETPUSHUNDEF;
- RETPUSHNO;
- }
- else
- result = my_stat();
-#else
- result = my_stat();
-#endif
- SPAGAIN;
- if (result < 0)
- RETPUSHUNDEF;
- if (cando(S_IXUSR, 0, &PL_statcache))
- RETPUSHYES;
- RETPUSHNO;
-}
-
-PP(pp_fteread)
-{
- I32 result;
- dSP;
-#ifdef PERL_EFF_ACCESS_R_OK
- STRLEN n_a;
- if ((PL_hints & HINT_FILETEST_ACCESS) && SvPOK(TOPs)) {
- result = PERL_EFF_ACCESS_R_OK(TOPpx);
- if (result == 0)
- RETPUSHYES;
- if (result < 0)
- RETPUSHUNDEF;
- RETPUSHNO;
- }
- else
- result = my_stat();
-#else
- result = my_stat();
-#endif
- SPAGAIN;
- if (result < 0)
- RETPUSHUNDEF;
- if (cando(S_IRUSR, 1, &PL_statcache))
- RETPUSHYES;
- RETPUSHNO;
-}
-
-PP(pp_ftewrite)
-{
- I32 result;
- dSP;
-#ifdef PERL_EFF_ACCESS_W_OK
- STRLEN n_a;
- if ((PL_hints & HINT_FILETEST_ACCESS) && SvPOK(TOPs)) {
- result = PERL_EFF_ACCESS_W_OK(TOPpx);
- if (result == 0)
- RETPUSHYES;
- if (result < 0)
- RETPUSHUNDEF;
- RETPUSHNO;
- }
- else
- result = my_stat();
-#else
- result = my_stat();
-#endif
- SPAGAIN;
- if (result < 0)
- RETPUSHUNDEF;
- if (cando(S_IWUSR, 1, &PL_statcache))
- RETPUSHYES;
- RETPUSHNO;
-}
-
-PP(pp_fteexec)
-{
- I32 result;
- dSP;
-#ifdef PERL_EFF_ACCESS_X_OK
- STRLEN n_a;
- if ((PL_hints & HINT_FILETEST_ACCESS) && SvPOK(TOPs)) {
- result = PERL_EFF_ACCESS_X_OK(TOPpx);
- if (result == 0)
- RETPUSHYES;
- if (result < 0)
- RETPUSHUNDEF;
- RETPUSHNO;
- }
- else
- result = my_stat();
-#else
- result = my_stat();
-#endif
- SPAGAIN;
- if (result < 0)
- RETPUSHUNDEF;
- if (cando(S_IXUSR, 1, &PL_statcache))
- RETPUSHYES;
- RETPUSHNO;
-}
-
-PP(pp_ftis)
-{
- I32 result = my_stat();
- dSP;
- if (result < 0)
- RETPUSHUNDEF;
- RETPUSHYES;
-}
-
-PP(pp_fteowned)
-{
- return pp_ftrowned();
-}
-
-PP(pp_ftrowned)
-{
- I32 result = my_stat();
- dSP;
- if (result < 0)
- RETPUSHUNDEF;
- if (PL_statcache.st_uid == (PL_op->op_type == OP_FTEOWNED ?
- PL_euid : PL_uid) )
- RETPUSHYES;
- RETPUSHNO;
-}
-
-PP(pp_ftzero)
-{
- I32 result = my_stat();
- dSP;
- if (result < 0)
- RETPUSHUNDEF;
- if (PL_statcache.st_size == 0)
- RETPUSHYES;
- RETPUSHNO;
-}
-
-PP(pp_ftsize)
-{
- I32 result = my_stat();
- dSP; dTARGET;
- if (result < 0)
- RETPUSHUNDEF;
-#if Off_t_size > IVSIZE
- PUSHn(PL_statcache.st_size);
-#else
- PUSHi(PL_statcache.st_size);
-#endif
- RETURN;
-}
-
-PP(pp_ftmtime)
-{
- I32 result = my_stat();
- dSP; dTARGET;
- if (result < 0)
- RETPUSHUNDEF;
- PUSHn( (PL_basetime - PL_statcache.st_mtime) / 86400.0 );
- RETURN;
-}
-
-PP(pp_ftatime)
-{
- I32 result = my_stat();
- dSP; dTARGET;
- if (result < 0)
- RETPUSHUNDEF;
- PUSHn( (PL_basetime - PL_statcache.st_atime) / 86400.0 );
- RETURN;
-}
-
-PP(pp_ftctime)
-{
- I32 result = my_stat();
- dSP; dTARGET;
- if (result < 0)
- RETPUSHUNDEF;
- PUSHn( (PL_basetime - PL_statcache.st_ctime) / 86400.0 );
- RETURN;
-}
-
-PP(pp_ftsock)
-{
- I32 result = my_stat();
- dSP;
- if (result < 0)
- RETPUSHUNDEF;
- if (S_ISSOCK(PL_statcache.st_mode))
- RETPUSHYES;
- RETPUSHNO;
-}
-
-PP(pp_ftchr)
-{
- I32 result = my_stat();
- dSP;
- if (result < 0)
- RETPUSHUNDEF;
- if (S_ISCHR(PL_statcache.st_mode))
- RETPUSHYES;
- RETPUSHNO;
-}
-
-PP(pp_ftblk)
-{
- I32 result = my_stat();
- dSP;
- if (result < 0)
- RETPUSHUNDEF;
- if (S_ISBLK(PL_statcache.st_mode))
- RETPUSHYES;
- RETPUSHNO;
-}
-
-PP(pp_ftfile)
-{
- I32 result = my_stat();
- dSP;
- if (result < 0)
- RETPUSHUNDEF;
- if (S_ISREG(PL_statcache.st_mode))
- RETPUSHYES;
- RETPUSHNO;
-}
-
-PP(pp_ftdir)
-{
- I32 result = my_stat();
- dSP;
- if (result < 0)
- RETPUSHUNDEF;
- if (S_ISDIR(PL_statcache.st_mode))
- RETPUSHYES;
- RETPUSHNO;
-}
-
-PP(pp_ftpipe)
-{
- I32 result = my_stat();
- dSP;
- if (result < 0)
- RETPUSHUNDEF;
- if (S_ISFIFO(PL_statcache.st_mode))
- RETPUSHYES;
- RETPUSHNO;
-}
-
-PP(pp_ftlink)
-{
- I32 result = my_lstat();
- dSP;
- if (result < 0)
- RETPUSHUNDEF;
- if (S_ISLNK(PL_statcache.st_mode))
- RETPUSHYES;
- RETPUSHNO;
-}
-
-PP(pp_ftsuid)
-{
- dSP;
-#ifdef S_ISUID
- I32 result = my_stat();
- SPAGAIN;
- if (result < 0)
- RETPUSHUNDEF;
- if (PL_statcache.st_mode & S_ISUID)
- RETPUSHYES;
-#endif
- RETPUSHNO;
-}
-
-PP(pp_ftsgid)
-{
- dSP;
-#ifdef S_ISGID
- I32 result = my_stat();
- SPAGAIN;
- if (result < 0)
- RETPUSHUNDEF;
- if (PL_statcache.st_mode & S_ISGID)
- RETPUSHYES;
-#endif
- RETPUSHNO;
-}
-
-PP(pp_ftsvtx)
-{
- dSP;
-#ifdef S_ISVTX
- I32 result = my_stat();
- SPAGAIN;
- if (result < 0)
- RETPUSHUNDEF;
- if (PL_statcache.st_mode & S_ISVTX)
- RETPUSHYES;
-#endif
- RETPUSHNO;
-}
-
-PP(pp_fttty)
-{
- dSP;
- int fd;
- GV *gv;
- char *tmps = Nullch;
- STRLEN n_a;
-
- if (PL_op->op_flags & OPf_REF)
- gv = cGVOP_gv;
- else if (isGV(TOPs))
- gv = (GV*)POPs;
- else if (SvROK(TOPs) && isGV(SvRV(TOPs)))
- gv = (GV*)SvRV(POPs);
- else
- gv = gv_fetchpv(tmps = POPpx, FALSE, SVt_PVIO);
-
- if (GvIO(gv) && IoIFP(GvIOp(gv)))
- fd = PerlIO_fileno(IoIFP(GvIOp(gv)));
- else if (tmps && isDIGIT(*tmps))
- fd = atoi(tmps);
- else
- RETPUSHUNDEF;
- if (PerlLIO_isatty(fd))
- RETPUSHYES;
- RETPUSHNO;
-}
-
-#if defined(atarist) /* this will work with atariST. Configure will
- make guesses for other systems. */
-# define FILE_base(f) ((f)->_base)
-# define FILE_ptr(f) ((f)->_ptr)
-# define FILE_cnt(f) ((f)->_cnt)
-# define FILE_bufsiz(f) ((f)->_cnt + ((f)->_ptr - (f)->_base))
-#endif
-
-PP(pp_fttext)
-{
- dSP;
- I32 i;
- I32 len;
- I32 odd = 0;
- STDCHAR tbuf[512];
- register STDCHAR *s;
- register IO *io;
- register SV *sv;
- GV *gv;
- STRLEN n_a;
- PerlIO *fp;
-
- if (PL_op->op_flags & OPf_REF)
- gv = cGVOP_gv;
- else if (isGV(TOPs))
- gv = (GV*)POPs;
- else if (SvROK(TOPs) && isGV(SvRV(TOPs)))
- gv = (GV*)SvRV(POPs);
- else
- gv = Nullgv;
-
- if (gv) {
- EXTEND(SP, 1);
- if (gv == PL_defgv) {
- if (PL_statgv)
- io = GvIO(PL_statgv);
- else {
- sv = PL_statname;
- goto really_filename;
- }
- }
- else {
- PL_statgv = gv;
- PL_laststatval = -1;
- sv_setpv(PL_statname, "");
- io = GvIO(PL_statgv);
- }
- if (io && IoIFP(io)) {
- if (! PerlIO_has_base(IoIFP(io)))
- DIE(aTHX_ "-T and -B not implemented on filehandles");
- PL_laststatval = PerlLIO_fstat(PerlIO_fileno(IoIFP(io)), &PL_statcache);
- if (PL_laststatval < 0)
- RETPUSHUNDEF;
- if (S_ISDIR(PL_statcache.st_mode)) /* handle NFS glitch */
- if (PL_op->op_type == OP_FTTEXT)
- RETPUSHNO;
- else
- RETPUSHYES;
- if (PerlIO_get_cnt(IoIFP(io)) <= 0) {
- i = PerlIO_getc(IoIFP(io));
- if (i != EOF)
- (void)PerlIO_ungetc(IoIFP(io),i);
- }
- if (PerlIO_get_cnt(IoIFP(io)) <= 0) /* null file is anything */
- RETPUSHYES;
- len = PerlIO_get_bufsiz(IoIFP(io));
- s = (STDCHAR *) PerlIO_get_base(IoIFP(io));
- /* sfio can have large buffers - limit to 512 */
- if (len > 512)
- len = 512;
- }
- else {
- if (ckWARN2(WARN_UNOPENED,WARN_CLOSED)) {
- gv = cGVOP_gv;
- report_evil_fh(gv, GvIO(gv), PL_op->op_type);
- }
- SETERRNO(EBADF,RMS$_IFI);
- RETPUSHUNDEF;
- }
- }
- else {
- sv = POPs;
- really_filename:
- PL_statgv = Nullgv;
- PL_laststatval = -1;
- sv_setpv(PL_statname, SvPV(sv, n_a));
- if (!(fp = PerlIO_open(SvPVX(PL_statname), "r"))) {
- if (ckWARN(WARN_NEWLINE) && strchr(SvPV(sv, n_a), '\n'))
- Perl_warner(aTHX_ WARN_NEWLINE, PL_warn_nl, "open");
- RETPUSHUNDEF;
- }
- PL_laststatval = PerlLIO_fstat(PerlIO_fileno(fp), &PL_statcache);
- if (PL_laststatval < 0) {
- (void)PerlIO_close(fp);
- RETPUSHUNDEF;
- }
- do_binmode(fp, '<', O_BINARY);
- len = PerlIO_read(fp, tbuf, sizeof(tbuf));
- (void)PerlIO_close(fp);
- if (len <= 0) {
- if (S_ISDIR(PL_statcache.st_mode) && PL_op->op_type == OP_FTTEXT)
- RETPUSHNO; /* special case NFS directories */
- RETPUSHYES; /* null file is anything */
- }
- s = tbuf;
- }
-
- /* now scan s to look for textiness */
- /* XXX ASCII dependent code */
-
-#if defined(DOSISH) || defined(USEMYBINMODE)
- /* ignore trailing ^Z on short files */
- if (len && len < sizeof(tbuf) && tbuf[len-1] == 26)
- --len;
-#endif
-
- for (i = 0; i < len; i++, s++) {
- if (!*s) { /* null never allowed in text */
- odd += len;
- break;
- }
-#ifdef EBCDIC
- else if (!(isPRINT(*s) || isSPACE(*s)))
- odd++;
-#else
- else if (*s & 128) {
-#ifdef USE_LOCALE
- if ((PL_op->op_private & OPpLOCALE) && isALPHA_LC(*s))
- continue;
-#endif
- /* utf8 characters don't count as odd */
- if (UTF8_IS_START(*s)) {
- int ulen = UTF8SKIP(s);
- if (ulen < len - i) {
- int j;
- for (j = 1; j < ulen; j++) {
- if (!UTF8_IS_CONTINUATION(s[j]))
- goto not_utf8;
- }
- --ulen; /* loop does extra increment */
- s += ulen;
- i += ulen;
- continue;
- }
- }
- not_utf8:
- odd++;
- }
- else if (*s < 32 &&
- *s != '\n' && *s != '\r' && *s != '\b' &&
- *s != '\t' && *s != '\f' && *s != 27)
- odd++;
-#endif
- }
-
- if ((odd * 3 > len) == (PL_op->op_type == OP_FTTEXT)) /* allow 1/3 odd */
- RETPUSHNO;
- else
- RETPUSHYES;
-}
-
-PP(pp_ftbinary)
-{
- return pp_fttext();
-}
-
-/* File calls. */
-
-PP(pp_chdir)
-{
- dSP; dTARGET;
- char *tmps;
- SV **svp;
- STRLEN n_a;
-
- if (MAXARG < 1)
- tmps = Nullch;
- else
- tmps = POPpx;
- if (!tmps || !*tmps) {
- svp = hv_fetch(GvHVn(PL_envgv), "HOME", 4, FALSE);
- if (svp)
- tmps = SvPV(*svp, n_a);
- }
- if (!tmps || !*tmps) {
- svp = hv_fetch(GvHVn(PL_envgv), "LOGDIR", 6, FALSE);
- if (svp)
- tmps = SvPV(*svp, n_a);
- }
-#ifdef VMS
- if (!tmps || !*tmps) {
- svp = hv_fetch(GvHVn(PL_envgv), "SYS$LOGIN", 9, FALSE);
- if (svp)
- tmps = SvPV(*svp, n_a);
- }
-#endif
- TAINT_PROPER("chdir");
- PUSHi( PerlDir_chdir(tmps) >= 0 );
-#ifdef VMS
- /* Clear the DEFAULT element of ENV so we'll get the new value
- * in the future. */
- hv_delete(GvHVn(PL_envgv),"DEFAULT",7,G_DISCARD);
-#endif
- RETURN;
-}
-
-PP(pp_chown)
-{
- dSP; dMARK; dTARGET;
- I32 value;
-#ifdef HAS_CHOWN
- value = (I32)apply(PL_op->op_type, MARK, SP);
- SP = MARK;
- PUSHi(value);
- RETURN;
-#else
- DIE(aTHX_ PL_no_func, "Unsupported function chown");
-#endif
-}
-
-PP(pp_chroot)
-{
- dSP; dTARGET;
- char *tmps;
-#ifdef HAS_CHROOT
- STRLEN n_a;
- tmps = POPpx;
- TAINT_PROPER("chroot");
- PUSHi( chroot(tmps) >= 0 );
- RETURN;
-#else
- DIE(aTHX_ PL_no_func, "chroot");
-#endif
-}
-
-PP(pp_unlink)
-{
- dSP; dMARK; dTARGET;
- I32 value;
- value = (I32)apply(PL_op->op_type, MARK, SP);
- SP = MARK;
- PUSHi(value);
- RETURN;
-}
-
-PP(pp_chmod)
-{
- dSP; dMARK; dTARGET;
- I32 value;
- value = (I32)apply(PL_op->op_type, MARK, SP);
- SP = MARK;
- PUSHi(value);
- RETURN;
-}
-
-PP(pp_utime)
-{
- dSP; dMARK; dTARGET;
- I32 value;
- value = (I32)apply(PL_op->op_type, MARK, SP);
- SP = MARK;
- PUSHi(value);
- RETURN;
-}
-
-PP(pp_rename)
-{
- dSP; dTARGET;
- int anum;
- STRLEN n_a;
-
- char *tmps2 = POPpx;
- char *tmps = SvPV(TOPs, n_a);
- TAINT_PROPER("rename");
-#ifdef HAS_RENAME
- anum = PerlLIO_rename(tmps, tmps2);
-#else
- if (!(anum = PerlLIO_stat(tmps, &PL_statbuf))) {
- if (same_dirent(tmps2, tmps)) /* can always rename to same name */
- anum = 1;
- else {
- if (PL_euid || PerlLIO_stat(tmps2, &PL_statbuf) < 0 || !S_ISDIR(PL_statbuf.st_mode))
- (void)UNLINK(tmps2);
- if (!(anum = link(tmps, tmps2)))
- anum = UNLINK(tmps);
- }
- }
-#endif
- SETi( anum >= 0 );
- RETURN;
-}
-
-PP(pp_link)
-{
- dSP; dTARGET;
-#ifdef HAS_LINK
- STRLEN n_a;
- char *tmps2 = POPpx;
- char *tmps = SvPV(TOPs, n_a);
- TAINT_PROPER("link");
- SETi( PerlLIO_link(tmps, tmps2) >= 0 );
-#else
- DIE(aTHX_ PL_no_func, "Unsupported function link");
-#endif
- RETURN;
-}
-
-PP(pp_symlink)
-{
- dSP; dTARGET;
-#ifdef HAS_SYMLINK
- STRLEN n_a;
- char *tmps2 = POPpx;
- char *tmps = SvPV(TOPs, n_a);
- TAINT_PROPER("symlink");
- SETi( symlink(tmps, tmps2) >= 0 );
- RETURN;
-#else
- DIE(aTHX_ PL_no_func, "symlink");
-#endif
-}
-
-PP(pp_readlink)
-{
- dSP; dTARGET;
-#ifdef HAS_SYMLINK
- char *tmps;
- char buf[MAXPATHLEN];
- int len;
- STRLEN n_a;
-
-#ifndef INCOMPLETE_TAINTS
- TAINT;
-#endif
- tmps = POPpx;
- len = readlink(tmps, buf, sizeof buf);
- EXTEND(SP, 1);
- if (len < 0)
- RETPUSHUNDEF;
- PUSHp(buf, len);
- RETURN;
-#else
- EXTEND(SP, 1);
- RETSETUNDEF; /* just pretend it's a normal file */
-#endif
-}
-
-#if !defined(HAS_MKDIR) || !defined(HAS_RMDIR)
-STATIC int
-S_dooneliner(pTHX_ char *cmd, char *filename)
-{
- char *save_filename = filename;
- char *cmdline;
- char *s;
- PerlIO *myfp;
- int anum = 1;
-
- New(666, cmdline, strlen(cmd) + (strlen(filename) * 2) + 10, char);
- strcpy(cmdline, cmd);
- strcat(cmdline, " ");
- for (s = cmdline + strlen(cmdline); *filename; ) {
- *s++ = '\\';
- *s++ = *filename++;
- }
- strcpy(s, " 2>&1");
- myfp = PerlProc_popen(cmdline, "r");
- Safefree(cmdline);
-
- if (myfp) {
- SV *tmpsv = sv_newmortal();
- /* Need to save/restore 'PL_rs' ?? */
- s = sv_gets(tmpsv, myfp, 0);
- (void)PerlProc_pclose(myfp);
- if (s != Nullch) {
- int e;
- for (e = 1;
-#ifdef HAS_SYS_ERRLIST
- e <= sys_nerr
-#endif
- ; e++)
- {
- /* you don't see this */
- char *errmsg =
-#ifdef HAS_SYS_ERRLIST
- sys_errlist[e]
-#else
- strerror(e)
-#endif
- ;
- if (!errmsg)
- break;
- if (instr(s, errmsg)) {
- SETERRNO(e,0);
- return 0;
- }
- }
- SETERRNO(0,0);
-#ifndef EACCES
-#define EACCES EPERM
-#endif
- if (instr(s, "cannot make"))
- SETERRNO(EEXIST,RMS$_FEX);
- else if (instr(s, "existing file"))
- SETERRNO(EEXIST,RMS$_FEX);
- else if (instr(s, "ile exists"))
- SETERRNO(EEXIST,RMS$_FEX);
- else if (instr(s, "non-exist"))
- SETERRNO(ENOENT,RMS$_FNF);
- else if (instr(s, "does not exist"))
- SETERRNO(ENOENT,RMS$_FNF);
- else if (instr(s, "not empty"))
- SETERRNO(EBUSY,SS$_DEVOFFLINE);
- else if (instr(s, "cannot access"))
- SETERRNO(EACCES,RMS$_PRV);
- else
- SETERRNO(EPERM,RMS$_PRV);
- return 0;
- }
- else { /* some mkdirs return no failure indication */
- anum = (PerlLIO_stat(save_filename, &PL_statbuf) >= 0);
- if (PL_op->op_type == OP_RMDIR)
- anum = !anum;
- if (anum)
- SETERRNO(0,0);
- else
- SETERRNO(EACCES,RMS$_PRV); /* a guess */
- }
- return anum;
- }
- else
- return 0;
-}
-#endif
-
-PP(pp_mkdir)
-{
- dSP; dTARGET;
- int mode;
-#ifndef HAS_MKDIR
- int oldumask;
-#endif
- STRLEN n_a;
- char *tmps;
-
- if (MAXARG > 1)
- mode = POPi;
- else
- mode = 0777;
-
- tmps = SvPV(TOPs, n_a);
-
- TAINT_PROPER("mkdir");
-#ifdef HAS_MKDIR
- SETi( PerlDir_mkdir(tmps, mode) >= 0 );
-#else
- SETi( dooneliner("mkdir", tmps) );
- oldumask = PerlLIO_umask(0);
- PerlLIO_umask(oldumask);
- PerlLIO_chmod(tmps, (mode & ~oldumask) & 0777);
-#endif
- RETURN;
-}
-
-PP(pp_rmdir)
-{
- dSP; dTARGET;
- char *tmps;
- STRLEN n_a;
-
- tmps = POPpx;
- TAINT_PROPER("rmdir");
-#ifdef HAS_RMDIR
- XPUSHi( PerlDir_rmdir(tmps) >= 0 );
-#else
- XPUSHi( dooneliner("rmdir", tmps) );
-#endif
- RETURN;
-}
-
-/* Directory calls. */
-
-PP(pp_open_dir)
-{
- dSP;
-#if defined(Direntry_t) && defined(HAS_READDIR)
- STRLEN n_a;
- char *dirname = POPpx;
- GV *gv = (GV*)POPs;
- register IO *io = GvIOn(gv);
-
- if (!io)
- goto nope;
-
- if (IoDIRP(io))
- PerlDir_close(IoDIRP(io));
- if (!(IoDIRP(io) = PerlDir_open(dirname)))
- goto nope;
-
- RETPUSHYES;
-nope:
- if (!errno)
- SETERRNO(EBADF,RMS$_DIR);
- RETPUSHUNDEF;
-#else
- DIE(aTHX_ PL_no_dir_func, "opendir");
-#endif
-}
-
-PP(pp_readdir)
-{
- dSP;
-#if defined(Direntry_t) && defined(HAS_READDIR)
-#ifndef I_DIRENT
- Direntry_t *readdir (DIR *);
-#endif
- register Direntry_t *dp;
- GV *gv = (GV*)POPs;
- register IO *io = GvIOn(gv);
- SV *sv;
-
- if (!io || !IoDIRP(io))
- goto nope;
-
- if (GIMME == G_ARRAY) {
- /*SUPPRESS 560*/
- while ((dp = (Direntry_t *)PerlDir_read(IoDIRP(io)))) {
-#ifdef DIRNAMLEN
- sv = newSVpvn(dp->d_name, dp->d_namlen);
-#else
- sv = newSVpv(dp->d_name, 0);
-#endif
-#ifndef INCOMPLETE_TAINTS
- if (!(IoFLAGS(io) & IOf_UNTAINT))
- SvTAINTED_on(sv);
-#endif
- XPUSHs(sv_2mortal(sv));
- }
- }
- else {
- if (!(dp = (Direntry_t *)PerlDir_read(IoDIRP(io))))
- goto nope;
-#ifdef DIRNAMLEN
- sv = newSVpvn(dp->d_name, dp->d_namlen);
-#else
- sv = newSVpv(dp->d_name, 0);
-#endif
-#ifndef INCOMPLETE_TAINTS
- if (!(IoFLAGS(io) & IOf_UNTAINT))
- SvTAINTED_on(sv);
-#endif
- XPUSHs(sv_2mortal(sv));
- }
- RETURN;
-
-nope:
- if (!errno)
- SETERRNO(EBADF,RMS$_ISI);
- if (GIMME == G_ARRAY)
- RETURN;
- else
- RETPUSHUNDEF;
-#else
- DIE(aTHX_ PL_no_dir_func, "readdir");
-#endif
-}
-
-PP(pp_telldir)
-{
- dSP; dTARGET;
-#if defined(HAS_TELLDIR) || defined(telldir)
- /* XXX does _anyone_ need this? --AD 2/20/1998 */
- /* XXX netbsd still seemed to.
- XXX HAS_TELLDIR_PROTO is new style, NEED_TELLDIR_PROTO is old style.
- --JHI 1999-Feb-02 */
-# if !defined(HAS_TELLDIR_PROTO) || defined(NEED_TELLDIR_PROTO)
- long telldir (DIR *);
-# endif
- GV *gv = (GV*)POPs;
- register IO *io = GvIOn(gv);
-
- if (!io || !IoDIRP(io))
- goto nope;
-
- PUSHi( PerlDir_tell(IoDIRP(io)) );
- RETURN;
-nope:
- if (!errno)
- SETERRNO(EBADF,RMS$_ISI);
- RETPUSHUNDEF;
-#else
- DIE(aTHX_ PL_no_dir_func, "telldir");
-#endif
-}
-
-PP(pp_seekdir)
-{
- dSP;
-#if defined(HAS_SEEKDIR) || defined(seekdir)
- long along = POPl;
- GV *gv = (GV*)POPs;
- register IO *io = GvIOn(gv);
-
- if (!io || !IoDIRP(io))
- goto nope;
-
- (void)PerlDir_seek(IoDIRP(io), along);
-
- RETPUSHYES;
-nope:
- if (!errno)
- SETERRNO(EBADF,RMS$_ISI);
- RETPUSHUNDEF;
-#else
- DIE(aTHX_ PL_no_dir_func, "seekdir");
-#endif
-}
-
-PP(pp_rewinddir)
-{
- dSP;
-#if defined(HAS_REWINDDIR) || defined(rewinddir)
- GV *gv = (GV*)POPs;
- register IO *io = GvIOn(gv);
-
- if (!io || !IoDIRP(io))
- goto nope;
-
- (void)PerlDir_rewind(IoDIRP(io));
- RETPUSHYES;
-nope:
- if (!errno)
- SETERRNO(EBADF,RMS$_ISI);
- RETPUSHUNDEF;
-#else
- DIE(aTHX_ PL_no_dir_func, "rewinddir");
-#endif
-}
-
-PP(pp_closedir)
-{
- dSP;
-#if defined(Direntry_t) && defined(HAS_READDIR)
- GV *gv = (GV*)POPs;
- register IO *io = GvIOn(gv);
-
- if (!io || !IoDIRP(io))
- goto nope;
-
-#ifdef VOID_CLOSEDIR
- PerlDir_close(IoDIRP(io));
-#else
- if (PerlDir_close(IoDIRP(io)) < 0) {
- IoDIRP(io) = 0; /* Don't try to close again--coredumps on SysV */
- goto nope;
- }
-#endif
- IoDIRP(io) = 0;
-
- RETPUSHYES;
-nope:
- if (!errno)
- SETERRNO(EBADF,RMS$_IFI);
- RETPUSHUNDEF;
-#else
- DIE(aTHX_ PL_no_dir_func, "closedir");
-#endif
-}
-
-/* Process control. */
-
-PP(pp_fork)
-{
-#ifdef HAS_FORK
- dSP; dTARGET;
- Pid_t childpid;
- GV *tmpgv;
-
- EXTEND(SP, 1);
- PERL_FLUSHALL_FOR_CHILD;
- childpid = fork();
- if (childpid < 0)
- RETSETUNDEF;
- if (!childpid) {
- /*SUPPRESS 560*/
- if ((tmpgv = gv_fetchpv("$", TRUE, SVt_PV)))
- sv_setiv(GvSV(tmpgv), (IV)PerlProc_getpid());
- hv_clear(PL_pidstatus); /* no kids, so don't wait for 'em */
- }
- PUSHi(childpid);
- RETURN;
-#else
-# if defined(USE_ITHREADS) && defined(PERL_IMPLICIT_SYS)
- dSP; dTARGET;
- Pid_t childpid;
-
- EXTEND(SP, 1);
- PERL_FLUSHALL_FOR_CHILD;
- childpid = PerlProc_fork();
- if (childpid == -1)
- RETSETUNDEF;
- PUSHi(childpid);
- RETURN;
-# else
- DIE(aTHX_ PL_no_func, "Unsupported function fork");
-# endif
-#endif
-}
-
-PP(pp_wait)
-{
-#if (!defined(DOSISH) || defined(OS2) || defined(WIN32)) && !defined(MACOS_TRADITIONAL)
- dSP; dTARGET;
- Pid_t childpid;
- int argflags;
-
- childpid = wait4pid(-1, &argflags, 0);
-# if defined(USE_ITHREADS) && defined(PERL_IMPLICIT_SYS)
- /* 0 and -1 are both error returns (the former applies to WNOHANG case) */
- STATUS_NATIVE_SET((childpid && childpid != -1) ? argflags : -1);
-# else
- STATUS_NATIVE_SET((childpid > 0) ? argflags : -1);
-# endif
- XPUSHi(childpid);
- RETURN;
-#else
- DIE(aTHX_ PL_no_func, "Unsupported function wait");
-#endif
-}
-
-PP(pp_waitpid)
-{
-#if (!defined(DOSISH) || defined(OS2) || defined(WIN32)) && !defined(MACOS_TRADITIONAL)
- dSP; dTARGET;
- Pid_t childpid;
- int optype;
- int argflags;
-
- optype = POPi;
- childpid = TOPi;
- childpid = wait4pid(childpid, &argflags, optype);
-# if defined(USE_ITHREADS) && defined(PERL_IMPLICIT_SYS)
- /* 0 and -1 are both error returns (the former applies to WNOHANG case) */
- STATUS_NATIVE_SET((childpid && childpid != -1) ? argflags : -1);
-# else
- STATUS_NATIVE_SET((childpid > 0) ? argflags : -1);
-# endif
- SETi(childpid);
- RETURN;
-#else
- DIE(aTHX_ PL_no_func, "Unsupported function waitpid");
-#endif
-}
-
-PP(pp_system)
-{
- dSP; dMARK; dORIGMARK; dTARGET;
- I32 value;
- Pid_t childpid;
- int result;
- int status;
- Sigsave_t ihand,qhand; /* place to save signals during system() */
- STRLEN n_a;
- I32 did_pipes = 0;
- int pp[2];
-
- if (SP - MARK == 1) {
- if (PL_tainting) {
- char *junk = SvPV(TOPs, n_a);
- TAINT_ENV();
- TAINT_PROPER("system");
- }
- }
- PERL_FLUSHALL_FOR_CHILD;
-#if (defined(HAS_FORK) || defined(AMIGAOS)) && !defined(VMS) && !defined(OS2) && !defined(__CYGWIN__)
- if (PerlProc_pipe(pp) >= 0)
- did_pipes = 1;
- while ((childpid = vfork()) == -1) {
- if (errno != EAGAIN) {
- value = -1;
- SP = ORIGMARK;
- PUSHi(value);
- if (did_pipes) {
- PerlLIO_close(pp[0]);
- PerlLIO_close(pp[1]);
- }
- RETURN;
- }
- sleep(5);
- }
- if (childpid > 0) {
- if (did_pipes)
- PerlLIO_close(pp[1]);
- rsignal_save(SIGINT, SIG_IGN, &ihand);
- rsignal_save(SIGQUIT, SIG_IGN, &qhand);
- do {
- result = wait4pid(childpid, &status, 0);
- } while (result == -1 && errno == EINTR);
- (void)rsignal_restore(SIGINT, &ihand);
- (void)rsignal_restore(SIGQUIT, &qhand);
- STATUS_NATIVE_SET(result == -1 ? -1 : status);
- do_execfree(); /* free any memory child malloced on vfork */
- SP = ORIGMARK;
- if (did_pipes) {
- int errkid;
- int n = 0, n1;
-
- while (n < sizeof(int)) {
- n1 = PerlLIO_read(pp[0],
- (void*)(((char*)&errkid)+n),
- (sizeof(int)) - n);
- if (n1 <= 0)
- break;
- n += n1;
- }
- PerlLIO_close(pp[0]);
- if (n) { /* Error */
- if (n != sizeof(int))
- DIE(aTHX_ "panic: kid popen errno read");
- errno = errkid; /* Propagate errno from kid */
- STATUS_CURRENT = -1;
- }
- }
- PUSHi(STATUS_CURRENT);
- RETURN;
- }
- if (did_pipes) {
- PerlLIO_close(pp[0]);
-#if defined(HAS_FCNTL) && defined(F_SETFD)
- fcntl(pp[1], F_SETFD, FD_CLOEXEC);
-#endif
- }
- if (PL_op->op_flags & OPf_STACKED) {
- SV *really = *++MARK;
- value = (I32)do_aexec5(really, MARK, SP, pp[1], did_pipes);
- }
- else if (SP - MARK != 1)
- value = (I32)do_aexec5(Nullsv, MARK, SP, pp[1], did_pipes);
- else {
- value = (I32)do_exec3(SvPVx(sv_mortalcopy(*SP), n_a), pp[1], did_pipes);
- }
- PerlProc__exit(-1);
-#else /* ! FORK or VMS or OS/2 */
- PL_statusvalue = 0;
- result = 0;
- if (PL_op->op_flags & OPf_STACKED) {
- SV *really = *++MARK;
- value = (I32)do_aspawn(really, (void **)MARK, (void **)SP);
- }
- else if (SP - MARK != 1)
- value = (I32)do_aspawn(Nullsv, (void **)MARK, (void **)SP);
- else {
- value = (I32)do_spawn(SvPVx(sv_mortalcopy(*SP), n_a));
- }
- if (PL_statusvalue == -1) /* hint that value must be returned as is */
- result = 1;
- STATUS_NATIVE_SET(value);
- do_execfree();
- SP = ORIGMARK;
- PUSHi(result ? value : STATUS_CURRENT);
-#endif /* !FORK or VMS */
- RETURN;
-}
-
-PP(pp_exec)
-{
- dSP; dMARK; dORIGMARK; dTARGET;
- I32 value;
- STRLEN n_a;
-
- PERL_FLUSHALL_FOR_CHILD;
- if (PL_op->op_flags & OPf_STACKED) {
- SV *really = *++MARK;
- value = (I32)do_aexec(really, MARK, SP);
- }
- else if (SP - MARK != 1)
-#ifdef VMS
- value = (I32)vms_do_aexec(Nullsv, MARK, SP);
-#else
-# ifdef __OPEN_VM
- {
- (void ) do_aspawn(Nullsv, MARK, SP);
- value = 0;
- }
-# else
- value = (I32)do_aexec(Nullsv, MARK, SP);
-# endif
-#endif
- else {
- if (PL_tainting) {
- char *junk = SvPV(*SP, n_a);
- TAINT_ENV();
- TAINT_PROPER("exec");
- }
-#ifdef VMS
- value = (I32)vms_do_exec(SvPVx(sv_mortalcopy(*SP), n_a));
-#else
-# ifdef __OPEN_VM
- (void) do_spawn(SvPVx(sv_mortalcopy(*SP), n_a));
- value = 0;
-# else
- value = (I32)do_exec(SvPVx(sv_mortalcopy(*SP), n_a));
-# endif
-#endif
- }
-
-#if !defined(HAS_FORK) && defined(USE_ITHREADS) && defined(PERL_IMPLICIT_SYS)
- if (value >= 0)
- my_exit(value);
-#endif
-
- SP = ORIGMARK;
- PUSHi(value);
- RETURN;
-}
-
-PP(pp_kill)
-{
- dSP; dMARK; dTARGET;
- I32 value;
-#ifdef HAS_KILL
- value = (I32)apply(PL_op->op_type, MARK, SP);
- SP = MARK;
- PUSHi(value);
- RETURN;
-#else
- DIE(aTHX_ PL_no_func, "Unsupported function kill");
-#endif
-}
-
-PP(pp_getppid)
-{
-#ifdef HAS_GETPPID
- dSP; dTARGET;
- XPUSHi( getppid() );
- RETURN;
-#else
- DIE(aTHX_ PL_no_func, "getppid");
-#endif
-}
-
-PP(pp_getpgrp)
-{
-#ifdef HAS_GETPGRP
- dSP; dTARGET;
- Pid_t pid;
- Pid_t pgrp;
-
- if (MAXARG < 1)
- pid = 0;
- else
- pid = SvIVx(POPs);
-#ifdef BSD_GETPGRP
- pgrp = (I32)BSD_GETPGRP(pid);
-#else
- if (pid != 0 && pid != PerlProc_getpid())
- DIE(aTHX_ "POSIX getpgrp can't take an argument");
- pgrp = getpgrp();
-#endif
- XPUSHi(pgrp);
- RETURN;
-#else
- DIE(aTHX_ PL_no_func, "getpgrp()");
-#endif
-}
-
-PP(pp_setpgrp)
-{
-#ifdef HAS_SETPGRP
- dSP; dTARGET;
- Pid_t pgrp;
- Pid_t pid;
- if (MAXARG < 2) {
- pgrp = 0;
- pid = 0;
- }
- else {
- pgrp = POPi;
- pid = TOPi;
- }
-
- TAINT_PROPER("setpgrp");
-#ifdef BSD_SETPGRP
- SETi( BSD_SETPGRP(pid, pgrp) >= 0 );
-#else
- if ((pgrp != 0 && pgrp != PerlProc_getpid())
- || (pid != 0 && pid != PerlProc_getpid()))
- {
- DIE(aTHX_ "setpgrp can't take arguments");
- }
- SETi( setpgrp() >= 0 );
-#endif /* USE_BSDPGRP */
- RETURN;
-#else
- DIE(aTHX_ PL_no_func, "setpgrp()");
-#endif
-}
-
-PP(pp_getpriority)
-{
- dSP; dTARGET;
- int which;
- int who;
-#ifdef HAS_GETPRIORITY
- who = POPi;
- which = TOPi;
- SETi( getpriority(which, who) );
- RETURN;
-#else
- DIE(aTHX_ PL_no_func, "getpriority()");
-#endif
-}
-
-PP(pp_setpriority)
-{
- dSP; dTARGET;
- int which;
- int who;
- int niceval;
-#ifdef HAS_SETPRIORITY
- niceval = POPi;
- who = POPi;
- which = TOPi;
- TAINT_PROPER("setpriority");
- SETi( setpriority(which, who, niceval) >= 0 );
- RETURN;
-#else
- DIE(aTHX_ PL_no_func, "setpriority()");
-#endif
-}
-
-/* Time calls. */
-
-PP(pp_time)
-{
- dSP; dTARGET;
-#ifdef BIG_TIME
- XPUSHn( time(Null(Time_t*)) );
-#else
- XPUSHi( time(Null(Time_t*)) );
-#endif
- RETURN;
-}
-
-/* XXX The POSIX name is CLK_TCK; it is to be preferred
- to HZ. Probably. For now, assume that if the system
- defines HZ, it does so correctly. (Will this break
- on VMS?)
- Probably we ought to use _sysconf(_SC_CLK_TCK), if
- it's supported. --AD 9/96.
-*/
-
-#ifndef HZ
-# ifdef CLK_TCK
-# define HZ CLK_TCK
-# else
-# define HZ 60
-# endif
-#endif
-
-PP(pp_tms)
-{
- dSP;
-
-#ifndef HAS_TIMES
- DIE(aTHX_ "times not implemented");
-#else
- EXTEND(SP, 4);
-
-#ifndef VMS
- (void)PerlProc_times(&PL_timesbuf);
-#else
- (void)PerlProc_times((tbuffer_t *)&PL_timesbuf); /* time.h uses different name for */
- /* struct tms, though same data */
- /* is returned. */
-#endif
-
- PUSHs(sv_2mortal(newSVnv(((NV)PL_timesbuf.tms_utime)/HZ)));
- if (GIMME == G_ARRAY) {
- PUSHs(sv_2mortal(newSVnv(((NV)PL_timesbuf.tms_stime)/HZ)));
- PUSHs(sv_2mortal(newSVnv(((NV)PL_timesbuf.tms_cutime)/HZ)));
- PUSHs(sv_2mortal(newSVnv(((NV)PL_timesbuf.tms_cstime)/HZ)));
- }
- RETURN;
-#endif /* HAS_TIMES */
-}
-
-PP(pp_localtime)
-{
- return pp_gmtime();
-}
-
-PP(pp_gmtime)
-{
- dSP;
- Time_t when;
- struct tm *tmbuf;
- static char *dayname[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
- static char *monname[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
-
- if (MAXARG < 1)
- (void)time(&when);
- else
-#ifdef BIG_TIME
- when = (Time_t)SvNVx(POPs);
-#else
- when = (Time_t)SvIVx(POPs);
-#endif
-
- if (PL_op->op_type == OP_LOCALTIME)
- tmbuf = localtime(&when);
- else
- tmbuf = gmtime(&when);
-
- EXTEND(SP, 9);
- EXTEND_MORTAL(9);
- if (GIMME != G_ARRAY) {
- SV *tsv;
- if (!tmbuf)
- RETPUSHUNDEF;
- tsv = Perl_newSVpvf(aTHX_ "%s %s %2d %02d:%02d:%02d %d",
- dayname[tmbuf->tm_wday],
- monname[tmbuf->tm_mon],
- tmbuf->tm_mday,
- tmbuf->tm_hour,
- tmbuf->tm_min,
- tmbuf->tm_sec,
- tmbuf->tm_year + 1900);
- PUSHs(sv_2mortal(tsv));
- }
- else if (tmbuf) {
- PUSHs(sv_2mortal(newSViv(tmbuf->tm_sec)));
- PUSHs(sv_2mortal(newSViv(tmbuf->tm_min)));
- PUSHs(sv_2mortal(newSViv(tmbuf->tm_hour)));
- PUSHs(sv_2mortal(newSViv(tmbuf->tm_mday)));
- PUSHs(sv_2mortal(newSViv(tmbuf->tm_mon)));
- PUSHs(sv_2mortal(newSViv(tmbuf->tm_year)));
- PUSHs(sv_2mortal(newSViv(tmbuf->tm_wday)));
- PUSHs(sv_2mortal(newSViv(tmbuf->tm_yday)));
- PUSHs(sv_2mortal(newSViv(tmbuf->tm_isdst)));
- }
- RETURN;
-}
-
-PP(pp_alarm)
-{
- dSP; dTARGET;
- int anum;
-#ifdef HAS_ALARM
- anum = POPi;
- anum = alarm((unsigned int)anum);
- EXTEND(SP, 1);
- if (anum < 0)
- RETPUSHUNDEF;
- PUSHi(anum);
- RETURN;
-#else
- DIE(aTHX_ PL_no_func, "Unsupported function alarm");
-#endif
-}
-
-PP(pp_sleep)
-{
- dSP; dTARGET;
- I32 duration;
- Time_t lasttime;
- Time_t when;
-
- (void)time(&lasttime);
- if (MAXARG < 1)
- PerlProc_pause();
- else {
- duration = POPi;
- PerlProc_sleep((unsigned int)duration);
- }
- (void)time(&when);
- XPUSHi(when - lasttime);
- RETURN;
-}
-
-/* Shared memory. */
-
-PP(pp_shmget)
-{
- return pp_semget();
-}
-
-PP(pp_shmctl)
-{
- return pp_semctl();
-}
-
-PP(pp_shmread)
-{
- return pp_shmwrite();
-}
-
-PP(pp_shmwrite)
-{
-#if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
- dSP; dMARK; dTARGET;
- I32 value = (I32)(do_shmio(PL_op->op_type, MARK, SP) >= 0);
- SP = MARK;
- PUSHi(value);
- RETURN;
-#else
- return pp_semget();
-#endif
-}
-
-/* Message passing. */
-
-PP(pp_msgget)
-{
- return pp_semget();
-}
-
-PP(pp_msgctl)
-{
- return pp_semctl();
-}
-
-PP(pp_msgsnd)
-{
-#if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
- dSP; dMARK; dTARGET;
- I32 value = (I32)(do_msgsnd(MARK, SP) >= 0);
- SP = MARK;
- PUSHi(value);
- RETURN;
-#else
- return pp_semget();
-#endif
-}
-
-PP(pp_msgrcv)
-{
-#if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
- dSP; dMARK; dTARGET;
- I32 value = (I32)(do_msgrcv(MARK, SP) >= 0);
- SP = MARK;
- PUSHi(value);
- RETURN;
-#else
- return pp_semget();
-#endif
-}
-
-/* Semaphores. */
-
-PP(pp_semget)
-{
-#if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
- dSP; dMARK; dTARGET;
- int anum = do_ipcget(PL_op->op_type, MARK, SP);
- SP = MARK;
- if (anum == -1)
- RETPUSHUNDEF;
- PUSHi(anum);
- RETURN;
-#else
- DIE(aTHX_ "System V IPC is not implemented on this machine");
-#endif
-}
-
-PP(pp_semctl)
-{
-#if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
- dSP; dMARK; dTARGET;
- int anum = do_ipcctl(PL_op->op_type, MARK, SP);
- SP = MARK;
- if (anum == -1)
- RETSETUNDEF;
- if (anum != 0) {
- PUSHi(anum);
- }
- else {
- PUSHp(zero_but_true, ZBTLEN);
- }
- RETURN;
-#else
- return pp_semget();
-#endif
-}
-
-PP(pp_semop)
-{
-#if defined(HAS_MSG) || defined(HAS_SEM) || defined(HAS_SHM)
- dSP; dMARK; dTARGET;
- I32 value = (I32)(do_semop(MARK, SP) >= 0);
- SP = MARK;
- PUSHi(value);
- RETURN;
-#else
- return pp_semget();
-#endif
-}
-
-/* Get system info. */
-
-PP(pp_ghbyname)
-{
-#ifdef HAS_GETHOSTBYNAME
- return pp_ghostent();
-#else
- DIE(aTHX_ PL_no_sock_func, "gethostbyname");
-#endif
-}
-
-PP(pp_ghbyaddr)
-{
-#ifdef HAS_GETHOSTBYADDR
- return pp_ghostent();
-#else
- DIE(aTHX_ PL_no_sock_func, "gethostbyaddr");
-#endif
-}
-
-PP(pp_ghostent)
-{
- dSP;
-#if defined(HAS_GETHOSTBYNAME) || defined(HAS_GETHOSTBYADDR) || defined(HAS_GETHOSTENT)
- I32 which = PL_op->op_type;
- register char **elem;
- register SV *sv;
-#ifndef HAS_GETHOST_PROTOS /* XXX Do we need individual probes? */
- struct hostent *PerlSock_gethostbyaddr(Netdb_host_t, Netdb_hlen_t, int);
- struct hostent *PerlSock_gethostbyname(Netdb_name_t);
- struct hostent *PerlSock_gethostent(void);
-#endif
- struct hostent *hent;
- unsigned long len;
- STRLEN n_a;
-
- EXTEND(SP, 10);
- if (which == OP_GHBYNAME)
-#ifdef HAS_GETHOSTBYNAME
- hent = PerlSock_gethostbyname(POPpx);
-#else
- DIE(aTHX_ PL_no_sock_func, "gethostbyname");
-#endif
- else if (which == OP_GHBYADDR) {
-#ifdef HAS_GETHOSTBYADDR
- int addrtype = POPi;
- SV *addrsv = POPs;
- STRLEN addrlen;
- Netdb_host_t addr = (Netdb_host_t) SvPV(addrsv, addrlen);
-
- hent = PerlSock_gethostbyaddr(addr, (Netdb_hlen_t) addrlen, addrtype);
-#else
- DIE(aTHX_ PL_no_sock_func, "gethostbyaddr");
-#endif
- }
- else
-#ifdef HAS_GETHOSTENT
- hent = PerlSock_gethostent();
-#else
- DIE(aTHX_ PL_no_sock_func, "gethostent");
-#endif
-
-#ifdef HOST_NOT_FOUND
- if (!hent)
- STATUS_NATIVE_SET(h_errno);
-#endif
-
- if (GIMME != G_ARRAY) {
- PUSHs(sv = sv_newmortal());
- if (hent) {
- if (which == OP_GHBYNAME) {
- if (hent->h_addr)
- sv_setpvn(sv, hent->h_addr, hent->h_length);
- }
- else
- sv_setpv(sv, (char*)hent->h_name);
- }
- RETURN;
- }
-
- if (hent) {
- PUSHs(sv = sv_mortalcopy(&PL_sv_no));
- sv_setpv(sv, (char*)hent->h_name);
- PUSHs(sv = sv_mortalcopy(&PL_sv_no));
- for (elem = hent->h_aliases; elem && *elem; elem++) {
- sv_catpv(sv, *elem);
- if (elem[1])
- sv_catpvn(sv, " ", 1);
- }
- PUSHs(sv = sv_mortalcopy(&PL_sv_no));
- sv_setiv(sv, (IV)hent->h_addrtype);
- PUSHs(sv = sv_mortalcopy(&PL_sv_no));
- len = hent->h_length;
- sv_setiv(sv, (IV)len);
-#ifdef h_addr
- for (elem = hent->h_addr_list; elem && *elem; elem++) {
- XPUSHs(sv = sv_mortalcopy(&PL_sv_no));
- sv_setpvn(sv, *elem, len);
- }
-#else
- PUSHs(sv = sv_mortalcopy(&PL_sv_no));
- if (hent->h_addr)
- sv_setpvn(sv, hent->h_addr, len);
-#endif /* h_addr */
- }
- RETURN;
-#else
- DIE(aTHX_ PL_no_sock_func, "gethostent");
-#endif
-}
-
-PP(pp_gnbyname)
-{
-#ifdef HAS_GETNETBYNAME
- return pp_gnetent();
-#else
- DIE(aTHX_ PL_no_sock_func, "getnetbyname");
-#endif
-}
-
-PP(pp_gnbyaddr)
-{
-#ifdef HAS_GETNETBYADDR
- return pp_gnetent();
-#else
- DIE(aTHX_ PL_no_sock_func, "getnetbyaddr");
-#endif
-}
-
-PP(pp_gnetent)
-{
- dSP;
-#if defined(HAS_GETNETBYNAME) || defined(HAS_GETNETBYADDR) || defined(HAS_GETNETENT)
- I32 which = PL_op->op_type;
- register char **elem;
- register SV *sv;
-#ifndef HAS_GETNET_PROTOS /* XXX Do we need individual probes? */
- struct netent *PerlSock_getnetbyaddr(Netdb_net_t, int);
- struct netent *PerlSock_getnetbyname(Netdb_name_t);
- struct netent *PerlSock_getnetent(void);
-#endif
- struct netent *nent;
- STRLEN n_a;
-
- if (which == OP_GNBYNAME)
-#ifdef HAS_GETNETBYNAME
- nent = PerlSock_getnetbyname(POPpx);
-#else
- DIE(aTHX_ PL_no_sock_func, "getnetbyname");
-#endif
- else if (which == OP_GNBYADDR) {
-#ifdef HAS_GETNETBYADDR
- int addrtype = POPi;
- Netdb_net_t addr = (Netdb_net_t) U_L(POPn);
- nent = PerlSock_getnetbyaddr(addr, addrtype);
-#else
- DIE(aTHX_ PL_no_sock_func, "getnetbyaddr");
-#endif
- }
- else
-#ifdef HAS_GETNETENT
- nent = PerlSock_getnetent();
-#else
- DIE(aTHX_ PL_no_sock_func, "getnetent");
-#endif
-
- EXTEND(SP, 4);
- if (GIMME != G_ARRAY) {
- PUSHs(sv = sv_newmortal());
- if (nent) {
- if (which == OP_GNBYNAME)
- sv_setiv(sv, (IV)nent->n_net);
- else
- sv_setpv(sv, nent->n_name);
- }
- RETURN;
- }
-
- if (nent) {
- PUSHs(sv = sv_mortalcopy(&PL_sv_no));
- sv_setpv(sv, nent->n_name);
- PUSHs(sv = sv_mortalcopy(&PL_sv_no));
- for (elem = nent->n_aliases; elem && *elem; elem++) {
- sv_catpv(sv, *elem);
- if (elem[1])
- sv_catpvn(sv, " ", 1);
- }
- PUSHs(sv = sv_mortalcopy(&PL_sv_no));
- sv_setiv(sv, (IV)nent->n_addrtype);
- PUSHs(sv = sv_mortalcopy(&PL_sv_no));
- sv_setiv(sv, (IV)nent->n_net);
- }
-
- RETURN;
-#else
- DIE(aTHX_ PL_no_sock_func, "getnetent");
-#endif
-}
-
-PP(pp_gpbyname)
-{
-#ifdef HAS_GETPROTOBYNAME
- return pp_gprotoent();
-#else
- DIE(aTHX_ PL_no_sock_func, "getprotobyname");
-#endif
-}
-
-PP(pp_gpbynumber)
-{
-#ifdef HAS_GETPROTOBYNUMBER
- return pp_gprotoent();
-#else
- DIE(aTHX_ PL_no_sock_func, "getprotobynumber");
-#endif
-}
-
-PP(pp_gprotoent)
-{
- dSP;
-#if defined(HAS_GETPROTOBYNAME) || defined(HAS_GETPROTOBYNUMBER) || defined(HAS_GETPROTOENT)
- I32 which = PL_op->op_type;
- register char **elem;
- register SV *sv;
-#ifndef HAS_GETPROTO_PROTOS /* XXX Do we need individual probes? */
- struct protoent *PerlSock_getprotobyname(Netdb_name_t);
- struct protoent *PerlSock_getprotobynumber(int);
- struct protoent *PerlSock_getprotoent(void);
-#endif
- struct protoent *pent;
- STRLEN n_a;
-
- if (which == OP_GPBYNAME)
-#ifdef HAS_GETPROTOBYNAME
- pent = PerlSock_getprotobyname(POPpx);
-#else
- DIE(aTHX_ PL_no_sock_func, "getprotobyname");
-#endif
- else if (which == OP_GPBYNUMBER)
-#ifdef HAS_GETPROTOBYNUMBER
- pent = PerlSock_getprotobynumber(POPi);
-#else
- DIE(aTHX_ PL_no_sock_func, "getprotobynumber");
-#endif
- else
-#ifdef HAS_GETPROTOENT
- pent = PerlSock_getprotoent();
-#else
- DIE(aTHX_ PL_no_sock_func, "getprotoent");
-#endif
-
- EXTEND(SP, 3);
- if (GIMME != G_ARRAY) {
- PUSHs(sv = sv_newmortal());
- if (pent) {
- if (which == OP_GPBYNAME)
- sv_setiv(sv, (IV)pent->p_proto);
- else
- sv_setpv(sv, pent->p_name);
- }
- RETURN;
- }
-
- if (pent) {
- PUSHs(sv = sv_mortalcopy(&PL_sv_no));
- sv_setpv(sv, pent->p_name);
- PUSHs(sv = sv_mortalcopy(&PL_sv_no));
- for (elem = pent->p_aliases; elem && *elem; elem++) {
- sv_catpv(sv, *elem);
- if (elem[1])
- sv_catpvn(sv, " ", 1);
- }
- PUSHs(sv = sv_mortalcopy(&PL_sv_no));
- sv_setiv(sv, (IV)pent->p_proto);
- }
-
- RETURN;
-#else
- DIE(aTHX_ PL_no_sock_func, "getprotoent");
-#endif
-}
-
-PP(pp_gsbyname)
-{
-#ifdef HAS_GETSERVBYNAME
- return pp_gservent();
-#else
- DIE(aTHX_ PL_no_sock_func, "getservbyname");
-#endif
-}
-
-PP(pp_gsbyport)
-{
-#ifdef HAS_GETSERVBYPORT
- return pp_gservent();
-#else
- DIE(aTHX_ PL_no_sock_func, "getservbyport");
-#endif
-}
-
-PP(pp_gservent)
-{
- dSP;
-#if defined(HAS_GETSERVBYNAME) || defined(HAS_GETSERVBYPORT) || defined(HAS_GETSERVENT)
- I32 which = PL_op->op_type;
- register char **elem;
- register SV *sv;
-#ifndef HAS_GETSERV_PROTOS /* XXX Do we need individual probes? */
- struct servent *PerlSock_getservbyname(Netdb_name_t, Netdb_name_t);
- struct servent *PerlSock_getservbyport(int, Netdb_name_t);
- struct servent *PerlSock_getservent(void);
-#endif
- struct servent *sent;
- STRLEN n_a;
-
- if (which == OP_GSBYNAME) {
-#ifdef HAS_GETSERVBYNAME
- char *proto = POPpx;
- char *name = POPpx;
-
- if (proto && !*proto)
- proto = Nullch;
-
- sent = PerlSock_getservbyname(name, proto);
-#else
- DIE(aTHX_ PL_no_sock_func, "getservbyname");
-#endif
- }
- else if (which == OP_GSBYPORT) {
-#ifdef HAS_GETSERVBYPORT
- char *proto = POPpx;
- unsigned short port = POPu;
-
-#ifdef HAS_HTONS
- port = PerlSock_htons(port);
-#endif
- sent = PerlSock_getservbyport(port, proto);
-#else
- DIE(aTHX_ PL_no_sock_func, "getservbyport");
-#endif
- }
- else
-#ifdef HAS_GETSERVENT
- sent = PerlSock_getservent();
-#else
- DIE(aTHX_ PL_no_sock_func, "getservent");
-#endif
-
- EXTEND(SP, 4);
- if (GIMME != G_ARRAY) {
- PUSHs(sv = sv_newmortal());
- if (sent) {
- if (which == OP_GSBYNAME) {
-#ifdef HAS_NTOHS
- sv_setiv(sv, (IV)PerlSock_ntohs(sent->s_port));
-#else
- sv_setiv(sv, (IV)(sent->s_port));
-#endif
- }
- else
- sv_setpv(sv, sent->s_name);
- }
- RETURN;
- }
-
- if (sent) {
- PUSHs(sv = sv_mortalcopy(&PL_sv_no));
- sv_setpv(sv, sent->s_name);
- PUSHs(sv = sv_mortalcopy(&PL_sv_no));
- for (elem = sent->s_aliases; elem && *elem; elem++) {
- sv_catpv(sv, *elem);
- if (elem[1])
- sv_catpvn(sv, " ", 1);
- }
- PUSHs(sv = sv_mortalcopy(&PL_sv_no));
-#ifdef HAS_NTOHS
- sv_setiv(sv, (IV)PerlSock_ntohs(sent->s_port));
-#else
- sv_setiv(sv, (IV)(sent->s_port));
-#endif
- PUSHs(sv = sv_mortalcopy(&PL_sv_no));
- sv_setpv(sv, sent->s_proto);
- }
-
- RETURN;
-#else
- DIE(aTHX_ PL_no_sock_func, "getservent");
-#endif
-}
-
-PP(pp_shostent)
-{
- dSP;
-#ifdef HAS_SETHOSTENT
- PerlSock_sethostent(TOPi);
- RETSETYES;
-#else
- DIE(aTHX_ PL_no_sock_func, "sethostent");
-#endif
-}
-
-PP(pp_snetent)
-{
- dSP;
-#ifdef HAS_SETNETENT
- PerlSock_setnetent(TOPi);
- RETSETYES;
-#else
- DIE(aTHX_ PL_no_sock_func, "setnetent");
-#endif
-}
-
-PP(pp_sprotoent)
-{
- dSP;
-#ifdef HAS_SETPROTOENT
- PerlSock_setprotoent(TOPi);
- RETSETYES;
-#else
- DIE(aTHX_ PL_no_sock_func, "setprotoent");
-#endif
-}
-
-PP(pp_sservent)
-{
- dSP;
-#ifdef HAS_SETSERVENT
- PerlSock_setservent(TOPi);
- RETSETYES;
-#else
- DIE(aTHX_ PL_no_sock_func, "setservent");
-#endif
-}
-
-PP(pp_ehostent)
-{
- dSP;
-#ifdef HAS_ENDHOSTENT
- PerlSock_endhostent();
- EXTEND(SP,1);
- RETPUSHYES;
-#else
- DIE(aTHX_ PL_no_sock_func, "endhostent");
-#endif
-}
-
-PP(pp_enetent)
-{
- dSP;
-#ifdef HAS_ENDNETENT
- PerlSock_endnetent();
- EXTEND(SP,1);
- RETPUSHYES;
-#else
- DIE(aTHX_ PL_no_sock_func, "endnetent");
-#endif
-}
-
-PP(pp_eprotoent)
-{
- dSP;
-#ifdef HAS_ENDPROTOENT
- PerlSock_endprotoent();
- EXTEND(SP,1);
- RETPUSHYES;
-#else
- DIE(aTHX_ PL_no_sock_func, "endprotoent");
-#endif
-}
-
-PP(pp_eservent)
-{
- dSP;
-#ifdef HAS_ENDSERVENT
- PerlSock_endservent();
- EXTEND(SP,1);
- RETPUSHYES;
-#else
- DIE(aTHX_ PL_no_sock_func, "endservent");
-#endif
-}
-
-PP(pp_gpwnam)
-{
-#ifdef HAS_PASSWD
- return pp_gpwent();
-#else
- DIE(aTHX_ PL_no_func, "getpwnam");
-#endif
-}
-
-PP(pp_gpwuid)
-{
-#ifdef HAS_PASSWD
- return pp_gpwent();
-#else
- DIE(aTHX_ PL_no_func, "getpwuid");
-#endif
-}
-
-PP(pp_gpwent)
-{
- dSP;
-#ifdef HAS_PASSWD
- I32 which = PL_op->op_type;
- register SV *sv;
- STRLEN n_a;
- struct passwd *pwent = NULL;
- /*
- * We currently support only the SysV getsp* shadow password interface.
- * The interface is declared in <shadow.h> and often one needs to link
- * with -lsecurity or some such.
- * This interface is used at least by Solaris, HP-UX, IRIX, and Linux.
- * (and SCO?)
- *
- * AIX getpwnam() is clever enough to return the encrypted password
- * only if the caller (euid?) is root.
- *
- * There are at least two other shadow password APIs. Many platforms
- * seem to contain more than one interface for accessing the shadow
- * password databases, possibly for compatibility reasons.
- * The getsp*() is by far he simplest one, the other two interfaces
- * are much more complicated, but also very similar to each other.
- *
- * <sys/types.h>
- * <sys/security.h>
- * <prot.h>
- * struct pr_passwd *getprpw*();
- * The password is in
- * char getprpw*(...).ufld.fd_encrypt[]
- * Mention HAS_GETPRPWNAM here so that Configure probes for it.
- *
- * <sys/types.h>
- * <sys/security.h>
- * <prot.h>
- * struct es_passwd *getespw*();
- * The password is in
- * char *(getespw*(...).ufld.fd_encrypt)
- * Mention HAS_GETESPWNAM here so that Configure probes for it.
- *
- * Mention I_PROT here so that Configure probes for it.
- *
- * In HP-UX for getprpw*() the manual page claims that one should include
- * <hpsecurity.h> instead of <sys/security.h>, but that is not needed
- * if one includes <shadow.h> as that includes <hpsecurity.h>,
- * and pp_sys.c already includes <shadow.h> if there is such.
- *
- * Note that <sys/security.h> is already probed for, but currently
- * it is only included in special cases.
- *
- * In Digital UNIX/Tru64 if using the getespw*() (which seems to be
- * be preferred interface, even though also the getprpw*() interface
- * is available) one needs to link with -lsecurity -ldb -laud -lm.
- * One also needs to call set_auth_parameters() in main() before
- * doing anything else, whether one is using getespw*() or getprpw*().
- *
- * Note that accessing the shadow databases can be magnitudes
- * slower than accessing the standard databases.
- *
- * --jhi
- */
-
- switch (which) {
- case OP_GPWNAM:
- pwent = getpwnam(POPpx);
- break;
- case OP_GPWUID:
- pwent = getpwuid((Uid_t)POPi);
- break;
- case OP_GPWENT:
-# ifdef HAS_GETPWENT
- pwent = getpwent();
-# else
- DIE(aTHX_ PL_no_func, "getpwent");
-# endif
- break;
- }
-
- EXTEND(SP, 10);
- if (GIMME != G_ARRAY) {
- PUSHs(sv = sv_newmortal());
- if (pwent) {
- if (which == OP_GPWNAM)
-# if Uid_t_sign <= 0
- sv_setiv(sv, (IV)pwent->pw_uid);
-# else
- sv_setuv(sv, (UV)pwent->pw_uid);
-# endif
- else
- sv_setpv(sv, pwent->pw_name);
- }
- RETURN;
- }
-
- if (pwent) {
- PUSHs(sv = sv_mortalcopy(&PL_sv_no));
- sv_setpv(sv, pwent->pw_name);
-
- PUSHs(sv = sv_mortalcopy(&PL_sv_no));
- SvPOK_off(sv);
- /* If we have getspnam(), we try to dig up the shadow
- * password. If we are underprivileged, the shadow
- * interface will set the errno to EACCES or similar,
- * and return a null pointer. If this happens, we will
- * use the dummy password (usually "*" or "x") from the
- * standard password database.
- *
- * In theory we could skip the shadow call completely
- * if euid != 0 but in practice we cannot know which
- * security measures are guarding the shadow databases
- * on a random platform.
- *
- * Resist the urge to use additional shadow interfaces.
- * Divert the urge to writing an extension instead.
- *
- * --jhi */
-# ifdef HAS_GETSPNAM
- {
- struct spwd *spwent;
- int saverrno; /* Save and restore errno so that
- * underprivileged attempts seem
- * to have never made the unsccessful
- * attempt to retrieve the shadow password. */
-
- saverrno = errno;
- spwent = getspnam(pwent->pw_name);
- errno = saverrno;
- if (spwent && spwent->sp_pwdp)
- sv_setpv(sv, spwent->sp_pwdp);
- }
-# endif
-# ifdef PWPASSWD
- if (!SvPOK(sv)) /* Use the standard password, then. */
- sv_setpv(sv, pwent->pw_passwd);
-# endif
-
-# ifndef INCOMPLETE_TAINTS
- /* passwd is tainted because user himself can diddle with it.
- * admittedly not much and in a very limited way, but nevertheless. */
- SvTAINTED_on(sv);
-# endif
-
- PUSHs(sv = sv_mortalcopy(&PL_sv_no));
-# if Uid_t_sign <= 0
- sv_setiv(sv, (IV)pwent->pw_uid);
-# else
- sv_setuv(sv, (UV)pwent->pw_uid);
-# endif
-
- PUSHs(sv = sv_mortalcopy(&PL_sv_no));
-# if Uid_t_sign <= 0
- sv_setiv(sv, (IV)pwent->pw_gid);
-# else
- sv_setuv(sv, (UV)pwent->pw_gid);
-# endif
- /* pw_change, pw_quota, and pw_age are mutually exclusive--
- * because of the poor interface of the Perl getpw*(),
- * not because there's some standard/convention saying so.
- * A better interface would have been to return a hash,
- * but we are accursed by our history, alas. --jhi. */
- PUSHs(sv = sv_mortalcopy(&PL_sv_no));
-# ifdef PWCHANGE
- sv_setiv(sv, (IV)pwent->pw_change);
-# else
-# ifdef PWQUOTA
- sv_setiv(sv, (IV)pwent->pw_quota);
-# else
-# ifdef PWAGE
- sv_setpv(sv, pwent->pw_age);
-# endif
-# endif
-# endif
-
- /* pw_class and pw_comment are mutually exclusive--.
- * see the above note for pw_change, pw_quota, and pw_age. */
- PUSHs(sv = sv_mortalcopy(&PL_sv_no));
-# ifdef PWCLASS
- sv_setpv(sv, pwent->pw_class);
-# else
-# ifdef PWCOMMENT
- sv_setpv(sv, pwent->pw_comment);
-# endif
-# endif
-
- PUSHs(sv = sv_mortalcopy(&PL_sv_no));
-# ifdef PWGECOS
- sv_setpv(sv, pwent->pw_gecos);
-# endif
-# ifndef INCOMPLETE_TAINTS
- /* pw_gecos is tainted because user himself can diddle with it. */
- SvTAINTED_on(sv);
-# endif
-
- PUSHs(sv = sv_mortalcopy(&PL_sv_no));
- sv_setpv(sv, pwent->pw_dir);
-
- PUSHs(sv = sv_mortalcopy(&PL_sv_no));
- sv_setpv(sv, pwent->pw_shell);
-# ifndef INCOMPLETE_TAINTS
- /* pw_shell is tainted because user himself can diddle with it. */
- SvTAINTED_on(sv);
-# endif
-
-# ifdef PWEXPIRE
- PUSHs(sv = sv_mortalcopy(&PL_sv_no));
- sv_setiv(sv, (IV)pwent->pw_expire);
-# endif
- }
- RETURN;
-#else
- DIE(aTHX_ PL_no_func, "getpwent");
-#endif
-}
-
-PP(pp_spwent)
-{
- dSP;
-#if defined(HAS_PASSWD) && defined(HAS_SETPWENT)
- setpwent();
- RETPUSHYES;
-#else
- DIE(aTHX_ PL_no_func, "setpwent");
-#endif
-}
-
-PP(pp_epwent)
-{
- dSP;
-#if defined(HAS_PASSWD) && defined(HAS_ENDPWENT)
- endpwent();
- RETPUSHYES;
-#else
- DIE(aTHX_ PL_no_func, "endpwent");
-#endif
-}
-
-PP(pp_ggrnam)
-{
-#ifdef HAS_GROUP
- return pp_ggrent();
-#else
- DIE(aTHX_ PL_no_func, "getgrnam");
-#endif
-}
-
-PP(pp_ggrgid)
-{
-#ifdef HAS_GROUP
- return pp_ggrent();
-#else
- DIE(aTHX_ PL_no_func, "getgrgid");
-#endif
-}
-
-PP(pp_ggrent)
-{
- dSP;
-#ifdef HAS_GROUP
- I32 which = PL_op->op_type;
- register char **elem;
- register SV *sv;
- struct group *grent;
- STRLEN n_a;
-
- if (which == OP_GGRNAM)
- grent = (struct group *)getgrnam(POPpx);
- else if (which == OP_GGRGID)
- grent = (struct group *)getgrgid(POPi);
- else
-#ifdef HAS_GETGRENT
- grent = (struct group *)getgrent();
-#else
- DIE(aTHX_ PL_no_func, "getgrent");
-#endif
-
- EXTEND(SP, 4);
- if (GIMME != G_ARRAY) {
- PUSHs(sv = sv_newmortal());
- if (grent) {
- if (which == OP_GGRNAM)
- sv_setiv(sv, (IV)grent->gr_gid);
- else
- sv_setpv(sv, grent->gr_name);
- }
- RETURN;
- }
-
- if (grent) {
- PUSHs(sv = sv_mortalcopy(&PL_sv_no));
- sv_setpv(sv, grent->gr_name);
-
- PUSHs(sv = sv_mortalcopy(&PL_sv_no));
-#ifdef GRPASSWD
- sv_setpv(sv, grent->gr_passwd);
-#endif
-
- PUSHs(sv = sv_mortalcopy(&PL_sv_no));
- sv_setiv(sv, (IV)grent->gr_gid);
-
- PUSHs(sv = sv_mortalcopy(&PL_sv_no));
- for (elem = grent->gr_mem; elem && *elem; elem++) {
- sv_catpv(sv, *elem);
- if (elem[1])
- sv_catpvn(sv, " ", 1);
- }
- }
-
- RETURN;
-#else
- DIE(aTHX_ PL_no_func, "getgrent");
-#endif
-}
-
-PP(pp_sgrent)
-{
- dSP;
-#if defined(HAS_GROUP) && defined(HAS_SETGRENT)
- setgrent();
- RETPUSHYES;
-#else
- DIE(aTHX_ PL_no_func, "setgrent");
-#endif
-}
-
-PP(pp_egrent)
-{
- dSP;
-#if defined(HAS_GROUP) && defined(HAS_ENDGRENT)
- endgrent();
- RETPUSHYES;
-#else
- DIE(aTHX_ PL_no_func, "endgrent");
-#endif
-}
-
-PP(pp_getlogin)
-{
- dSP; dTARGET;
-#ifdef HAS_GETLOGIN
- char *tmps;
- EXTEND(SP, 1);
- if (!(tmps = PerlProc_getlogin()))
- RETPUSHUNDEF;
- PUSHp(tmps, strlen(tmps));
- RETURN;
-#else
- DIE(aTHX_ PL_no_func, "getlogin");
-#endif
-}
-
-/* Miscellaneous. */
-
-PP(pp_syscall)
-{
-#ifdef HAS_SYSCALL
- dSP; dMARK; dORIGMARK; dTARGET;
- register I32 items = SP - MARK;
- unsigned long a[20];
- register I32 i = 0;
- I32 retval = -1;
- STRLEN n_a;
-
- if (PL_tainting) {
- while (++MARK <= SP) {
- if (SvTAINTED(*MARK)) {
- TAINT;
- break;
- }
- }
- MARK = ORIGMARK;
- TAINT_PROPER("syscall");
- }
-
- /* This probably won't work on machines where sizeof(long) != sizeof(int)
- * or where sizeof(long) != sizeof(char*). But such machines will
- * not likely have syscall implemented either, so who cares?
- */
- while (++MARK <= SP) {
- if (SvNIOK(*MARK) || !i)
- a[i++] = SvIV(*MARK);
- else if (*MARK == &PL_sv_undef)
- a[i++] = 0;
- else
- a[i++] = (unsigned long)SvPV_force(*MARK, n_a);
- if (i > 15)
- break;
- }
- switch (items) {
- default:
- DIE(aTHX_ "Too many args to syscall");
- case 0:
- DIE(aTHX_ "Too few args to syscall");
- case 1:
- retval = syscall(a[0]);
- break;
- case 2:
- retval = syscall(a[0],a[1]);
- break;
- case 3:
- retval = syscall(a[0],a[1],a[2]);
- break;
- case 4:
- retval = syscall(a[0],a[1],a[2],a[3]);
- break;
- case 5:
- retval = syscall(a[0],a[1],a[2],a[3],a[4]);
- break;
- case 6:
- retval = syscall(a[0],a[1],a[2],a[3],a[4],a[5]);
- break;
- case 7:
- retval = syscall(a[0],a[1],a[2],a[3],a[4],a[5],a[6]);
- break;
- case 8:
- retval = syscall(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7]);
- break;
-#ifdef atarist
- case 9:
- retval = syscall(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8]);
- break;
- case 10:
- retval = syscall(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9]);
- break;
- case 11:
- retval = syscall(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9],
- a[10]);
- break;
- case 12:
- retval = syscall(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9],
- a[10],a[11]);
- break;
- case 13:
- retval = syscall(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9],
- a[10],a[11],a[12]);
- break;
- case 14:
- retval = syscall(a[0],a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8],a[9],
- a[10],a[11],a[12],a[13]);
- break;
-#endif /* atarist */
- }
- SP = ORIGMARK;
- PUSHi(retval);
- RETURN;
-#else
- DIE(aTHX_ PL_no_func, "syscall");
-#endif
-}
-
-#ifdef FCNTL_EMULATE_FLOCK
-
-/* XXX Emulate flock() with fcntl().
- What's really needed is a good file locking module.
-*/
-
-static int
-fcntl_emulate_flock(int fd, int operation)
-{
- struct flock flock;
-
- switch (operation & ~LOCK_NB) {
- case LOCK_SH:
- flock.l_type = F_RDLCK;
- break;
- case LOCK_EX:
- flock.l_type = F_WRLCK;
- break;
- case LOCK_UN:
- flock.l_type = F_UNLCK;
- break;
- default:
- errno = EINVAL;
- return -1;
- }
- flock.l_whence = SEEK_SET;
- flock.l_start = flock.l_len = (Off_t)0;
-
- return fcntl(fd, (operation & LOCK_NB) ? F_SETLK : F_SETLKW, &flock);
-}
-
-#endif /* FCNTL_EMULATE_FLOCK */
-
-#ifdef LOCKF_EMULATE_FLOCK
-
-/* XXX Emulate flock() with lockf(). This is just to increase
- portability of scripts. The calls are not completely
- interchangeable. What's really needed is a good file
- locking module.
-*/
-
-/* The lockf() constants might have been defined in <unistd.h>.
- Unfortunately, <unistd.h> causes troubles on some mixed
- (BSD/POSIX) systems, such as SunOS 4.1.3.
-
- Further, the lockf() constants aren't POSIX, so they might not be
- visible if we're compiling with _POSIX_SOURCE defined. Thus, we'll
- just stick in the SVID values and be done with it. Sigh.
-*/
-
-# ifndef F_ULOCK
-# define F_ULOCK 0 /* Unlock a previously locked region */
-# endif
-# ifndef F_LOCK
-# define F_LOCK 1 /* Lock a region for exclusive use */
-# endif
-# ifndef F_TLOCK
-# define F_TLOCK 2 /* Test and lock a region for exclusive use */
-# endif
-# ifndef F_TEST
-# define F_TEST 3 /* Test a region for other processes locks */
-# endif
-
-static int
-lockf_emulate_flock(int fd, int operation)
-{
- int i;
- int save_errno;
- Off_t pos;
-
- /* flock locks entire file so for lockf we need to do the same */
- save_errno = errno;
- pos = PerlLIO_lseek(fd, (Off_t)0, SEEK_CUR); /* get pos to restore later */
- if (pos > 0) /* is seekable and needs to be repositioned */
- if (PerlLIO_lseek(fd, (Off_t)0, SEEK_SET) < 0)
- pos = -1; /* seek failed, so don't seek back afterwards */
- errno = save_errno;
-
- switch (operation) {
-
- /* LOCK_SH - get a shared lock */
- case LOCK_SH:
- /* LOCK_EX - get an exclusive lock */
- case LOCK_EX:
- i = lockf (fd, F_LOCK, 0);
- break;
-
- /* LOCK_SH|LOCK_NB - get a non-blocking shared lock */
- case LOCK_SH|LOCK_NB:
- /* LOCK_EX|LOCK_NB - get a non-blocking exclusive lock */
- case LOCK_EX|LOCK_NB:
- i = lockf (fd, F_TLOCK, 0);
- if (i == -1)
- if ((errno == EAGAIN) || (errno == EACCES))
- errno = EWOULDBLOCK;
- break;
-
- /* LOCK_UN - unlock (non-blocking is a no-op) */
- case LOCK_UN:
- case LOCK_UN|LOCK_NB:
- i = lockf (fd, F_ULOCK, 0);
- break;
-
- /* Default - can't decipher operation */
- default:
- i = -1;
- errno = EINVAL;
- break;
- }
-
- if (pos > 0) /* need to restore position of the handle */
- PerlLIO_lseek(fd, pos, SEEK_SET); /* ignore error here */
-
- return (i);
-}
-
-#endif /* LOCKF_EMULATE_FLOCK */
OpenPOWER on IntegriCloud