X-Git-Url: https://perl5.git.perl.org/perl5.git/blobdiff_plain/e8432c63fd530dd325a1bd86b17c892b4cfb754a..8657e86b4fb3c8cf23a0c23b7093dda2e79b462b:/pp_sys.c diff --git a/pp_sys.c b/pp_sys.c index 194d2eb..3bf2673 100644 --- a/pp_sys.c +++ b/pp_sys.c @@ -192,6 +192,10 @@ void setservent(int); void endservent(void); #endif +#ifdef __amigaos4__ +# include "amigaos4/amigaio.h" +#endif + #undef PERL_EFF_ACCESS /* EFFective uid/gid ACCESS */ /* F_OK unused: if stat() cannot find it... */ @@ -293,7 +297,7 @@ PP(pp_backtick) dSP; dTARGET; PerlIO *fp; const char * const tmps = POPpconstx; - const I32 gimme = GIMME_V; + const U8 gimme = GIMME_V; const char *mode = "r"; TAINT_PROPER("``"); @@ -529,6 +533,7 @@ Perl_tied_method(pTHX_ SV *methname, SV **sp, SV *const sv, { SV **orig_sp = sp; I32 ret_args; + SSize_t extend_size; PERL_ARGS_ASSERT_TIED_METHOD; @@ -539,7 +544,20 @@ Perl_tied_method(pTHX_ SV *methname, SV **sp, SV *const sv, PUTBACK; /* sp is at *foot* of args, so this pops args from old stack */ PUSHSTACKi(PERLSI_MAGIC); - EXTEND(SP, argc+1); /* object + args */ + /* extend for object + args. If argc might wrap/truncate when cast + * to SSize_t and incremented, set to -1, which will trigger a panic in + * EXTEND(). + * The weird way this is written is because g++ is dumb enough to + * warn "comparison is always false" on something like: + * + * sizeof(a) >= sizeof(b) && a >= B_t_MAX -1 + * + * (where the LH condition is false) + */ + extend_size = + (argc > (sizeof(argc) >= sizeof(SSize_t) ? SSize_t_MAX - 1 : argc)) + ? -1 : (SSize_t)argc + 1; + EXTEND(SP, extend_size); PUSHMARK(sp); PUSHs(SvTIED_obj(sv, mg)); if (flags & TIED_METHOD_ARGUMENTS_ON_STACK) { @@ -677,8 +695,6 @@ PP(pp_pipe_op) GV * const wgv = MUTABLE_GV(POPs); GV * const rgv = MUTABLE_GV(POPs); - assert (isGV_with_GP(rgv)); - assert (isGV_with_GP(wgv)); rstio = GvIOn(rgv); if (IoIFP(rstio)) do_close(rgv, FALSE); @@ -1276,10 +1292,13 @@ of the typeglob that C points to is decreased by one. void Perl_setdefout(pTHX_ GV *gv) { + GV *oldgv = PL_defoutgv; + PERL_ARGS_ASSERT_SETDEFOUT; + SvREFCNT_inc_simple_void_NN(gv); - SvREFCNT_dec(PL_defoutgv); PL_defoutgv = gv; + SvREFCNT_dec(oldgv); } PP(pp_select) @@ -1326,7 +1345,7 @@ PP(pp_getc) if (io) { const MAGIC * const mg = SvTIED_mg((const SV *)io, PERL_MAGIC_tiedscalar); if (mg) { - const U32 gimme = GIMME_V; + const U8 gimme = GIMME_V; Perl_tied_method(aTHX_ SV_CONST(GETC), SP, MUTABLE_SV(io), mg, gimme, 0); if (gimme == G_SCALAR) { SPAGAIN; @@ -1363,23 +1382,17 @@ STATIC OP * S_doform(pTHX_ CV *cv, GV *gv, OP *retop) { PERL_CONTEXT *cx; - const I32 gimme = GIMME_V; + const U8 gimme = GIMME_V; PERL_ARGS_ASSERT_DOFORM; if (CvCLONE(cv)) cv = MUTABLE_CV(sv_2mortal(MUTABLE_SV(cv_clone(cv)))); - ENTER; - SAVETMPS; - - PUSHBLOCK(cx, CXt_FORMAT, PL_stack_sp); - PUSHFORMAT(cx, retop); - if (CvDEPTH(cv) >= 2) { - PERL_STACK_OVERFLOW_CHECK(); + cx = cx_pushblock(CXt_FORMAT, gimme, PL_stack_sp, PL_savestack_ix); + cx_pushformat(cx, cv, retop, gv); + if (CvDEPTH(cv) >= 2) pad_push(CvPADLIST(cv), CvDEPTH(cv)); - } - SAVECOMPPAD(); PAD_SET_CUR_NOSAVE(CvPADLIST(cv), CvDEPTH(cv)); setdefout(gv); /* locally select filehandle so $% et al work */ @@ -1428,12 +1441,10 @@ PP(pp_enterwrite) PP(pp_leavewrite) { dSP; - GV * const gv = cxstack[cxstack_ix].blk_format.gv; + GV * const gv = CX_CUR()->blk_format.gv; IO * const io = GvIOp(gv); PerlIO *ofp; PerlIO *fp; - SV **newsp; - I32 gimme; PERL_CONTEXT *cx; OP *retop; bool is_return = cBOOL(PL_op->op_type == OP_RETURN); @@ -1510,11 +1521,14 @@ PP(pp_leavewrite) } forget_top: - POPBLOCK(cx,PL_curpm); + cx = CX_CUR(); + assert(CxTYPE(cx) == CXt_FORMAT); + SP = PL_stack_base + cx->blk_oldsp; /* ignore retval of formline */ + CX_LEAVE_SCOPE(cx); + cx_popformat(cx); + cx_popblock(cx); retop = cx->blk_sub.retop; - POPFORMAT(cx); - SP = newsp; /* ignore retval of formline */ - LEAVE; + CX_POP(cx); if (is_return) /* XXX the semantics of doing 'return' in a format aren't documented. @@ -1545,7 +1559,6 @@ PP(pp_leavewrite) } } PL_formtarget = PL_bodytarget; - PERL_UNUSED_VAR(gimme); RETURNOP(retop); } @@ -2484,7 +2497,6 @@ PP(pp_socket) TAINT_PROPER("socket"); fd = PerlSock_socket(domain, type, protocol); if (fd < 0) { - SETERRNO(EBADF,RMS_IFI); RETPUSHUNDEF; } IoIFP(io) = PerlIO_fdopen(fd, "r"SOCKET_OPEN_MODE); /* stdio gets confused about sockets */ @@ -2857,7 +2869,7 @@ PP(pp_stat) dSP; GV *gv = NULL; IO *io = NULL; - I32 gimme; + U8 gimme; I32 max = 13; SV* sv; @@ -3518,8 +3530,9 @@ PP(pp_fttext) } PL_laststatval = PerlLIO_fstat(fd, &PL_statcache); if (PL_laststatval < 0) { + dSAVE_ERRNO; (void)PerlIO_close(fp); - SETERRNO(EBADF,RMS_IFI); + RESTORE_ERRNO; FT_RETURNUNDEF; } PerlIO_binmode(aTHX_ fp, '<', O_BINARY, NULL); @@ -3716,17 +3729,20 @@ PP(pp_rename) { dSP; dTARGET; int anum; +#ifndef HAS_RENAME + Stat_t statbuf; +#endif const char * const tmps2 = POPpconstx; const char * const tmps = SvPV_nolen_const(TOPs); TAINT_PROPER("rename"); #ifdef HAS_RENAME anum = PerlLIO_rename(tmps, tmps2); #else - if (!(anum = PerlLIO_stat(tmps, &PL_statbuf))) { + if (!(anum = PerlLIO_stat(tmps, &statbuf))) { if (same_dirent(tmps2, tmps)) /* can always rename to same name */ anum = 1; else { - if (PerlProc_geteuid() || PerlLIO_stat(tmps2, &PL_statbuf) < 0 || !S_ISDIR(PL_statbuf.st_mode)) + if (PerlProc_geteuid() || PerlLIO_stat(tmps2, &statbuf) < 0 || !S_ISDIR(statbuf.st_mode)) (void)UNLINK(tmps2); if (!(anum = link(tmps, tmps2))) anum = UNLINK(tmps); @@ -3888,7 +3904,8 @@ S_dooneliner(pTHX_ const char *cmd, const char *filename) return 0; } else { /* some mkdirs return no failure indication */ - anum = (PerlLIO_stat(save_filename, &PL_statbuf) >= 0); + Stat_t statbuf; + anum = (PerlLIO_stat(save_filename, &statbuf) >= 0); if (PL_op->op_type == OP_RMDIR) anum = !anum; if (anum) @@ -4009,7 +4026,7 @@ PP(pp_readdir) dSP; SV *sv; - const I32 gimme = GIMME_V; + const U8 gimme = GIMME_V; GV * const gv = MUTABLE_GV(POPs); const Direntry_t *dp; IO * const io = GvIOn(gv); @@ -4207,7 +4224,7 @@ PP(pp_fork) PUSHi(childpid); RETURN; #else -# if defined(USE_ITHREADS) && defined(PERL_IMPLICIT_SYS) +# if (defined(USE_ITHREADS) && defined(PERL_IMPLICIT_SYS)) || defined(__amigaos4__) dSP; dTARGET; Pid_t childpid; @@ -4259,6 +4276,12 @@ PP(pp_waitpid) const int optype = POPi; const Pid_t pid = TOPi; Pid_t result; +#ifdef __amigaos4__ + int argflags = 0; + result = amigaos_waitpid(aTHX_ optype, pid, &argflags); + STATUS_NATIVE_CHILD_SET((result >= 0) ? argflags : -1); + result = result == 0 ? pid : -1; +#else int argflags; if (PL_signals & PERL_SIGNALS_UNSAFE_FLAG) @@ -4275,6 +4298,7 @@ PP(pp_waitpid) # else STATUS_NATIVE_CHILD_SET((result > 0) ? argflags : -1); # endif +# endif /* __amigaos4__ */ SETi(result); RETURN; #else @@ -4291,7 +4315,11 @@ PP(pp_system) XPUSHi(-1); #else I32 value; +# ifdef __amigaos4__ + void * result; +# else int result; +# endif if (TAINTING_get) { TAINT_ENV(); @@ -4304,17 +4332,33 @@ PP(pp_system) TAINT_PROPER("system"); } PERL_FLUSHALL_FOR_CHILD; -#if (defined(HAS_FORK) || defined(AMIGAOS)) && !defined(VMS) && !defined(OS2) || defined(PERL_MICRO) +#if (defined(HAS_FORK) || defined(__amigaos4__)) && !defined(VMS) && !defined(OS2) || defined(PERL_MICRO) { +#ifdef __amigaos4__ + struct UserData userdata; + pthread_t proc; +#else Pid_t childpid; +#endif int pp[2]; I32 did_pipes = 0; + bool child_success = FALSE; #ifdef HAS_SIGPROCMASK sigset_t newset, oldset; #endif if (PerlProc_pipe(pp) >= 0) did_pipes = 1; +#ifdef __amigaos4__ + amigaos_fork_set_userdata(aTHX_ + &userdata, + did_pipes, + pp[1], + SP, + mark); + pthread_create(&proc,NULL,amigaos_system_child,(void *)&userdata); + child_success = proc > 0; +#else #ifdef HAS_SIGPROCMASK sigemptyset(&newset); sigaddset(&newset, SIGCHLD); @@ -4336,19 +4380,27 @@ PP(pp_system) } sleep(5); } - if (childpid > 0) { + child_success = childpid > 0; +#endif + if (child_success) { Sigsave_t ihand,qhand; /* place to save signals during system() */ int status; +#ifndef __amigaos4__ if (did_pipes) PerlLIO_close(pp[1]); +#endif #ifndef PERL_MICRO rsignal_save(SIGINT, (Sighandler_t) SIG_IGN, &ihand); rsignal_save(SIGQUIT, (Sighandler_t) SIG_IGN, &qhand); #endif +#ifdef __amigaos4__ + result = pthread_join(proc, (void **)&status); +#else do { result = wait4pid(childpid, &status, 0); } while (result == -1 && errno == EINTR); +#endif #ifndef PERL_MICRO #ifdef HAS_SIGPROCMASK sigprocmask(SIG_SETMASK, &oldset, NULL); @@ -4377,12 +4429,20 @@ PP(pp_system) if (n != sizeof(int)) DIE(aTHX_ "panic: kid popen errno read, n=%u", n); errno = errkid; /* Propagate errno from kid */ - STATUS_NATIVE_CHILD_SET(-1); +#ifdef __amigaos4__ + /* The pipe always has something in it + * so n alone is not enough. */ + if (errno > 0) +#endif + { + STATUS_NATIVE_CHILD_SET(-1); + } } } XPUSHi(STATUS_CURRENT); RETURN; } +#ifndef __amigaos4__ #ifdef HAS_SIGPROCMASK sigprocmask(SIG_SETMASK, &oldset, NULL); #endif @@ -4402,6 +4462,7 @@ PP(pp_system) else { value = (I32)do_exec3(SvPVx_nolen(sv_mortalcopy(*SP)), pp[1], did_pipes); } +#endif /* __amigaos4__ */ PerlProc__exit(-1); } #else /* ! FORK or VMS or OS/2 */ @@ -4440,9 +4501,6 @@ PP(pp_exec) { dSP; dMARK; dORIGMARK; dTARGET; I32 value; -#if defined(__amigaos4__) - amigaos_stdio_store store; -#endif if (TAINTING_get) { TAINT_ENV(); @@ -4454,12 +4512,7 @@ PP(pp_exec) MARK = ORIGMARK; TAINT_PROPER("exec"); } -#if defined(__amigaos4__) - /* Make sure redirection behaves after exec. Yes, in AmigaOS the - * original process continues after exec, since processes are more - * like threads. */ - amigaos_stdio_save(aTHX_ &store); -#endif + PERL_FLUSHALL_FOR_CHILD; if (PL_op->op_flags & OPf_STACKED) { SV * const really = *++MARK; @@ -4478,13 +4531,6 @@ PP(pp_exec) value = (I32)do_exec(SvPVx_nolen(sv_mortalcopy(*SP))); #endif } - -#if defined(__amigaos4__) - amigaos_stdio_restore(aTHX_ &store); - STATUS_NATIVE_CHILD_SET(value); - PL_exit_flags |= PERL_EXIT_EXPECTED; - if (value != -1) my_exit(value); -#endif SP = ORIGMARK; XPUSHi(value); RETURN;