This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
More explicit Solaris instructions
[perl5.git] / pp_sys.c
index 75fdc40..ef769a5 100644 (file)
--- a/pp_sys.c
+++ b/pp_sys.c
@@ -1,6 +1,6 @@
 /*    pp_sys.c
  *
- *    Copyright (c) 1991-1994, Larry Wall
+ *    Copyright (c) 1991-1997, 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.
 # include <sys/resource.h>
 #endif
 
-/* Put this after #includes because fork and vfork prototypes may
-   conflict.
-*/
-#ifndef HAS_VFORK
-#   define vfork fork
-#endif
-
 #if defined(HAS_SOCKET) && !defined(VMS) /* VMS handles sockets via vmsish.h */
 # include <sys/socket.h>
 # include <netdb.h>
@@ -78,7 +71,11 @@ extern int h_errno;
 #endif
 
 #ifdef I_UTIME
-#include <utime.h>
+#  ifdef WIN32
+#    include <sys/utime.h>
+#  else
+#    include <utime.h>
+#  endif
 #endif
 #ifdef I_FCNTL
 #include <fcntl.h>
@@ -87,6 +84,20 @@ extern int h_errno;
 #include <sys/file.h>
 #endif
 
+/* Put this after #includes because fork and vfork prototypes may conflict. */
+#ifndef HAS_VFORK
+#   define vfork fork
+#endif
+
+/* Put this after #includes because <unistd.h> defines _XOPEN_*. */
+#ifndef Sock_size_t
+#  if _XOPEN_VERSION >= 5 || defined(_XOPEN_SOURCE_EXTENDED) || defined(__GLIBC__)
+#    define Sock_size_t Size_t
+#  else
+#    define Sock_size_t int
+#  endif
+#endif
+
 #if !defined(HAS_MKDIR) || !defined(HAS_RMDIR)
 static int dooneliner _((char *cmd, char *filename));
 #endif
@@ -143,6 +154,16 @@ static int dooneliner _((char *cmd, char *filename));
 
 #endif /* no flock() */
 
+#ifndef MAXPATHLEN
+#  ifdef PATH_MAX
+#    define MAXPATHLEN PATH_MAX
+#  else
+#    define MAXPATHLEN 1024
+#  endif
+#endif
+
+#define ZBTLEN 10
+static char zero_but_true[ZBTLEN + 1] = "0 but true";
 
 /* Pushy I/O. */
 
@@ -151,10 +172,17 @@ PP(pp_backtick)
     dSP; dTARGET;
     PerlIO *fp;
     char *tmps = POPp;
+    I32 gimme = GIMME_V;
+
     TAINT_PROPER("``");
     fp = my_popen(tmps, "r");
     if (fp) {
-       if (GIMME == G_SCALAR) {
+       if (gimme == G_VOID) {
+           while (PerlIO_read(fp, tokenbuf, sizeof tokenbuf) > 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*/
@@ -184,7 +212,7 @@ PP(pp_backtick)
     }
     else {
        STATUS_NATIVE_SET(-1);
-       if (GIMME == G_SCALAR)
+       if (gimme == G_SCALAR)
            RETPUSHUNDEF;
     }
 
@@ -316,7 +344,7 @@ PP(pp_close)
     else
        gv = (GV*)POPs;
     EXTEND(SP, 1);
-    PUSHs( do_close(gv, TRUE) ? &sv_yes : &sv_no );
+    PUSHs(boolSV(do_close(gv, TRUE)));
     RETURN;
 }
 
@@ -459,6 +487,7 @@ PP(pp_tie)
     SV **mark = stack_base + ++*markstack_ptr; /* reuse in entersub */
     I32 markoff = mark - stack_base - 1;
     char *methname;
+    bool oldcatch = CATCH_GET;
 
     varsv = mark[0];
     if (SvTYPE(varsv) == SVt_PVHV)
@@ -478,7 +507,8 @@ PP(pp_tie)
     Zero(&myop, 1, BINOP);
     myop.op_last = (OP *) &myop;
     myop.op_next = Nullop;
-    myop.op_flags = OPf_KNOW|OPf_STACKED;
+    myop.op_flags = OPf_WANT_SCALAR | OPf_STACKED;
+    CATCH_SET(TRUE);
 
     ENTER;
     SAVESPTR(op);
@@ -493,6 +523,7 @@ PP(pp_tie)
         runops();
     SPAGAIN;
 
+    CATCH_SET(oldcatch);
     sv = TOPs;
     if (sv_isobject(sv)) {
        if (SvTYPE(varsv) == SVt_PVHV || SvTYPE(varsv) == SVt_PVAV) {
@@ -569,6 +600,7 @@ PP(pp_dbmopen)
     GV *gv;
     BINOP myop;
     SV *sv;
+    bool oldcatch = CATCH_GET;
 
     hv = (HV*)POPs;
 
@@ -586,7 +618,8 @@ PP(pp_dbmopen)
     Zero(&myop, 1, BINOP);
     myop.op_last = (OP *) &myop;
     myop.op_next = Nullop;
-    myop.op_flags = OPf_KNOW|OPf_STACKED;
+    myop.op_flags = OPf_WANT_SCALAR | OPf_STACKED;
+    CATCH_SET(TRUE);
 
     ENTER;
     SAVESPTR(op);
@@ -629,6 +662,7 @@ PP(pp_dbmopen)
        SPAGAIN;
     }
 
+    CATCH_SET(oldcatch);
     if (sv_isobject(TOPs))
        sv_magic((SV*)hv, TOPs, 'P', Nullch, 0);
     LEAVE;
@@ -823,6 +857,7 @@ PP(pp_getc)
 {
     dSP; dTARGET;
     GV *gv;
+    MAGIC *mg;
 
     if (MAXARG <= 0)
        gv = stdingv;
@@ -830,6 +865,20 @@ PP(pp_getc)
        gv = (GV*)POPs;
     if (!gv)
        gv = argvgv;
+
+    if (SvMAGICAL(gv) && (mg = mg_find((SV*)gv, 'q'))) {
+       I32 gimme = GIMME_V;
+       PUSHMARK(SP);
+       XPUSHs(mg->mg_obj);
+       PUTBACK;
+       ENTER;
+       perl_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;
@@ -851,7 +900,7 @@ GV *gv;
 OP *retop;
 {
     register CONTEXT *cx;
-    I32 gimme = GIMME;
+    I32 gimme = GIMME_V;
     AV* padlist = CvPADLIST(cv);
     SV** svp = AvARRAY(padlist);
 
@@ -929,16 +978,16 @@ PP(pp_leavewrite)
        CV *cv;
        if (!IoTOP_GV(io)) {
            GV *topgv;
-           char tmpbuf[256];
+           SV *topname;
 
            if (!IoTOP_NAME(io)) {
                if (!IoFMT_NAME(io))
                    IoFMT_NAME(io) = savepv(GvNAME(gv));
-               sprintf(tmpbuf, "%s_TOP", IoFMT_NAME(io));
-               topgv = gv_fetchpv(tmpbuf,FALSE, SVt_PVFM);
+               topname = sv_2mortal(newSVpvf("%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(tmpbuf);
+                   IoTOP_NAME(io) = savepv(SvPVX(topname));
                else
                    IoTOP_NAME(io) = savepv("top");
            }
@@ -1029,12 +1078,35 @@ PP(pp_prtf)
     GV *gv;
     IO *io;
     PerlIO *fp;
-    SV *sv = NEWSV(0,0);
+    SV *sv;
+    MAGIC *mg;
 
     if (op->op_flags & OPf_STACKED)
        gv = (GV*)*++MARK;
     else
        gv = defoutgv;
+
+    if (SvMAGICAL(gv) && (mg = mg_find((SV*)gv, 'q'))) {
+       if (MARK == ORIGMARK) {
+           EXTEND(SP, 1);
+           ++MARK;
+           Move(MARK, MARK + 1, (SP - MARK) + 1, SV*);
+           ++SP;
+       }
+       PUSHMARK(MARK - 1);
+       *MARK = mg->mg_obj;
+       PUTBACK;
+       ENTER;
+       perl_call_method("PRINTF", G_SCALAR);
+       LEAVE;
+       SPAGAIN;
+       MARK = ORIGMARK + 1;
+       *MARK = *SP;
+       SP = MARK;
+       RETURN;
+    }
+
+    sv = NEWSV(0,0);
     if (!(io = GvIO(gv))) {
        if (dowarn) {
            gv_fullname3(sv, gv, Nullch);
@@ -1116,12 +1188,30 @@ PP(pp_sysread)
     GV *gv;
     IO *io;
     char *buffer;
-    int length;
-    int bufsize;
+    SSize_t length;
+    Sock_size_t bufsize;
     SV *bufsv;
     STRLEN blen;
+    MAGIC *mg;
 
     gv = (GV*)*++MARK;
+    if ((op->op_type == OP_READ || op->op_type == OP_SYSREAD) &&
+       SvMAGICAL(gv) && (mg = mg_find((SV*)gv, 'q')))
+    {
+       SV *sv;
+       
+       PUSHMARK(MARK-1);
+       *MARK = mg->mg_obj;
+       ENTER;
+       perl_call_method("READ", G_SCALAR);
+       LEAVE;
+       SPAGAIN;
+       sv = POPs;
+       SP = ORIGMARK;
+       PUSHs(sv);
+       RETURN;
+    }
+
     if (!gv)
        goto say_undef;
     bufsv = *++MARK;
@@ -1141,11 +1231,12 @@ PP(pp_sysread)
        goto say_undef;
 #ifdef HAS_SOCKET
     if (op->op_type == OP_RECV) {
-       bufsize = sizeof buf;
+       char namebuf[MAXPATHLEN];
+       bufsize = sizeof namebuf;
        buffer = SvGROW(bufsv, length+1);
        /* 'offset' means 'flags' here */
        length = recvfrom(PerlIO_fileno(IoIFP(io)), buffer, length, offset,
-           (struct sockaddr *)buf, &bufsize);
+                         (struct sockaddr *)namebuf, &bufsize);
        if (length < 0)
            RETPUSHUNDEF;
        SvCUR_set(bufsv, length);
@@ -1156,7 +1247,7 @@ PP(pp_sysread)
        if (!(IoFLAGS(io) & IOf_UNTAINT))
            SvTAINTED_on(bufsv);
        SP = ORIGMARK;
-       sv_setpvn(TARG, buf, bufsize);
+       sv_setpvn(TARG, namebuf, bufsize);
        PUSHs(TARG);
        RETURN;
     }
@@ -1180,9 +1271,10 @@ PP(pp_sysread)
     else
 #ifdef HAS_SOCKET__bad_code_maybe
     if (IoTYPE(io) == 's') {
-       bufsize = sizeof buf;
+       char namebuf[MAXPATHLEN];
+       bufsize = sizeof namebuf;
        length = recvfrom(PerlIO_fileno(IoIFP(io)), buffer+offset, length, 0,
-           (struct sockaddr *)buf, &bufsize);
+                         (struct sockaddr *)namebuf, &bufsize);
     }
     else
 #endif
@@ -1294,7 +1386,7 @@ PP(pp_eof)
        gv = last_in_gv;
     else
        gv = last_in_gv = (GV*)POPs;
-    PUSHs(!gv || do_eof(gv) ? &sv_yes : &sv_no);
+    PUSHs(boolSV(!gv || do_eof(gv)));
     RETURN;
 }
 
@@ -1313,13 +1405,25 @@ PP(pp_tell)
 
 PP(pp_seek)
 {
+    return pp_sysseek(ARGS);
+}
+
+PP(pp_sysseek)
+{
     dSP;
     GV *gv;
     int whence = POPi;
     long offset = POPl;
 
     gv = last_in_gv = (GV*)POPs;
-    PUSHs( do_seek(gv, offset, whence) ? &sv_yes : &sv_no );
+    if (op->op_type == OP_SEEK)
+       PUSHs(boolSV(do_seek(gv, offset, whence)));
+    else {
+       long n = do_sysseek(gv, offset, whence);
+       PUSHs((n < 0) ? &sv_undef
+             : sv_2mortal(n ? newSViv((IV)n)
+                          : newSVpv(zero_but_true, ZBTLEN)));
+    }
     RETURN;
 }
 
@@ -1333,8 +1437,9 @@ PP(pp_truncate)
     SETERRNO(0,0);
 #if defined(HAS_TRUNCATE) || defined(HAS_CHSIZE) || defined(F_FREESP)
     if (op->op_flags & OPf_SPECIAL) {
-       tmpgv = gv_fetchpv(POPp,FALSE, SVt_PVIO);
+       tmpgv = gv_fetchpv(POPp, FALSE, SVt_PVIO);
     do_ftruncate:
+       TAINT_PROPER("truncate");
        if (!GvIO(tmpgv) || !IoIFP(GvIOp(tmpgv)) ||
 #ifdef HAS_TRUNCATE
          ftruncate(PerlIO_fileno(IoIFP(GvIOn(tmpgv))), len) < 0)
@@ -1345,6 +1450,8 @@ PP(pp_truncate)
     }
     else {
        SV *sv = POPs;
+       char *name;
+
        if (SvTYPE(sv) == SVt_PVGV) {
            tmpgv = (GV*)sv;            /* *main::FRED for example */
            goto do_ftruncate;
@@ -1353,14 +1460,16 @@ PP(pp_truncate)
            tmpgv = (GV*) SvRV(sv);     /* \*main::FRED for example */
            goto do_ftruncate;
        }
+
+       name = SvPV(sv, na);
+       TAINT_PROPER("truncate");
 #ifdef HAS_TRUNCATE
-       if (truncate (SvPV (sv, na), len) < 0)
+       if (truncate(name, len) < 0)
            result = 0;
 #else
        {
            int tmpfd;
-
-           if ((tmpfd = open(SvPV (sv, na), O_RDWR)) < 0)
+           if ((tmpfd = open(name, O_RDWR)) < 0)
                result = 0;
            else {
                if (my_chsize(tmpfd, len) < 0)
@@ -1393,7 +1502,7 @@ PP(pp_ioctl)
     unsigned int func = U_I(POPn);
     int optype = op->op_type;
     char *s;
-    int retval;
+    IV retval;
     GV *gv = (GV*)POPs;
     IO *io = GvIOn(gv);
 
@@ -1404,22 +1513,19 @@ PP(pp_ioctl)
 
     if (SvPOK(argsv) || !SvNIOK(argsv)) {
        STRLEN len;
+       STRLEN need;
        s = SvPV_force(argsv, len);
-       retval = IOCPARM_LEN(func);
-       if (len < retval) {
-           s = Sv_Grow(argsv, retval+1);
-           SvCUR_set(argsv, retval);
+       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);
-#ifdef DOSISH
-       s = (char*)(long)retval;        /* ouch */
-#else
        s = (char*)retval;              /* ouch */
-#endif
     }
 
     TAINT_PROPER(optype == OP_IOCTL ? "ioctl" : "fcntl");
@@ -1455,7 +1561,7 @@ PP(pp_ioctl)
        PUSHi(retval);
     }
     else {
-       PUSHp("0 but true", 10);
+       PUSHp(zero_but_true, ZBTLEN);
     }
     RETURN;
 }
@@ -1479,6 +1585,7 @@ PP(pp_flock)
     else
        fp = Nullfp;
     if (fp) {
+       (void)PerlIO_flush(fp);
        value = (I32)(FLOCK(PerlIO_fileno(fp), argtype) >= 0);
     }
     else
@@ -1679,7 +1786,7 @@ PP(pp_accept)
     register IO *nstio;
     register IO *gstio;
     struct sockaddr saddr;     /* use a struct to avoid alignment problems */
-    int len = sizeof saddr;
+    Sock_size_t len = sizeof saddr;
     int fd;
 
     ggv = (GV*)POPs;
@@ -1771,7 +1878,7 @@ PP(pp_ssockopt)
     unsigned int lvl;
     GV *gv;
     register IO *io;
-    int aint;
+    Sock_size_t len;
 
     if (optype == OP_GSOCKOPT)
        sv = sv_2mortal(NEWSV(22, 257));
@@ -1792,24 +1899,26 @@ PP(pp_ssockopt)
        (void)SvPOK_only(sv);
        SvCUR_set(sv,256);
        *SvEND(sv) ='\0';
-       aint = SvCUR(sv);
-       if (getsockopt(fd, lvl, optname, SvPVX(sv), &aint) < 0)
+       len = SvCUR(sv);
+       if (getsockopt(fd, lvl, optname, SvPVX(sv), &len) < 0)
            goto nuts2;
-       SvCUR_set(sv,aint);
+       SvCUR_set(sv, len);
        *SvEND(sv) ='\0';
        PUSHs(sv);
        break;
     case OP_SSOCKOPT: {
-           STRLEN len = 0;
-           char *buf = 0;
-           if (SvPOKp(sv))
-               buf = SvPV(sv, len);
+           char *buf;
+           int aint;
+           if (SvPOKp(sv)) {
+               buf = SvPV(sv, na);
+               len = na;
+           }
            else if (SvOK(sv)) {
                aint = (int)SvIV(sv);
                buf = (char*)&aint;
                len = sizeof(int);
            }
-           if (setsockopt(fd, lvl, optname, buf, (int)len) < 0)
+           if (setsockopt(fd, lvl, optname, buf, len) < 0)
                goto nuts2;
            PUSHs(&sv_yes);
        }
@@ -1847,34 +1956,34 @@ PP(pp_getpeername)
     int fd;
     GV *gv = (GV*)POPs;
     register IO *io = GvIOn(gv);
-    int aint;
+    Sock_size_t len;
 
     if (!io || !IoIFP(io))
        goto nuts;
 
     sv = sv_2mortal(NEWSV(22, 257));
     (void)SvPOK_only(sv);
-    SvCUR_set(sv,256);
+    len = 256;
+    SvCUR_set(sv, len);
     *SvEND(sv) ='\0';
-    aint = SvCUR(sv);
     fd = PerlIO_fileno(IoIFP(io));
     switch (optype) {
     case OP_GETSOCKNAME:
-       if (getsockname(fd, (struct sockaddr *)SvPVX(sv), &aint) < 0)
+       if (getsockname(fd, (struct sockaddr *)SvPVX(sv), &len) < 0)
            goto nuts2;
        break;
     case OP_GETPEERNAME:
-       if (getpeername(fd, (struct sockaddr *)SvPVX(sv), &aint) < 0)
+       if (getpeername(fd, (struct sockaddr *)SvPVX(sv), &len) < 0)
            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);
+    if (len == BOGUS_GETNAME_RETURN)
+       len = sizeof(struct sockaddr);
 #endif
-    SvCUR_set(sv,aint);
+    SvCUR_set(sv, len);
     *SvEND(sv) ='\0';
     PUSHs(sv);
     RETURN;
@@ -1902,6 +2011,7 @@ PP(pp_stat)
 {
     dSP;
     GV *tmpgv;
+    I32 gimme;
     I32 max = 13;
 
     if (op->op_flags & OPf_REF) {
@@ -1943,17 +2053,15 @@ PP(pp_stat)
        }
     }
 
-    if (GIMME != G_ARRAY) {
-       EXTEND(SP, 1);
-       if (max)
-           RETPUSHYES;
-       else
-           RETPUSHUNDEF;
+    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((I32)statcache.st_dev)));
        PUSHs(sv_2mortal(newSViv((I32)statcache.st_ino)));
        PUSHs(sv_2mortal(newSViv((I32)statcache.st_mode)));
@@ -2552,7 +2660,9 @@ PP(pp_readlink)
     dSP; dTARGET;
 #ifdef HAS_SYMLINK
     char *tmps;
+    char buf[MAXPATHLEN];
     int len;
+
     tmps = POPp;
     len = readlink(tmps, buf, sizeof buf);
     EXTEND(SP, 1);
@@ -2572,55 +2682,68 @@ dooneliner(cmd, filename)
 char *cmd;
 char *filename;
 {
-    char mybuf[8192];
-    char *s,
-        *save_filename = filename;
-    int anum = 1;
+    char *save_filename = filename;
+    char *cmdline;
+    char *s;
     PerlIO *myfp;
+    int anum = 1;
 
-    strcpy(mybuf, cmd);
-    strcat(mybuf, " ");
-    for (s = mybuf+strlen(mybuf); *filename; ) {
+    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 = my_popen(mybuf, "r");
+    myfp = my_popen(cmdline, "r");
+    Safefree(cmdline);
+
     if (myfp) {
-       *mybuf = '\0';
+       SV *tmpsv = sv_newmortal();
        /* 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++) {
+           int e;
+           for (e = 1;
 #ifdef HAS_SYS_ERRLIST
-               if (instr(mybuf, sys_errlist[errno]))   /* you don't see this */
-                   return 0;
+                e <= sys_nerr
+#endif
+                ; e++)
+           {
+               /* you don't see this */
+               char *errmsg =
+#ifdef HAS_SYS_ERRLIST
+                   sys_errlist[e]
 #else
-               char *errmsg;                           /* especially if it isn't there */
-
-               if (instr(mybuf,
-                         (errmsg = strerror(errno)) ? errmsg : "NoErRoR"))
-                   return 0;
+                   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(mybuf, "cannot make"))
+           if (instr(s, "cannot make"))
                SETERRNO(EEXIST,RMS$_FEX);
-           else if (instr(mybuf, "existing file"))
+           else if (instr(s, "existing file"))
                SETERRNO(EEXIST,RMS$_FEX);
-           else if (instr(mybuf, "ile exists"))
+           else if (instr(s, "ile exists"))
                SETERRNO(EEXIST,RMS$_FEX);
-           else if (instr(mybuf, "non-exist"))
+           else if (instr(s, "non-exist"))
                SETERRNO(ENOENT,RMS$_FNF);
-           else if (instr(mybuf, "does not exist"))
+           else if (instr(s, "does not exist"))
                SETERRNO(ENOENT,RMS$_FNF);
-           else if (instr(mybuf, "not empty"))
+           else if (instr(s, "not empty"))
                SETERRNO(EBUSY,SS$_DEVOFFLINE);
-           else if (instr(mybuf, "cannot access"))
+           else if (instr(s, "cannot access"))
                SETERRNO(EACCES,RMS$_PRV);
            else
                SETERRNO(EPERM,RMS$_PRV);
@@ -2653,7 +2776,7 @@ PP(pp_mkdir)
 
     TAINT_PROPER("mkdir");
 #ifdef HAS_MKDIR
-    SETi( mkdir(tmps, mode) >= 0 );
+    SETi( Mkdir(tmps, mode) >= 0 );
 #else
     SETi( dooneliner("mkdir", tmps) );
     oldumask = umask(0);
@@ -2867,7 +2990,7 @@ PP(pp_fork)
     if (!childpid) {
        /*SUPPRESS 560*/
        if (tmpgv = gv_fetchpv("$", TRUE, SVt_PV))
-           sv_setiv(GvSV(tmpgv), (I32)getpid());
+           sv_setiv(GvSV(tmpgv), (IV)getpid());
        hv_clear(pidstatus);    /* no kids, so don't wait for 'em */
     }
     PUSHi(childpid);
@@ -2921,7 +3044,6 @@ PP(pp_system)
     int status;
     Sigsave_t ihand,qhand;     /* place to save signals during system() */
 
-#if (defined(HAS_FORK) || defined(AMIGAOS)) && !defined(VMS) && !defined(OS2)
     if (SP - MARK == 1) {
        if (tainting) {
            char *junk = SvPV(TOPs, na);
@@ -2929,6 +3051,7 @@ PP(pp_system)
            TAINT_PROPER("system");
        }
     }
+#if (defined(HAS_FORK) || defined(AMIGAOS)) && !defined(VMS) && !defined(OS2)
     while ((childpid = vfork()) == -1) {
        if (errno != EAGAIN) {
            value = -1;
@@ -3212,18 +3335,18 @@ PP(pp_gmtime)
     EXTEND_MORTAL(9);
     if (GIMME != G_ARRAY) {
        dTARGET;
-       char mybuf[30];
+       SV *tsv;
        if (!tmbuf)
            RETPUSHUNDEF;
-       sprintf(mybuf, "%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);
-       PUSHp(mybuf, strlen(mybuf));
+       tsv = newSVpvf("%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((I32)tmbuf->tm_sec)));
@@ -3372,7 +3495,7 @@ PP(pp_semctl)
        PUSHi(anum);
     }
     else {
-       PUSHp("0 but true",10);
+       PUSHp(zero_but_true, ZBTLEN);
     }
     RETURN;
 #else
@@ -3475,10 +3598,10 @@ PP(pp_ghostent)
                sv_catpvn(sv, " ", 1);
        }
        PUSHs(sv = sv_mortalcopy(&sv_no));
-       sv_setiv(sv, (I32)hent->h_addrtype);
+       sv_setiv(sv, (IV)hent->h_addrtype);
        PUSHs(sv = sv_mortalcopy(&sv_no));
        len = hent->h_length;
-       sv_setiv(sv, (I32)len);
+       sv_setiv(sv, (IV)len);
 #ifdef h_addr
        for (elem = hent->h_addr_list; elem && *elem; elem++) {
            XPUSHs(sv = sv_mortalcopy(&sv_no));
@@ -3541,7 +3664,7 @@ PP(pp_gnetent)
        PUSHs(sv = sv_newmortal());
        if (nent) {
            if (which == OP_GNBYNAME)
-               sv_setiv(sv, (I32)nent->n_net);
+               sv_setiv(sv, (IV)nent->n_net);
            else
                sv_setpv(sv, nent->n_name);
        }
@@ -3558,9 +3681,9 @@ PP(pp_gnetent)
                sv_catpvn(sv, " ", 1);
        }
        PUSHs(sv = sv_mortalcopy(&sv_no));
-       sv_setiv(sv, (I32)nent->n_addrtype);
+       sv_setiv(sv, (IV)nent->n_addrtype);
        PUSHs(sv = sv_mortalcopy(&sv_no));
-       sv_setiv(sv, (I32)nent->n_net);
+       sv_setiv(sv, (IV)nent->n_net);
     }
 
     RETURN;
@@ -3611,7 +3734,7 @@ PP(pp_gprotoent)
        PUSHs(sv = sv_newmortal());
        if (pent) {
            if (which == OP_GPBYNAME)
-               sv_setiv(sv, (I32)pent->p_proto);
+               sv_setiv(sv, (IV)pent->p_proto);
            else
                sv_setpv(sv, pent->p_name);
        }
@@ -3628,7 +3751,7 @@ PP(pp_gprotoent)
                sv_catpvn(sv, " ", 1);
        }
        PUSHs(sv = sv_mortalcopy(&sv_no));
-       sv_setiv(sv, (I32)pent->p_proto);
+       sv_setiv(sv, (IV)pent->p_proto);
     }
 
     RETURN;
@@ -3694,9 +3817,9 @@ PP(pp_gservent)
        if (sent) {
            if (which == OP_GSBYNAME) {
 #ifdef HAS_NTOHS
-               sv_setiv(sv, (I32)ntohs(sent->s_port));
+               sv_setiv(sv, (IV)ntohs(sent->s_port));
 #else
-               sv_setiv(sv, (I32)(sent->s_port));
+               sv_setiv(sv, (IV)(sent->s_port));
 #endif
            }
            else
@@ -3716,9 +3839,9 @@ PP(pp_gservent)
        }
        PUSHs(sv = sv_mortalcopy(&sv_no));
 #ifdef HAS_NTOHS
-       sv_setiv(sv, (I32)ntohs(sent->s_port));
+       sv_setiv(sv, (IV)ntohs(sent->s_port));
 #else
-       sv_setiv(sv, (I32)(sent->s_port));
+       sv_setiv(sv, (IV)(sent->s_port));
 #endif
        PUSHs(sv = sv_mortalcopy(&sv_no));
        sv_setpv(sv, sent->s_proto);
@@ -3860,7 +3983,7 @@ PP(pp_gpwent)
        PUSHs(sv = sv_newmortal());
        if (pwent) {
            if (which == OP_GPWNAM)
-               sv_setiv(sv, (I32)pwent->pw_uid);
+               sv_setiv(sv, (IV)pwent->pw_uid);
            else
                sv_setpv(sv, pwent->pw_name);
        }
@@ -3873,15 +3996,15 @@ PP(pp_gpwent)
        PUSHs(sv = sv_mortalcopy(&sv_no));
        sv_setpv(sv, pwent->pw_passwd);
        PUSHs(sv = sv_mortalcopy(&sv_no));
-       sv_setiv(sv, (I32)pwent->pw_uid);
+       sv_setiv(sv, (IV)pwent->pw_uid);
        PUSHs(sv = sv_mortalcopy(&sv_no));
-       sv_setiv(sv, (I32)pwent->pw_gid);
+       sv_setiv(sv, (IV)pwent->pw_gid);
        PUSHs(sv = sv_mortalcopy(&sv_no));
 #ifdef PWCHANGE
-       sv_setiv(sv, (I32)pwent->pw_change);
+       sv_setiv(sv, (IV)pwent->pw_change);
 #else
 #ifdef PWQUOTA
-       sv_setiv(sv, (I32)pwent->pw_quota);
+       sv_setiv(sv, (IV)pwent->pw_quota);
 #else
 #ifdef PWAGE
        sv_setpv(sv, pwent->pw_age);
@@ -3904,7 +4027,7 @@ PP(pp_gpwent)
        sv_setpv(sv, pwent->pw_shell);
 #ifdef PWEXPIRE
        PUSHs(sv = sv_mortalcopy(&sv_no));
-       sv_setiv(sv, (I32)pwent->pw_expire);
+       sv_setiv(sv, (IV)pwent->pw_expire);
 #endif
     }
     RETURN;
@@ -3916,7 +4039,7 @@ PP(pp_gpwent)
 PP(pp_spwent)
 {
     dSP;
-#ifdef HAS_PASSWD
+#if defined(HAS_PASSWD) && !defined(CYGWIN32)
     setpwent();
     RETPUSHYES;
 #else
@@ -3974,7 +4097,7 @@ PP(pp_ggrent)
        PUSHs(sv = sv_newmortal());
        if (grent) {
            if (which == OP_GGRNAM)
-               sv_setiv(sv, (I32)grent->gr_gid);
+               sv_setiv(sv, (IV)grent->gr_gid);
            else
                sv_setpv(sv, grent->gr_name);
        }
@@ -3987,7 +4110,7 @@ PP(pp_ggrent)
        PUSHs(sv = sv_mortalcopy(&sv_no));
        sv_setpv(sv, grent->gr_passwd);
        PUSHs(sv = sv_mortalcopy(&sv_no));
-       sv_setiv(sv, (I32)grent->gr_gid);
+       sv_setiv(sv, (IV)grent->gr_gid);
        PUSHs(sv = sv_mortalcopy(&sv_no));
        for (elem = grent->gr_mem; *elem; elem++) {
            sv_catpv(sv, *elem);