[win32] merge change#985 from maintbranch
[p5sagit/p5-mst-13.2.git] / pp_sys.c
index 5cfb74b..d00d162 100644 (file)
--- a/pp_sys.c
+++ b/pp_sys.c
@@ -290,10 +290,11 @@ PP(pp_warn)
        tmps = SvPV(TOPs, na);
     }
     if (!tmps || !*tmps) {
-       (void)SvUPGRADE(ERRSV, SVt_PV);
-       if (SvPOK(ERRSV) && SvCUR(ERRSV))
-           sv_catpv(ERRSV, "\t...caught");
-       tmps = SvPV(ERRSV, na);
+       SV *error = ERRSV;
+       (void)SvUPGRADE(error, SVt_PV);
+       if (SvPOK(error) && SvCUR(error))
+           sv_catpv(error, "\t...caught");
+       tmps = SvPV(error, na);
     }
     if (!tmps || !*tmps)
        tmps = "Warning: something's wrong";
@@ -305,6 +306,8 @@ PP(pp_die)
 {
     djSP; dMARK;
     char *tmps;
+    SV *tmpsv = Nullsv;
+    char *pat = "%s";
     if (SP - MARK != 1) {
        dTARGET;
        do_join(TARG, &sv_no, MARK, SP);
@@ -312,17 +315,26 @@ PP(pp_die)
        SP = MARK + 1;
     }
     else {
-       tmps = SvPV(TOPs, na);
+       tmpsv = TOPs;
+       tmps = SvROK(tmpsv) ? Nullch : SvPV(tmpsv, na);
     }
     if (!tmps || !*tmps) {
-       (void)SvUPGRADE(ERRSV, SVt_PV);
-       if (SvPOK(ERRSV) && SvCUR(ERRSV))
-           sv_catpv(ERRSV, "\t...propagated");
-       tmps = SvPV(ERRSV, na);
+       SV *error = ERRSV;
+       (void)SvUPGRADE(error, SVt_PV);
+       if(tmpsv ? SvROK(tmpsv) : SvROK(error)) {
+           if(tmpsv)
+               SvSetSV(error,tmpsv);
+           pat = Nullch;
+       }
+       else {
+           if (SvPOK(error) && SvCUR(error))
+               sv_catpv(error, "\t...propagated");
+           tmps = SvPV(error, na);
+       }
     }
     if (!tmps || !*tmps)
        tmps = "Died";
-    DIE("%s", tmps);
+    DIE(pat, tmps);
 }
 
 /* I/O. */
@@ -464,7 +476,7 @@ PP(pp_umask)
     TAINT_PROPER("umask");
     XPUSHi(anum);
 #else
-    DIE(no_func, "Unsupported function umask");
+    XPUSHs(&sv_undef)
 #endif
     RETURN;
 }
@@ -485,56 +497,27 @@ PP(pp_binmode)
     if (!(io = GvIO(gv)) || !(fp = IoIFP(io)))
        RETPUSHUNDEF;
 
-#ifdef DOSISH
-#ifdef atarist
-    if (!PerlIO_flush(fp) && (fp->_flag |= _IOBIN))
-       RETPUSHYES;
-    else
-       RETPUSHUNDEF;
-#else
-    if (PerlLIO_setmode(PerlIO_fileno(fp), OP_BINARY) != -1) {
-#if defined(WIN32) && defined(__BORLANDC__)
-       /* The translation mode of the stream is maintained independent
-        * of the translation mode of the fd in the Borland RTL (heavy
-        * digging through their runtime sources reveal).  User has to
-        * set the mode explicitly for the stream (though they don't
-        * document this anywhere). GSAR 97-5-24
-        */
-       PerlIO_seek(fp,0L,0);
-       fp->flags |= _F_BIN;
-#endif
+    if (do_binmode(fp,IoTYPE(io),TRUE)) 
        RETPUSHYES;
-    }
     else
        RETPUSHUNDEF;
-#endif
-#else
-#if defined(USEMYBINMODE)
-    if (my_binmode(fp,IoTYPE(io)) != NULL)
-       RETPUSHYES;
-       else
-       RETPUSHUNDEF;
-#else
-    RETPUSHYES;
-#endif
-#endif
-
 }
 
 
 PP(pp_tie)
 {
     djSP;
+    dMARK;
     SV *varsv;
     HV* stash;
     GV *gv;
     SV *sv;
-    SV **mark = stack_base + ++*markstack_ptr; /* reuse in entersub */
-    I32 markoff = mark - stack_base - 1;
+    I32 markoff = MARK - stack_base;
     char *methname;
     int how = 'P';
+    U32 items;
 
-    varsv = mark[0];  
+    varsv = *++MARK;
     switch(SvTYPE(varsv)) {
        case SVt_PVHV:
            methname = "TIEHASH";
@@ -551,26 +534,39 @@ PP(pp_tie)
            how = 'q';
            break;
     }
-
-    if (sv_isobject(mark[1])) {
+    items = SP - MARK++;
+    if (sv_isobject(*MARK)) {
        ENTER;
+       PUSHSTACK(SI_MAGIC);
+       PUSHMARK(SP);
+       EXTEND(SP,items);
+       while (items--)
+           PUSHs(*MARK++);
+       PUTBACK;
        perl_call_method(methname, G_SCALAR);
     } 
     else {
        /* Not clear why we don't call perl_call_method here too.
         * perhaps to get different error message ?
         */
-       stash = gv_stashsv(mark[1], FALSE);
+       stash = gv_stashsv(*MARK, FALSE);
        if (!stash || !(gv = gv_fetchmethod(stash, methname))) {
            DIE("Can't locate object method \"%s\" via package \"%s\"",
-                methname, SvPV(mark[1],na));                   
+                methname, SvPV(*MARK,na));                   
        }
        ENTER;
+       PUSHSTACK(SI_MAGIC);
+       PUSHMARK(SP);
+       EXTEND(SP,items);
+       while (items--)
+           PUSHs(*MARK++);
+       PUTBACK;
        perl_call_sv((SV*)GvCV(gv), G_SCALAR);
     }
     SPAGAIN;
 
     sv = TOPs;
+    POPSTACK();
     if (sv_isobject(sv)) {
        sv_unmagic(varsv, how);            
        sv_magic(varsv, sv, how, Nullch, 0);
@@ -2589,6 +2585,13 @@ PP(pp_chdir)
        if (svp)
            tmps = SvPV(*svp, na);
     }
+#ifdef VMS
+    if (!tmps || !*tmps) {
+       svp = hv_fetch(GvHVn(envgv), "SYS$LOGIN", 9, FALSE);
+       if (svp)
+           tmps = SvPV(*svp, na);
+    }
+#endif
     TAINT_PROPER("chdir");
     PUSHi( PerlDir_chdir(tmps) >= 0 );
 #ifdef VMS
@@ -4110,41 +4113,55 @@ PP(pp_gpwent)
     if (pwent) {
        PUSHs(sv = sv_mortalcopy(&sv_no));
        sv_setpv(sv, pwent->pw_name);
+
        PUSHs(sv = sv_mortalcopy(&sv_no));
        sv_setpv(sv, pwent->pw_passwd);
+
        PUSHs(sv = sv_mortalcopy(&sv_no));
        sv_setiv(sv, (IV)pwent->pw_uid);
+
        PUSHs(sv = sv_mortalcopy(&sv_no));
        sv_setiv(sv, (IV)pwent->pw_gid);
+
+       /* pw_change, pw_quota, and pw_age are mutually exclusive. */
        PUSHs(sv = sv_mortalcopy(&sv_no));
 #ifdef PWCHANGE
        sv_setiv(sv, (IV)pwent->pw_change);
 #else
-#ifdef PWQUOTA
+#   ifdef PWQUOTA
        sv_setiv(sv, (IV)pwent->pw_quota);
-#else
-#ifdef PWAGE
+#   else
+#       ifdef PWAGE
        sv_setpv(sv, pwent->pw_age);
+#       endif
+#   endif
 #endif
-#endif
-#endif
+
+       /* pw_class and pw_comment are mutually exclusive. */
        PUSHs(sv = sv_mortalcopy(&sv_no));
 #ifdef PWCLASS
        sv_setpv(sv, pwent->pw_class);
 #else
-#ifdef PWCOMMENT
+#   ifdef PWCOMMENT
        sv_setpv(sv, pwent->pw_comment);
+#   endif
 #endif
-#endif
+
        PUSHs(sv = sv_mortalcopy(&sv_no));
+#ifdef PWGECOS
        sv_setpv(sv, pwent->pw_gecos);
+#endif
 #ifndef INCOMPLETE_TAINTS
+       /* pw_gecos is tainted. */
        SvTAINTED_on(sv);
 #endif
+
        PUSHs(sv = sv_mortalcopy(&sv_no));
        sv_setpv(sv, pwent->pw_dir);
+
        PUSHs(sv = sv_mortalcopy(&sv_no));
        sv_setpv(sv, pwent->pw_shell);
+
 #ifdef PWEXPIRE
        PUSHs(sv = sv_mortalcopy(&sv_no));
        sv_setiv(sv, (IV)pwent->pw_expire);