X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=pp_sys.c;h=d9a80873f7575276812cdac2447548204115fd47;hb=af28e88917ada915d1c6a69f2caccaada3cad842;hp=d1dacdd3c87b39f9647f13aca11d6eb9ebd2e6eb;hpb=93189314521460c01625b05f7cfa81ac855affa9;p=p5sagit%2Fp5-mst-13.2.git diff --git a/pp_sys.c b/pp_sys.c index d1dacdd..d9a8087 100644 --- a/pp_sys.c +++ b/pp_sys.c @@ -1,6 +1,7 @@ /* pp_sys.c * - * Copyright (c) 1991-2002, Larry Wall + * Copyright (C) 1995, 1996, 1997, 1998, 1999, + * 2000, 2001, 2002, 2003, by Larry Wall and others * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. @@ -422,7 +423,7 @@ PP(pp_warn) tmpsv = TOPs; } tmps = SvPV(tmpsv, len); - if (!tmps || !len) { + if ((!tmps || !len) && PL_errgv) { SV *error = ERRSV; (void)SvUPGRADE(error, SVt_PV); if (SvPOK(error) && SvCUR(error)) @@ -457,7 +458,7 @@ PP(pp_die) } else { tmpsv = TOPs; - tmps = (SvROK(tmpsv) && PL_in_eval) ? Nullch : SvPV(tmpsv, len); + tmps = SvROK(tmpsv) ? Nullch : SvPV(tmpsv, len); } if (!tmps || !len) { SV *error = ERRSV; @@ -608,8 +609,8 @@ PP(pp_pipe_op) if (PerlProc_pipe(fd) < 0) goto badexit; - IoIFP(rstio) = PerlIO_fdopen(fd[0], "r"); - IoOFP(wstio) = PerlIO_fdopen(fd[1], "w"); + IoIFP(rstio) = PerlIO_fdopen(fd[0], "r"PIPESOCK_MODE); + IoOFP(wstio) = PerlIO_fdopen(fd[1], "w"PIPESOCK_MODE); IoOFP(rstio) = IoIFP(rstio); IoIFP(wstio) = IoOFP(wstio); IoTYPE(rstio) = IoTYPE_RDONLY; @@ -734,6 +735,7 @@ PP(pp_binmode) if (!(io = GvIO(gv)) || !(fp = IoIFP(io))) { if (ckWARN2(WARN_UNOPENED,WARN_CLOSED)) report_evil_fh(gv, io, PL_op->op_type); + SETERRNO(EBADF,RMS_IFI); RETPUSHUNDEF; } @@ -761,7 +763,6 @@ PP(pp_tie) char *methname; int how = PERL_MAGIC_tied; U32 items; - STRLEN n_a; varsv = *++MARK; switch(SvTYPE(varsv)) { @@ -808,8 +809,8 @@ PP(pp_tie) */ 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)); + DIE(aTHX_ "Can't locate object method \"%s\" via package \"%"SVf"\"", + methname, *MARK); } ENTER; PUSHSTACKi(PERLSI_MAGIC); @@ -1068,12 +1069,23 @@ PP(pp_sselect) #endif } +#ifdef PERL_IRIX5_SELECT_TIMEVAL_VOID_CAST + /* Can't make just the (void*) conditional because that would be + * cpp #if within cpp macro, and not all compilers like that. */ + 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], + (void*) tbuf); /* Workaround for compiler bug. */ +#else 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); +#endif for (i = 1; i <= 3; i++) { if (fd_sets[i]) { sv = SP[i]; @@ -1177,6 +1189,7 @@ PP(pp_getc) if (ckWARN2(WARN_UNOPENED,WARN_CLOSED) && (!io || (!IoIFP(io) && IoTYPE(io) != IoTYPE_WRONLY))) report_evil_fh(gv, io, PL_op->op_type); + SETERRNO(EBADF,RMS_IFI); RETPUSHUNDEF; } TAINT; @@ -1206,8 +1219,6 @@ 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; @@ -1215,8 +1226,7 @@ S_doform(pTHX_ CV *cv, GV *gv, OP *retop) push_return(retop); PUSHBLOCK(cx, CXt_FORMAT, PL_stack_sp); PUSHFORMAT(cx); - SAVEVPTR(PL_curpad); - PL_curpad = AvARRAY((AV*)svp[1]); + PAD_SET_CUR(CvPADLIST(cv), 1); setdefout(gv); /* locally select filehandle so $% et al work */ return CvSTART(cv); @@ -1365,21 +1375,8 @@ PP(pp_leavewrite) 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_ packWARN(WARN_IO), - "Filehandle %s opened only for input", name); - else - Perl_warner(aTHX_ packWARN(WARN_IO), - "Filehandle opened only for input"); - } + if (IoIFP(io)) + report_evil_fh(gv, io, OP_phoney_INPUT_ONLY); else if (ckWARN(WARN_CLOSED)) report_evil_fh(gv, io, PL_op->op_type); } @@ -1452,20 +1449,8 @@ PP(pp_prtf) } 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_ packWARN(WARN_IO), - "Filehandle %s opened only for input", name); - else - Perl_warner(aTHX_ packWARN(WARN_IO), - "Filehandle opened only for input"); - } + if (IoIFP(io)) + report_evil_fh(gv, io, OP_phoney_INPUT_ONLY); else if (ckWARN(WARN_CLOSED)) report_evil_fh(gv, io, PL_op->op_type); } @@ -1574,8 +1559,12 @@ PP(pp_sysread) else offset = 0; io = GvIO(gv); - if (!io || !IoIFP(io)) + if (!io || !IoIFP(io)) { + if (ckWARN2(WARN_UNOPENED,WARN_CLOSED)) + report_evil_fh(gv, io, PL_op->op_type); + SETERRNO(EBADF,RMS_IFI); goto say_undef; + } if ((fp_utf8 = PerlIO_isutf8(IoIFP(io))) && !IN_BYTES) { buffer = SvPVutf8_force(bufsv, blen); /* UTF8 may not have been set if they are all low bytes */ @@ -1688,21 +1677,7 @@ PP(pp_sysread) } if (count < 0) { if ((IoTYPE(io) == IoTYPE_WRONLY) && 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_ packWARN(WARN_IO), - "Filehandle %s opened only for output", name); - else - Perl_warner(aTHX_ packWARN(WARN_IO), - "Filehandle opened only for output"); - } + report_evil_fh(gv, io, OP_phoney_OUTPUT_ONLY); goto say_undef; } SvCUR_set(bufsv, count+(buffer - SvPVX(bufsv))); @@ -1816,6 +1791,7 @@ PP(pp_send) retval = -1; if (ckWARN(WARN_CLOSED)) report_evil_fh(gv, io, PL_op->op_type); + SETERRNO(EBADF,RMS_IFI); goto say_undef; } @@ -2067,22 +2043,31 @@ PP(pp_truncate) STRLEN n_a; int result = 1; GV *tmpgv; - + IO *io; + 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; + do_ftruncate_gv: + if (!GvIO(tmpgv)) + result = 0; else { - PerlIO_flush(IoIFP(GvIOp(tmpgv))); + PerlIO *fp; + io = GvIOp(tmpgv); + do_ftruncate_io: + TAINT_PROPER("truncate"); + if (!(fp = IoIFP(io))) { + result = 0; + } + else { + PerlIO_flush(fp); #ifdef HAS_TRUNCATE - if (ftruncate(PerlIO_fileno(IoIFP(GvIOn(tmpgv))), len) < 0) + if (ftruncate(PerlIO_fileno(fp), len) < 0) #else - if (my_chsize(PerlIO_fileno(IoIFP(GvIOn(tmpgv))), len) < 0) + if (my_chsize(PerlIO_fileno(fp), len) < 0) #endif - result = 0; + result = 0; + } } } else { @@ -2091,11 +2076,15 @@ PP(pp_truncate) if (SvTYPE(sv) == SVt_PVGV) { tmpgv = (GV*)sv; /* *main::FRED for example */ - goto do_ftruncate; + goto do_ftruncate_gv; } else if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVGV) { tmpgv = (GV*) SvRV(sv); /* \*main::FRED for example */ - goto do_ftruncate; + goto do_ftruncate_gv; + } + else if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVIO) { + io = (IO*) SvRV(sv); /* *main::FRED{IO} for example */ + goto do_ftruncate_io; } name = SvPV(sv, n_a); @@ -2186,7 +2175,9 @@ PP(pp_ioctl) #else retval = fcntl(PerlIO_fileno(IoIFP(io)), func, s); #endif +#endif +#if defined(HAS_IOCTL) || defined(HAS_FCNTL) if (SvPOK(argsv)) { if (s[SvCUR(argsv)] != 17) DIE(aTHX_ "Possible memory corruption: %s overflowed 3rd argument", @@ -2277,8 +2268,8 @@ PP(pp_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"); + IoIFP(io) = PerlIO_fdopen(fd, "r"PIPESOCK_MODE); /* stdio gets confused about sockets */ + IoOFP(io) = PerlIO_fdopen(fd, "w"PIPESOCK_MODE); IoTYPE(io) = IoTYPE_SOCKET; if (!IoIFP(io) || !IoOFP(io)) { if (IoIFP(io)) PerlIO_close(IoIFP(io)); @@ -2339,11 +2330,11 @@ PP(pp_sockpair) 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"); + IoIFP(io1) = PerlIO_fdopen(fd[0], "r"PIPESOCK_MODE); + IoOFP(io1) = PerlIO_fdopen(fd[0], "w"PIPESOCK_MODE); IoTYPE(io1) = IoTYPE_SOCKET; - IoIFP(io2) = PerlIO_fdopen(fd[1], "r"); - IoOFP(io2) = PerlIO_fdopen(fd[1], "w"); + IoIFP(io2) = PerlIO_fdopen(fd[1], "r"PIPESOCK_MODE); + IoOFP(io2) = PerlIO_fdopen(fd[1], "w"PIPESOCK_MODE); IoTYPE(io2) = IoTYPE_SOCKET; if (!IoIFP(io1) || !IoOFP(io1) || !IoIFP(io2) || !IoOFP(io2)) { if (IoIFP(io1)) PerlIO_close(IoIFP(io1)); @@ -2491,7 +2482,6 @@ PP(pp_accept) struct sockaddr saddr; /* use a struct to avoid alignment problems */ Sock_size_t len = sizeof saddr; int fd; - int fd2; ggv = (GV*)POPs; ngv = (GV*)POPs; @@ -2511,12 +2501,8 @@ PP(pp_accept) goto badexit; if (IoIFP(nstio)) do_close(ngv, FALSE); - IoIFP(nstio) = PerlIO_fdopen(fd, "r"); - /* FIXME: we dup(fd) here so that refcounting of fd's does not inhibit - fclose of IoOFP's FILE * - and hence leak memory. - Special treatment of _this_ case of IoIFP != IoOFP seems wrong. - */ - IoOFP(nstio) = PerlIO_fdopen(fd2 = PerlLIO_dup(fd), "w"); + IoIFP(nstio) = PerlIO_fdopen(fd, "r"PIPESOCK_MODE); + IoOFP(nstio) = PerlIO_fdopen(fd, "w"PIPESOCK_MODE); IoTYPE(nstio) = IoTYPE_SOCKET; if (!IoIFP(nstio) || !IoOFP(nstio)) { if (IoIFP(nstio)) PerlIO_close(IoIFP(nstio)); @@ -2526,13 +2512,15 @@ PP(pp_accept) } #if defined(HAS_FCNTL) && defined(F_SETFD) fcntl(fd, F_SETFD, fd > PL_maxsysfd); /* ensure close-on-exec */ - fcntl(fd2, F_SETFD, fd2 > 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 +#ifdef __SCO_VERSION__ + len = sizeof saddr; /* OpenUNIX 8 somehow truncates info */ +#endif PUSHp((char *)&saddr, len); RETURN; @@ -2834,7 +2822,7 @@ PP(pp_stat) PUSHs(sv_2mortal(newSVpvn("", 0))); #endif #if Off_t_size > IVSIZE - PUSHs(sv_2mortal(newSVnv(PL_statcache.st_size))); + PUSHs(sv_2mortal(newSVnv((NV)PL_statcache.st_size))); #else PUSHs(sv_2mortal(newSViv(PL_statcache.st_size))); #endif @@ -2864,8 +2852,8 @@ PP(pp_ftrread) 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 ((PL_op->op_private & OPpFT_ACCESS) && SvPOK(TOPs)) { + result = access(POPpx, R_OK); if (result == 0) RETPUSHYES; if (result < 0) @@ -2891,8 +2879,8 @@ PP(pp_ftrwrite) 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 ((PL_op->op_private & OPpFT_ACCESS) && SvPOK(TOPs)) { + result = access(POPpx, W_OK); if (result == 0) RETPUSHYES; if (result < 0) @@ -2918,8 +2906,8 @@ PP(pp_ftrexec) 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 ((PL_op->op_private & OPpFT_ACCESS) && SvPOK(TOPs)) { + result = access(POPpx, X_OK); if (result == 0) RETPUSHYES; if (result < 0) @@ -2945,8 +2933,8 @@ PP(pp_fteread) 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 ((PL_op->op_private & OPpFT_ACCESS) && SvPOK(TOPs)) { + result = PERL_EFF_ACCESS_R_OK(POPpx); if (result == 0) RETPUSHYES; if (result < 0) @@ -2972,8 +2960,8 @@ PP(pp_ftewrite) 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 ((PL_op->op_private & OPpFT_ACCESS) && SvPOK(TOPs)) { + result = PERL_EFF_ACCESS_W_OK(POPpx); if (result == 0) RETPUSHYES; if (result < 0) @@ -2999,8 +2987,8 @@ PP(pp_fteexec) 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 ((PL_op->op_private & OPpFT_ACCESS) && SvPOK(TOPs)) { + result = PERL_EFF_ACCESS_X_OK(POPpx); if (result == 0) RETPUSHYES; if (result < 0) @@ -3337,7 +3325,7 @@ PP(pp_fttext) PL_laststype = OP_STAT; 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')) + if (ckWARN(WARN_NEWLINE) && strchr(SvPV(PL_statname, n_a), '\n')) Perl_warner(aTHX_ packWARN(WARN_NEWLINE), PL_warn_nl, "open"); RETPUSHUNDEF; } @@ -3687,6 +3675,26 @@ S_dooneliner(pTHX_ char *cmd, char *filename) } #endif +/* This macro removes trailing slashes from a directory name. + * Different operating and file systems take differently to + * trailing slashes. According to POSIX 1003.1 1996 Edition + * any number of trailing slashes should be allowed. + * Thusly we snip them away so that even non-conforming + * systems are happy. + * We should probably do this "filtering" for all + * the functions that expect (potentially) directory names: + * -d, chdir(), chmod(), chown(), chroot(), fcntl()?, + * (mkdir()), opendir(), rename(), rmdir(), stat(). --jhi */ + +#define TRIMSLASHES(tmps,len,copy) (tmps) = SvPV(TOPs, (len)); \ + if ((len) > 1 && (tmps)[(len)-1] == '/') { \ + do { \ + (len)--; \ + } while ((len) > 1 && (tmps)[(len)-1] == '/'); \ + (tmps) = savepvn((tmps), (len)); \ + (copy) = TRUE; \ + } + PP(pp_mkdir) { dSP; dTARGET; @@ -3703,22 +3711,7 @@ PP(pp_mkdir) else mode = 0777; - tmps = SvPV(TOPs, len); - /* Different operating and file systems take differently to - * trailing slashes. According to POSIX 1003.1 1996 Edition - * any number of trailing slashes should be allowed. - * Thusly we snip them away so that even non-conforming - * systems are happy. */ - /* We should probably do this "filtering" for all - * the functions that expect (potentially) directory names: - * -d, chdir(), chmod(), chown(), chroot(), fcntl()?, - * (mkdir()), opendir(), rename(), rmdir(), stat(). --jhi */ - if (len > 1 && tmps[len-1] == '/') { - while (tmps[len] == '/' && len > 1) - len--; - tmps = savepvn(tmps, len); - copy = TRUE; - } + TRIMSLASHES(tmps,len,copy); TAINT_PROPER("mkdir"); #ifdef HAS_MKDIR @@ -3737,16 +3730,19 @@ PP(pp_mkdir) PP(pp_rmdir) { dSP; dTARGET; + STRLEN len; char *tmps; - STRLEN n_a; + bool copy = FALSE; - tmps = POPpx; + TRIMSLASHES(tmps,len,copy); TAINT_PROPER("rmdir"); #ifdef HAS_RMDIR - XPUSHi( PerlDir_rmdir(tmps) >= 0 ); + SETi( PerlDir_rmdir(tmps) >= 0 ); #else - XPUSHi( dooneliner("rmdir", tmps) ); + SETi( dooneliner("rmdir", tmps) ); #endif + if (copy) + Safefree(tmps); RETURN; } @@ -3992,13 +3988,14 @@ PP(pp_wait) Pid_t childpid; int argflags; -#ifdef PERL_OLD_SIGNALS - childpid = wait4pid(-1, &argflags, 0); -#else - while ((childpid = wait4pid(-1, &argflags, 0)) == -1 && errno == EINTR) { - PERL_ASYNC_CHECK(); + if (PL_signals & PERL_SIGNALS_UNSAFE_FLAG) + childpid = wait4pid(-1, &argflags, 0); + else { + while ((childpid = wait4pid(-1, &argflags, 0)) == -1 && + errno == EINTR) { + PERL_ASYNC_CHECK(); + } } -#endif # 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); @@ -4022,13 +4019,14 @@ PP(pp_waitpid) optype = POPi; childpid = TOPi; -#ifdef PERL_OLD_SIGNALS - childpid = wait4pid(childpid, &argflags, optype); -#else - while ((childpid = wait4pid(childpid, &argflags, optype)) == -1 && errno == EINTR) { - PERL_ASYNC_CHECK(); + if (PL_signals & PERL_SIGNALS_UNSAFE_FLAG) + childpid = wait4pid(childpid, &argflags, optype); + else { + while ((childpid = wait4pid(childpid, &argflags, optype)) == -1 && + errno == EINTR) { + PERL_ASYNC_CHECK(); + } } -#endif # 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); @@ -4948,6 +4946,9 @@ PP(pp_gservent) char *proto = POPpbytex; unsigned short port = (unsigned short)POPu; + if (proto && !*proto) + proto = Nullch; + #ifdef HAS_HTONS port = PerlSock_htons(port); #endif