X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=pp_sys.c;h=13e11b5adba6756c3f1638a3fbf399d98f5143de;hb=9a3e71f668bd84b1cf53dd3ea10f588d59ecfebb;hp=ee51347cdc72ebddae5ca8cb48e7c641fadb97df;hpb=cbdc8872ffece705964522f9a9d92e9a36b58bfc;p=p5sagit%2Fp5-mst-13.2.git diff --git a/pp_sys.c b/pp_sys.c index ee51347..13e11b5 100644 --- a/pp_sys.c +++ b/pp_sys.c @@ -17,14 +17,17 @@ #include "EXTERN.h" #include "perl.h" -/* XXX Omit this -- it causes too much grief on mixed systems. - Next time, I should force broken systems to unset i_unistd in - hint files. -*/ -#if 0 -# ifdef I_UNISTD -# include -# endif +/* XXX If this causes problems, set i_unistd=undef in the hint file. */ +#ifdef I_UNISTD +# include +#endif + +#ifdef I_SYS_WAIT +# include +#endif + +#ifdef I_SYS_RESOURCE +# include #endif /* Put this after #includes because fork and vfork prototypes may @@ -46,11 +49,9 @@ #ifdef HAS_SELECT #ifdef I_SYS_SELECT -#ifndef I_SYS_TIME #include #endif #endif -#endif #ifdef HOST_NOT_FOUND extern int h_errno; @@ -91,15 +92,64 @@ static int dooneliner _((char *cmd, char *filename)); #endif #ifdef HAS_CHSIZE +# ifdef my_chsize /* Probably #defined to Perl_my_chsize in embed.h */ +# undef my_chsize +# endif # define my_chsize 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 +# endif + +# if defined(HAS_FCNTL) && defined(F_SETLK) && defined (F_SETLKW) +# 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() */ + + /* Pushy I/O. */ PP(pp_backtick) { dSP; dTARGET; - FILE *fp; + PerlIO *fp; char *tmps = POPp; TAINT_PROPER("``"); fp = my_popen(tmps, "r"); @@ -152,7 +202,7 @@ PP(pp_glob) #ifndef CSH *SvPVX(rs) = '\n'; #endif /* !CSH */ -#endif /* !MSDOS */ +#endif /* !DOSISH */ result = do_readline(); LEAVE; @@ -234,16 +284,18 @@ PP(pp_open) if (MAXARG > 1) sv = POPs; - else if (SvTYPE(TOPs) == SVt_PVGV) - sv = GvSV(TOPs); - else + if (!isGV(TOPs)) DIE(no_usym, "filehandle"); + if (MAXARG <= 1) + sv = GvSV(TOPs); gv = (GV*)POPs; + if (!isGV(gv)) + DIE(no_usym, "filehandle"); + if (GvIOp(gv)) + IoFLAGS(GvIOp(gv)) &= ~IOf_UNTAINT; tmps = SvPV(sv, len); - if (do_open(gv, tmps, len, FALSE, 0, 0, Nullfp)) { - IoLINES(GvIOp(gv)) = 0; + if (do_open(gv, tmps, len, FALSE, 0, 0, Nullfp)) PUSHi( (I32)forkprocess ); - } else if (forkprocess == 0) /* we are a new child */ PUSHi(0); else @@ -294,16 +346,16 @@ PP(pp_pipe_op) if (pipe(fd) < 0) goto badexit; - IoIFP(rstio) = fdopen(fd[0], "r"); - IoOFP(wstio) = fdopen(fd[1], "w"); + IoIFP(rstio) = PerlIO_fdopen(fd[0], "r"); + IoOFP(wstio) = PerlIO_fdopen(fd[1], "w"); IoIFP(wstio) = IoOFP(wstio); IoTYPE(rstio) = '<'; IoTYPE(wstio) = '>'; if (!IoIFP(rstio) || !IoOFP(wstio)) { - if (IoIFP(rstio)) fclose(IoIFP(rstio)); + if (IoIFP(rstio)) PerlIO_close(IoIFP(rstio)); else close(fd[0]); - if (IoOFP(wstio)) fclose(IoOFP(wstio)); + if (IoOFP(wstio)) PerlIO_close(IoOFP(wstio)); else close(fd[1]); goto badexit; } @@ -322,13 +374,13 @@ PP(pp_fileno) dSP; dTARGET; GV *gv; IO *io; - FILE *fp; + PerlIO *fp; if (MAXARG < 1) RETPUSHUNDEF; gv = (GV*)POPs; if (!gv || !(io = GvIO(gv)) || !(fp = IoIFP(io))) RETPUSHUNDEF; - PUSHi(fileno(fp)); + PUSHi(PerlIO_fileno(fp)); RETURN; } @@ -357,7 +409,7 @@ PP(pp_binmode) dSP; GV *gv; IO *io; - FILE *fp; + PerlIO *fp; if (MAXARG < 1) RETPUSHUNDEF; @@ -366,16 +418,16 @@ PP(pp_binmode) EXTEND(SP, 1); if (!(io = GvIO(gv)) || !(fp = IoIFP(io))) - RETSETUNDEF; + RETPUSHUNDEF; #ifdef DOSISH #ifdef atarist - if (!Fflush(fp) && (fp->_flag |= _IOBIN)) + if (!PerlIO_flush(fp) && (fp->_flag |= _IOBIN)) RETPUSHYES; else RETPUSHUNDEF; #else - if (setmode(fileno(fp), OP_BINARY) != -1) + if (setmode(PerlIO_fileno(fp), OP_BINARY) != -1) RETPUSHYES; else RETPUSHUNDEF; @@ -416,7 +468,7 @@ PP(pp_tie) methname = "TIESCALAR"; stash = gv_stashsv(mark[1], FALSE); - if (!stash || !(gv = gv_fetchmethod(stash, methname)) || !GvCV(gv)) + if (!stash || !(gv = gv_fetchmethod(stash, methname))) DIE("Can't locate object method \"%s\" via package \"%s\"", methname, SvPV(mark[1],na)); @@ -431,7 +483,7 @@ PP(pp_tie) if (perldb && curstash != debstash) op->op_private |= OPpENTERSUB_DB; - XPUSHs((SV*)gv); + XPUSHs((SV*)GvCV(gv)); PUTBACK; if (op = pp_entersub()) @@ -461,8 +513,8 @@ PP(pp_untie) SV * sv ; sv = POPs; - if (hints & HINT_STRICT_UNTIE) - { + + if (dowarn) { MAGIC * mg ; if (SvMAGICAL(sv)) { if (SvTYPE(sv) == SVt_PVHV || SvTYPE(sv) == SVt_PVAV) @@ -471,7 +523,7 @@ PP(pp_untie) mg = mg_find(sv, 'q') ; if (mg && SvREFCNT(SvRV(mg->mg_obj)) > 1) - croak("Can't untie: %d inner references still exist", + warn("untie attempted while %d inner references still exist", SvREFCNT(SvRV(mg->mg_obj)) - 1 ) ; } } @@ -480,7 +532,7 @@ PP(pp_untie) sv_unmagic(sv, 'P'); else sv_unmagic(sv, 'q'); - RETSETYES; + RETPUSHYES; } PP(pp_tied) @@ -520,11 +572,11 @@ PP(pp_dbmopen) sv = sv_mortalcopy(&sv_no); sv_setpv(sv, "AnyDBM_File"); stash = gv_stashsv(sv, FALSE); - if (!stash || !(gv = gv_fetchmethod(stash, "TIEHASH")) || !GvCV(gv)) { + if (!stash || !(gv = gv_fetchmethod(stash, "TIEHASH"))) { PUTBACK; perl_require_pv("AnyDBM_File.pm"); SPAGAIN; - if (!(gv = gv_fetchmethod(stash, "TIEHASH")) || !GvCV(gv)) + if (!(gv = gv_fetchmethod(stash, "TIEHASH"))) DIE("No dbm on this machine"); } @@ -549,7 +601,7 @@ PP(pp_dbmopen) else PUSHs(sv_2mortal(newSViv(O_RDWR))); PUSHs(right); - PUSHs((SV*)gv); + PUSHs((SV*)GvCV(gv)); PUTBACK; if (op = pp_entersub()) @@ -566,7 +618,7 @@ PP(pp_dbmopen) PUSHs(left); PUSHs(sv_2mortal(newSViv(O_RDONLY))); PUSHs(right); - PUSHs((SV*)gv); + PUSHs((SV*)GvCV(gv)); PUTBACK; if (op = pp_entersub()) @@ -623,7 +675,7 @@ PP(pp_sselect) } #if BYTEORDER == 0x1234 || BYTEORDER == 0x12345678 -#ifdef __linux__ +#if defined(__linux__) || defined(OS2) growsize = sizeof(fd_set); #else growsize = maxlen; /* little endians can use vecs directly */ @@ -747,7 +799,7 @@ PP(pp_select) else { GV **gvp = (GV**)hv_fetch(hv, GvNAME(egv), GvNAMELEN(egv), FALSE); if (gvp && *gvp == egv) - gv_efullname(TARG, defoutgv); + gv_efullname3(TARG, defoutgv, Nullch); else sv_setsv(TARG, sv_2mortal(newRV((SV*)egv))); XPUSHTARG; @@ -775,9 +827,9 @@ PP(pp_getc) gv = argvgv; if (!gv || do_eof(gv)) /* make sure we have fp with something */ RETPUSHUNDEF; - TAINT_IF(1); + TAINT; sv_setpv(TARG, " "); - *SvPVX(TARG) = getc(IoIFP(GvIOp(gv))); /* should never be EOF */ + *SvPVX(TARG) = PerlIO_getc(IoIFP(GvIOp(gv))); /* should never be EOF */ PUSHTARG; RETURN; } @@ -841,7 +893,7 @@ PP(pp_enterwrite) if (!cv) { if (fgv) { SV *tmpsv = sv_newmortal(); - gv_efullname(tmpsv, gv); + gv_efullname3(tmpsv, fgv, Nullch); DIE("Undefined format \"%s\" called",SvPVX(tmpsv)); } DIE("Not a format reference"); @@ -856,13 +908,13 @@ PP(pp_leavewrite) dSP; GV *gv = cxstack[cxstack_ix].blk_sub.gv; register IO *io = GvIOp(gv); - FILE *ofp = IoOFP(io); - FILE *fp; + PerlIO *ofp = IoOFP(io); + PerlIO *fp; SV **newsp; I32 gimme; register CONTEXT *cx; - DEBUG_f(fprintf(Perl_debug_log,"left=%ld, todo=%ld\n", + DEBUG_f(PerlIO_printf(Perl_debug_log, "left=%ld, todo=%ld\n", (long)IoLINES_LEFT(io), (long)FmLINES(formtarget))); if (IoLINES_LEFT(io) < FmLINES(formtarget) && formtarget != toptarget) @@ -903,13 +955,13 @@ PP(pp_leavewrite) s++; } if (s) { - fwrite1(SvPVX(formtarget), s - SvPVX(formtarget), 1, ofp); + PerlIO_write(ofp, SvPVX(formtarget), s - SvPVX(formtarget)); sv_chop(formtarget, s); FmLINES(formtarget) -= IoLINES_LEFT(io); } } if (IoLINES_LEFT(io) >= 0 && IoPAGE(io) > 0) - fwrite1(SvPVX(formfeed), SvCUR(formfeed), 1, ofp); + PerlIO_write(ofp, SvPVX(formfeed), SvCUR(formfeed)); IoLINES_LEFT(io) = IoPAGE_LEN(io); IoPAGE(io)++; formtarget = toptarget; @@ -920,7 +972,7 @@ PP(pp_leavewrite) cv = GvFORM(fgv); if (!cv) { SV *tmpsv = sv_newmortal(); - gv_efullname(tmpsv, fgv); + gv_efullname3(tmpsv, fgv, Nullch); DIE("Undefined top format \"%s\" called",SvPVX(tmpsv)); } return doform(cv,gv,op); @@ -946,15 +998,15 @@ PP(pp_leavewrite) if (dowarn) warn("page overflow"); } - if (!fwrite1(SvPVX(formtarget), 1, SvCUR(formtarget), ofp) || - ferror(fp)) + if (!PerlIO_write(ofp, SvPVX(formtarget), SvCUR(formtarget)) || + PerlIO_error(fp)) PUSHs(&sv_no); else { FmLINES(formtarget) = 0; SvCUR_set(formtarget, 0); *SvEND(formtarget) = '\0'; if (IoFLAGS(io) & IOf_FLUSH) - (void)Fflush(fp); + (void)PerlIO_flush(fp); PUSHs(&sv_yes); } } @@ -968,7 +1020,7 @@ PP(pp_prtf) dSP; dMARK; dORIGMARK; GV *gv; IO *io; - FILE *fp; + PerlIO *fp; SV *sv = NEWSV(0,0); if (op->op_flags & OPf_STACKED) @@ -977,7 +1029,7 @@ PP(pp_prtf) gv = defoutgv; if (!(io = GvIO(gv))) { if (dowarn) { - gv_fullname(sv,gv); + gv_fullname3(sv, gv, Nullch); warn("Filehandle %s never opened", SvPV(sv,na)); } SETERRNO(EBADF,RMS$_IFI); @@ -985,7 +1037,7 @@ PP(pp_prtf) } else if (!(fp = IoOFP(io))) { if (dowarn) { - gv_fullname(sv,gv); + gv_fullname3(sv, gv, Nullch); if (IoIFP(io)) warn("Filehandle %s opened only for input", SvPV(sv,na)); else @@ -995,12 +1047,18 @@ PP(pp_prtf) goto just_say_no; } else { +#ifdef USE_LOCALE_NUMERIC + if (op->op_private & OPpLOCALE) + SET_NUMERIC_LOCAL(); + else + SET_NUMERIC_STANDARD(); +#endif do_sprintf(sv, SP - MARK, MARK + 1); if (!do_print(sv, fp)) goto just_say_no; if (IoFLAGS(io) & IOf_FLUSH) - if (Fflush(fp) == EOF) + if (PerlIO_flush(fp) == EOF) goto just_say_no; } SvREFCNT_dec(sv); @@ -1059,6 +1117,8 @@ PP(pp_sysread) 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) @@ -1075,7 +1135,8 @@ PP(pp_sysread) if (op->op_type == OP_RECV) { bufsize = sizeof buf; buffer = SvGROW(bufsv, length+1); - length = recvfrom(fileno(IoIFP(io)), buffer, length, offset, + /* 'offset' means 'flags' here */ + length = recvfrom(PerlIO_fileno(IoIFP(io)), buffer, length, offset, (struct sockaddr *)buf, &bufsize); if (length < 0) RETPUSHUNDEF; @@ -1083,8 +1144,9 @@ PP(pp_sysread) *SvEND(bufsv) = '\0'; (void)SvPOK_only(bufsv); SvSETMAGIC(bufsv); - if (tainting) - sv_magic(bufsv, Nullsv, 't', Nullch, 0); + /* 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, buf, bufsize); PUSHs(TARG); @@ -1094,28 +1156,38 @@ PP(pp_sysread) if (op->op_type == OP_RECV) DIE(no_sock_func, "recv"); #endif + if (offset < 0) { + if (-offset > blen) + DIE("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 (op->op_type == OP_SYSREAD) { - length = read(fileno(IoIFP(io)), buffer+offset, length); + length = read(PerlIO_fileno(IoIFP(io)), buffer+offset, length); } else #ifdef HAS_SOCKET__bad_code_maybe if (IoTYPE(io) == 's') { bufsize = sizeof buf; - length = recvfrom(fileno(IoIFP(io)), buffer+offset, length, 0, + length = recvfrom(PerlIO_fileno(IoIFP(io)), buffer+offset, length, 0, (struct sockaddr *)buf, &bufsize); } else #endif - length = fread(buffer+offset, 1, length, IoIFP(io)); + length = PerlIO_read(IoIFP(io), buffer+offset, length); if (length < 0) goto say_undef; SvCUR_set(bufsv, length+offset); *SvEND(bufsv) = '\0'; (void)SvPOK_only(bufsv); SvSETMAGIC(bufsv); - if (tainting) - sv_magic(bufsv, Nullsv, 't', Nullch, 0); + /* 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; @@ -1161,24 +1233,30 @@ PP(pp_send) } } else if (op->op_type == OP_SYSWRITE) { - if (MARK < SP) + if (MARK < SP) { offset = SvIVx(*++MARK); - else + if (offset < 0) { + if (-offset > blen) + DIE("Offset outside string"); + offset += blen; + } else if (offset >= blen) + DIE("Offset outside string"); + } else offset = 0; if (length > blen - offset) length = blen - offset; - length = write(fileno(IoIFP(io)), buffer+offset, length); + length = write(PerlIO_fileno(IoIFP(io)), buffer+offset, length); } #ifdef HAS_SOCKET else if (SP > MARK) { char *sockbuf; STRLEN mlen; sockbuf = SvPVx(*++MARK, mlen); - length = sendto(fileno(IoIFP(io)), buffer, blen, length, + length = sendto(PerlIO_fileno(IoIFP(io)), buffer, blen, length, (struct sockaddr *)sockbuf, mlen); } else - length = send(fileno(IoIFP(io)), buffer, blen, length); + length = send(PerlIO_fileno(IoIFP(io)), buffer, blen, length); #else else DIE(no_sock_func, "send"); @@ -1251,9 +1329,9 @@ PP(pp_truncate) do_ftruncate: if (!GvIO(tmpgv) || !IoIFP(GvIOp(tmpgv)) || #ifdef HAS_TRUNCATE - ftruncate(fileno(IoIFP(GvIOn(tmpgv))), len) < 0) + ftruncate(PerlIO_fileno(IoIFP(GvIOn(tmpgv))), len) < 0) #else - my_chsize(fileno(IoIFP(GvIOn(tmpgv))), len) < 0) + my_chsize(PerlIO_fileno(IoIFP(GvIOn(tmpgv))), len) < 0) #endif result = 0; } @@ -1274,8 +1352,8 @@ PP(pp_truncate) { int tmpfd; - if ((tmpfd = open(SvPV (sv, na), 0)) < 0) - result = 0; + if ((tmpfd = open(SvPV (sv, na), O_RDWR)) < 0) + result = 0; else { if (my_chsize(tmpfd, len) < 0) result = 0; @@ -1340,23 +1418,19 @@ PP(pp_ioctl) if (optype == OP_IOCTL) #ifdef HAS_IOCTL - retval = ioctl(fileno(IoIFP(io)), func, s); + retval = ioctl(PerlIO_fileno(IoIFP(io)), func, s); #else DIE("ioctl is not implemented"); #endif else -#if defined(DOSISH) && !defined(OS2) - DIE("fcntl is not implemented"); +#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 -# ifdef HAS_FCNTL -# if defined(OS2) && defined(__EMX__) - retval = fcntl(fileno(IoIFP(io)), func, (int)s); -# else - retval = fcntl(fileno(IoIFP(io)), func, s); -# endif -# else DIE("fcntl is not implemented"); -# endif #endif if (SvPOK(argsv)) { @@ -1384,13 +1458,9 @@ PP(pp_flock) I32 value; int argtype; GV *gv; - FILE *fp; - -#if !defined(HAS_FLOCK) && defined(HAS_LOCKF) -# define flock lockf_emulate_flock -#endif + PerlIO *fp; -#if defined(HAS_FLOCK) || defined(flock) +#ifdef FLOCK argtype = POPi; if (MAXARG <= 0) gv = last_in_gv; @@ -1401,7 +1471,7 @@ PP(pp_flock) else fp = Nullfp; if (fp) { - value = (I32)(flock(fileno(fp), argtype) >= 0); + value = (I32)(FLOCK(PerlIO_fileno(fp), argtype) >= 0); } else value = 0; @@ -1440,12 +1510,12 @@ PP(pp_socket) fd = socket(domain, type, protocol); if (fd < 0) RETPUSHUNDEF; - IoIFP(io) = fdopen(fd, "r"); /* stdio gets confused about sockets */ - IoOFP(io) = fdopen(fd, "w"); + IoIFP(io) = PerlIO_fdopen(fd, "r"); /* stdio gets confused about sockets */ + IoOFP(io) = PerlIO_fdopen(fd, "w"); IoTYPE(io) = 's'; if (!IoIFP(io) || !IoOFP(io)) { - if (IoIFP(io)) fclose(IoIFP(io)); - if (IoOFP(io)) fclose(IoOFP(io)); + if (IoIFP(io)) PerlIO_close(IoIFP(io)); + if (IoOFP(io)) PerlIO_close(IoOFP(io)); if (!IoIFP(io) && !IoOFP(io)) close(fd); RETPUSHUNDEF; } @@ -1484,18 +1554,18 @@ PP(pp_sockpair) TAINT_PROPER("socketpair"); if (socketpair(domain, type, protocol, fd) < 0) RETPUSHUNDEF; - IoIFP(io1) = fdopen(fd[0], "r"); - IoOFP(io1) = fdopen(fd[0], "w"); + IoIFP(io1) = PerlIO_fdopen(fd[0], "r"); + IoOFP(io1) = PerlIO_fdopen(fd[0], "w"); IoTYPE(io1) = 's'; - IoIFP(io2) = fdopen(fd[1], "r"); - IoOFP(io2) = fdopen(fd[1], "w"); + IoIFP(io2) = PerlIO_fdopen(fd[1], "r"); + IoOFP(io2) = PerlIO_fdopen(fd[1], "w"); IoTYPE(io2) = 's'; if (!IoIFP(io1) || !IoOFP(io1) || !IoIFP(io2) || !IoOFP(io2)) { - if (IoIFP(io1)) fclose(IoIFP(io1)); - if (IoOFP(io1)) fclose(IoOFP(io1)); + if (IoIFP(io1)) PerlIO_close(IoIFP(io1)); + if (IoOFP(io1)) PerlIO_close(IoOFP(io1)); if (!IoIFP(io1) && !IoOFP(io1)) close(fd[0]); - if (IoIFP(io2)) fclose(IoIFP(io2)); - if (IoOFP(io2)) fclose(IoOFP(io2)); + if (IoIFP(io2)) PerlIO_close(IoIFP(io2)); + if (IoOFP(io2)) PerlIO_close(IoOFP(io2)); if (!IoIFP(io2) && !IoOFP(io2)) close(fd[1]); RETPUSHUNDEF; } @@ -1521,7 +1591,7 @@ PP(pp_bind) addr = SvPV(addrsv, len); TAINT_PROPER("bind"); - if (bind(fileno(IoIFP(io)), (struct sockaddr *)addr, len) >= 0) + if (bind(PerlIO_fileno(IoIFP(io)), (struct sockaddr *)addr, len) >= 0) RETPUSHYES; else RETPUSHUNDEF; @@ -1551,7 +1621,7 @@ PP(pp_connect) addr = SvPV(addrsv, len); TAINT_PROPER("connect"); - if (connect(fileno(IoIFP(io)), (struct sockaddr *)addr, len) >= 0) + if (connect(PerlIO_fileno(IoIFP(io)), (struct sockaddr *)addr, len) >= 0) RETPUSHYES; else RETPUSHUNDEF; @@ -1577,7 +1647,7 @@ PP(pp_listen) if (!io || !IoIFP(io)) goto nuts; - if (listen(fileno(IoIFP(io)), backlog) >= 0) + if (listen(PerlIO_fileno(IoIFP(io)), backlog) >= 0) RETPUSHYES; else RETPUSHUNDEF; @@ -1620,15 +1690,15 @@ PP(pp_accept) if (IoIFP(nstio)) do_close(ngv, FALSE); - fd = accept(fileno(IoIFP(gstio)), (struct sockaddr *)&saddr, &len); + fd = accept(PerlIO_fileno(IoIFP(gstio)), (struct sockaddr *)&saddr, &len); if (fd < 0) goto badexit; - IoIFP(nstio) = fdopen(fd, "r"); - IoOFP(nstio) = fdopen(fd, "w"); + IoIFP(nstio) = PerlIO_fdopen(fd, "r"); + IoOFP(nstio) = PerlIO_fdopen(fd, "w"); IoTYPE(nstio) = 's'; if (!IoIFP(nstio) || !IoOFP(nstio)) { - if (IoIFP(nstio)) fclose(IoIFP(nstio)); - if (IoOFP(nstio)) fclose(IoOFP(nstio)); + if (IoIFP(nstio)) PerlIO_close(IoIFP(nstio)); + if (IoOFP(nstio)) PerlIO_close(IoOFP(nstio)); if (!IoIFP(nstio) && !IoOFP(nstio)) close(fd); goto badexit; } @@ -1660,7 +1730,7 @@ PP(pp_shutdown) if (!io || !IoIFP(io)) goto nuts; - PUSHi( shutdown(fileno(IoIFP(io)), how) >= 0 ); + PUSHi( shutdown(PerlIO_fileno(IoIFP(io)), how) >= 0 ); RETURN; nuts: @@ -1707,7 +1777,7 @@ PP(pp_ssockopt) if (!io || !IoIFP(io)) goto nuts; - fd = fileno(IoIFP(io)); + fd = PerlIO_fileno(IoIFP(io)); switch (optype) { case OP_GSOCKOPT: SvGROW(sv, 257); @@ -1779,7 +1849,7 @@ PP(pp_getpeername) SvCUR_set(sv,256); *SvEND(sv) ='\0'; aint = SvCUR(sv); - fd = fileno(IoIFP(io)); + fd = PerlIO_fileno(IoIFP(io)); switch (optype) { case OP_GETSOCKNAME: if (getsockname(fd, (struct sockaddr *)SvPVX(sv), &aint) < 0) @@ -1790,6 +1860,12 @@ PP(pp_getpeername) goto nuts2; break; } +#ifdef BOGUS_GETNAME_RETURN + /* Interactive Unix, getpeername() and getsockname() + does not return valid namelen */ + if (aint == BOGUS_GETNAME_RETURN) + aint = sizeof(struct sockaddr); +#endif SvCUR_set(sv,aint); *SvEND(sv) ='\0'; PUSHs(sv); @@ -1827,13 +1903,10 @@ PP(pp_stat) laststype = OP_STAT; statgv = tmpgv; sv_setpv(statname, ""); - if (!GvIO(tmpgv) || !IoIFP(GvIOp(tmpgv)) || - Fstat(fileno(IoIFP(GvIOn(tmpgv))), &statcache) < 0) { - max = 0; - laststatval = -1; - } + laststatval = (GvIO(tmpgv) && IoIFP(GvIOp(tmpgv)) + ? Fstat(PerlIO_fileno(IoIFP(GvIOn(tmpgv))), &statcache) : -1); } - else if (laststatval < 0) + if (laststatval < 0) max = 0; } else { @@ -1862,14 +1935,17 @@ PP(pp_stat) } } - EXTEND(SP, 13); if (GIMME != G_ARRAY) { + EXTEND(SP, 1); if (max) RETPUSHYES; else RETPUSHUNDEF; } if (max) { + EXTEND(SP, max); + EXTEND_MORTAL(max); + PUSHs(sv_2mortal(newSViv((I32)statcache.st_dev))); PUSHs(sv_2mortal(newSViv((I32)statcache.st_ino))); PUSHs(sv_2mortal(newSViv((I32)statcache.st_mode))); @@ -2176,7 +2252,7 @@ PP(pp_fttty) else gv = gv_fetchpv(tmps = POPp, FALSE, SVt_PVIO); if (GvIO(gv) && IoIFP(GvIOp(gv))) - fd = fileno(IoIFP(GvIOp(gv))); + fd = PerlIO_fileno(IoIFP(GvIOp(gv))); else if (isDIGIT(*tmps)) fd = atoi(tmps); else @@ -2203,11 +2279,21 @@ PP(pp_fttext) STDCHAR tbuf[512]; register STDCHAR *s; register IO *io; - SV *sv; + register SV *sv; + GV *gv; - if (op->op_flags & OPf_REF) { + if (op->op_flags & OPf_REF) + gv = cGVOP->op_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 (cGVOP->op_gv == defgv) { + if (gv == defgv) { if (statgv) io = GvIO(statgv); else { @@ -2216,30 +2302,34 @@ PP(pp_fttext) } } else { - statgv = cGVOP->op_gv; + statgv = gv; + laststatval = -1; sv_setpv(statname, ""); io = GvIO(statgv); } if (io && IoIFP(io)) { -#ifdef FILE_base - Fstat(fileno(IoIFP(io)), &statcache); + if (! PerlIO_has_base(IoIFP(io))) + DIE("-T and -B not implemented on filehandles"); + laststatval = Fstat(PerlIO_fileno(IoIFP(io)), &statcache); + if (laststatval < 0) + RETPUSHUNDEF; if (S_ISDIR(statcache.st_mode)) /* handle NFS glitch */ if (op->op_type == OP_FTTEXT) RETPUSHNO; else RETPUSHYES; - if (FILE_cnt(IoIFP(io)) <= 0) { - i = getc(IoIFP(io)); + if (PerlIO_get_cnt(IoIFP(io)) <= 0) { + i = PerlIO_getc(IoIFP(io)); if (i != EOF) - (void)ungetc(i, IoIFP(io)); + (void)PerlIO_ungetc(IoIFP(io),i); } - if (FILE_cnt(IoIFP(io)) <= 0) /* null file is anything */ + if (PerlIO_get_cnt(IoIFP(io)) <= 0) /* null file is anything */ RETPUSHYES; - len = FILE_bufsiz(IoIFP(io)); - s = FILE_base(IoIFP(io)); -#else - DIE("-T and -B not implemented on filehandles"); -#endif + 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 (dowarn) @@ -2251,9 +2341,10 @@ PP(pp_fttext) } else { sv = POPs; + really_filename: statgv = Nullgv; + laststatval = -1; sv_setpv(statname, SvPV(sv, na)); - really_filename: #ifdef HAS_OPEN3 i = open(SvPV(sv, na), O_RDONLY, 0); #else @@ -2264,7 +2355,9 @@ PP(pp_fttext) warn(warn_nl, "open"); RETPUSHUNDEF; } - Fstat(i, &statcache); + laststatval = Fstat(i, &statcache); + if (laststatval < 0) + RETPUSHUNDEF; len = read(i, tbuf, 512); (void)close(i); if (len <= 0) { @@ -2403,13 +2496,15 @@ PP(pp_rename) #ifdef HAS_RENAME anum = rename(tmps, tmps2); #else - if (same_dirent(tmps2, tmps)) /* can always rename to same name */ - anum = 1; - else { - if (euid || Stat(tmps2, &statbuf) < 0 || !S_ISDIR(statbuf.st_mode)) - (void)UNLINK(tmps2); - if (!(anum = link(tmps, tmps2))) - anum = UNLINK(tmps); + if (!(anum = Stat(tmps, &statbuf))) { + if (same_dirent(tmps2, tmps)) /* can always rename to same name */ + anum = 1; + else { + if (euid || Stat(tmps2, &statbuf) < 0 || !S_ISDIR(statbuf.st_mode)) + (void)UNLINK(tmps2); + if (!(anum = link(tmps, tmps2))) + anum = UNLINK(tmps); + } } #endif SETi( anum >= 0 ); @@ -2473,7 +2568,7 @@ char *filename; char *s, *save_filename = filename; int anum = 1; - FILE *myfp; + PerlIO *myfp; strcpy(mybuf, cmd); strcat(mybuf, " "); @@ -2485,7 +2580,8 @@ char *filename; myfp = my_popen(mybuf, "r"); if (myfp) { *mybuf = '\0'; - s = fgets(mybuf, sizeof mybuf, myfp); + /* Need to save/restore 'rs' ?? */ + s = sv_gets(tmpsv, myfp, 0); (void)my_pclose(myfp); if (s != Nullch) { for (errno = 1; errno < sys_nerr; errno++) { @@ -2822,10 +2918,9 @@ PP(pp_system) int childpid; int result; int status; - Signal_t (*ihand)(); /* place to save signal during system() */ - Signal_t (*qhand)(); /* place to save signal during system() */ + Sigsave_t ihand,qhand; /* place to save signals during system() */ -#if defined(HAS_FORK) && !defined(VMS) && !defined(OS2) +#if (defined(HAS_FORK) || defined(AMIGAOS)) && !defined(VMS) && !defined(OS2) if (SP - MARK == 1) { if (tainting) { char *junk = SvPV(TOPs, na); @@ -2843,13 +2938,13 @@ PP(pp_system) sleep(5); } if (childpid > 0) { - ihand = signal(SIGINT, SIG_IGN); - qhand = signal(SIGQUIT, SIG_IGN); + rsignal_save(SIGINT, SIG_IGN, &ihand); + rsignal_save(SIGQUIT, SIG_IGN, &qhand); do { result = wait4pid(childpid, &status, 0); } while (result == -1 && errno == EINTR); - (void)signal(SIGINT, ihand); - (void)signal(SIGQUIT, qhand); + (void)rsignal_restore(SIGINT, &ihand); + (void)rsignal_restore(SIGQUIT, &qhand); statusvalue = FIXSTATUS(status); if (result < 0) value = -1; @@ -3047,15 +3142,27 @@ PP(pp_time) 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 -#define HZ 60 +# ifdef CLK_TCK +# define HZ CLK_TCK +# else +# define HZ 60 +# endif #endif PP(pp_tms) { dSP; -#if defined(MSDOS) || !defined(HAS_TIMES) +#ifndef HAS_TIMES DIE("times not implemented"); #else EXTEND(SP, 4); @@ -3066,8 +3173,6 @@ PP(pp_tms) (void)times((tbuffer_t *)×buf); /* time.h uses different name for */ /* struct tms, though same data */ /* is returned. */ -#undef HZ -#define HZ CLK_TCK #endif PUSHs(sv_2mortal(newSVnv(((double)timesbuf.tms_utime)/HZ))); @@ -3077,7 +3182,7 @@ PP(pp_tms) PUSHs(sv_2mortal(newSVnv(((double)timesbuf.tms_cstime)/HZ))); } RETURN; -#endif /* MSDOS */ +#endif /* HAS_TIMES */ } PP(pp_localtime) @@ -3109,6 +3214,7 @@ PP(pp_gmtime) tmbuf = gmtime(&when); EXTEND(SP, 9); + EXTEND_MORTAL(9); if (GIMME != G_ARRAY) { dTARGET; char mybuf[30]; @@ -3164,7 +3270,7 @@ PP(pp_sleep) (void)time(&lasttime); if (MAXARG < 1) - pause(); + Pause(); else { duration = POPi; sleep((unsigned int)duration); @@ -3577,8 +3683,11 @@ PP(pp_gservent) } else if (which == OP_GSBYPORT) { char *proto = POPp; - int port = POPi; + unsigned short port = POPu; +#ifdef HAS_HTONS + port = htons(port); +#endif sent = getservbyport(port, proto); } else @@ -3949,9 +4058,10 @@ PP(pp_syscall) if (tainting) { while (++MARK <= SP) { - if (SvGMAGICAL(*MARK) && SvSMAGICAL(*MARK) && - (mg = mg_find(*MARK, 't')) && mg->mg_len & 1) - tainted = TRUE; + if (SvTAINTED(*MARK)) { + TAINT; + break; + } } MARK = ORIGMARK; TAINT_PROPER("syscall"); @@ -4033,7 +4143,42 @@ PP(pp_syscall) #endif } -#if !defined(HAS_FLOCK) && defined(HAS_LOCKF) +#ifdef FCNTL_EMULATE_FLOCK + +/* XXX Emulate flock() with fcntl(). + What's really needed is a good file locking module. +*/ + +static int +fcntl_emulate_flock(fd, operation) +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 = 0L; + + 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 @@ -4041,12 +4186,9 @@ PP(pp_syscall) locking module. */ -/* We might need because it sometimes defines the lockf() - constants. Unfortunately, causes troubles on some mixed - (BSD/POSIX) systems, such as SunOS 4.1.3. We could just try including - here in this part of the file, but that might - conflict with various other #defines and includes above, such as - #define vfork fork above. +/* The lockf() constants might have been defined in . + Unfortunately, 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 @@ -4066,23 +4208,7 @@ PP(pp_syscall) # define F_TEST 3 /* Test a region for other processes locks */ # endif -/* 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 - -int +static int lockf_emulate_flock (fd, operation) int fd; int operation; @@ -4107,8 +4233,9 @@ int operation; errno = EWOULDBLOCK; break; - /* LOCK_UN - unlock */ + /* LOCK_UN - unlock (non-blocking is a no-op) */ case LOCK_UN: + case LOCK_UN|LOCK_NB: i = lockf (fd, F_ULOCK, 0); break; @@ -4120,4 +4247,5 @@ int operation; } return (i); } -#endif + +#endif /* LOCKF_EMULATE_FLOCK */