This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Avoid an error that VC++'s resource compiler seems to have
[perl5.git] / perlio.c
index 47fbd92..30e3e6c 100644 (file)
--- a/perlio.c
+++ b/perlio.c
 #ifdef PERL_MICRO
 #   include "uconfig.h"
 #else
-#   include "config.h"
+#   ifndef USE_CROSS_COMPILE
+#       include "config.h"
+#   else
+#       include "xconfig.h"
+#   endif
 #endif
 
 #define PERLIO_NOT_STDIO 0
@@ -474,9 +478,9 @@ PerlIO_debug(const char *fmt, ...)
        const char * const s = CopFILE(PL_curcop);
        /* Use fixed buffer as sv_catpvf etc. needs SVs */
        char buffer[1024];
-       const STRLEN len = my_sprintf(buffer, "%.40s:%" IVdf " ", s ? s : "(none)", (IV) CopLINE(PL_curcop));
-       const STRLEN len2 = vsprintf(buffer+len, fmt, ap);
-       PerlLIO_write(PL_perlio_debug_fd, buffer, len + len2);
+       const STRLEN len1 = my_snprintf(buffer, sizeof(buffer), "%.40s:%" IVdf " ", s ? s : "(none)", (IV) CopLINE(PL_curcop));
+       const STRLEN len2 = my_vsnprintf(buffer + len1, sizeof(buffer) - len1, fmt, ap);
+       PerlLIO_write(PL_perlio_debug_fd, buffer, len1 + len2);
 #else
        const char *s = CopFILE(PL_curcop);
        STRLEN len;
@@ -645,7 +649,7 @@ PerlIO_clone(pTHX_ PerlInterpreter *proto, CLONE_PARAMS *param)
     PL_known_layers = PerlIO_clone_list(aTHX_ proto->Iknown_layers, param);
     PL_def_layerlist = PerlIO_clone_list(aTHX_ proto->Idef_layerlist, param);
     PerlIO_allocate(aTHX); /* root slot is never used */
-    PerlIO_debug("Clone %p from %p\n",aTHX,proto);
+    PerlIO_debug("Clone %p from %p\n",(void*)aTHX,(void*)proto);
     while ((f = *table)) {
            int i;
            table = (PerlIO **) (f++);
@@ -657,6 +661,7 @@ PerlIO_clone(pTHX_ PerlInterpreter *proto, CLONE_PARAMS *param)
            }
        }
 #else
+    PERL_UNUSED_CONTEXT;
     PERL_UNUSED_ARG(proto);
     PERL_UNUSED_ARG(param);
 #endif
@@ -669,7 +674,7 @@ PerlIO_destruct(pTHX)
     PerlIO **table = &PL_perlio;
     PerlIO *f;
 #ifdef USE_ITHREADS
-    PerlIO_debug("Destruct %p\n",aTHX);
+    PerlIO_debug("Destruct %p\n",(void*)aTHX);
 #endif
     while ((f = *table)) {
        int i;
@@ -1182,19 +1187,26 @@ PerlIO_push(pTHX_ PerlIO *f, PERLIO_FUNCS_DECL(*tab), const char *mode, SV *arg)
            goto mismatch;
        }
        /* Real layer with a data area */
-       Newxc(l,tab->size,char,PerlIOl);
-       if (l && f) {
-           Zero(l, tab->size, char);
-           l->next = *f;
-           l->tab = (PerlIO_funcs*) tab;
-           *f = l;
-           PerlIO_debug("PerlIO_push f=%p %s %s %p\n", (void*)f, tab->name,
-                       (mode) ? mode : "(Null)", (void*)arg);
-           if (*l->tab->Pushed &&
-               (*l->tab->Pushed) (aTHX_ f, mode, arg, (PerlIO_funcs*) tab) != 0) {
-               PerlIO_pop(aTHX_ f);
-               return NULL;
+       if (f) {
+           char *temp;
+           Newxz(temp, tab->size, char);
+           l = (PerlIOl*)temp;
+           if (l) {
+               l->next = *f;
+               l->tab = (PerlIO_funcs*) tab;
+               *f = l;
+               PerlIO_debug("PerlIO_push f=%p %s %s %p\n",
+                            (void*)f, tab->name,
+                            (mode) ? mode : "(Null)", (void*)arg);
+               if (*l->tab->Pushed &&
+                   (*l->tab->Pushed)
+                     (aTHX_ f, mode, arg, (PerlIO_funcs*) tab) != 0) {
+                   PerlIO_pop(aTHX_ f);
+                   return NULL;
+               }
            }
+           else
+               return NULL;
        }
     }
     else if (f) {
@@ -1396,32 +1408,6 @@ Perl_PerlIO_fileno(pTHX_ PerlIO *f)
      Perl_PerlIO_or_Base(f, Fileno, fileno, -1, (aTHX_ f));
 }
 
-static const char *
-PerlIO_context_layers(pTHX_ const char *mode)
-{
-    dVAR;
-    const char *type = NULL;
-    /*
-     * Need to supply default layer info from open.pm
-     */
-    if (PL_curcop) {
-       SV * const layers = PL_curcop->cop_io;
-       if (layers) {
-           STRLEN len;
-           type = SvPV_const(layers, len);
-           if (type && mode[0] != 'r') {
-               /*
-                * Skip to write part
-                */
-               const char * const s = strchr(type, 0);
-               if (s && (STRLEN)(s - type) < len) {
-                   type = s + 1;
-               }
-           }
-       }
-    }
-    return type;
-}
 
 static PerlIO_funcs *
 PerlIO_layer_from_ref(pTHX_ SV *sv)
@@ -1445,8 +1431,9 @@ PerlIO_layer_from_ref(pTHX_ SV *sv)
        return PerlIO_find_layer(aTHX_ STR_WITH_LEN("Code"), 0);
     case SVt_PVGV:
        return PerlIO_find_layer(aTHX_ STR_WITH_LEN("Glob"), 0);
+    default:
+       return NULL;
     }
-    return NULL;
 }
 
 PerlIO_list_t *
@@ -1479,7 +1466,7 @@ PerlIO_resolve_layers(pTHX_ const char *layers,
        }
     }
     if (!layers || !*layers)
-       layers = PerlIO_context_layers(aTHX_ mode);
+       layers = Perl_PerlIO_context_layers(aTHX_ mode);
     if (layers && *layers) {
        PerlIO_list_t *av;
        if (incdef) {
@@ -1516,7 +1503,7 @@ PerlIO_openn(pTHX_ const char *layers, const char *mode, int fd,
     if (!f && narg == 1 && *args == &PL_sv_undef) {
        if ((f = PerlIO_tmpfile())) {
            if (!layers || !*layers)
-               layers = PerlIO_context_layers(aTHX_ mode);
+               layers = Perl_PerlIO_context_layers(aTHX_ mode);
            if (layers && *layers)
                PerlIO_apply_layers(aTHX_ f, mode, layers);
        }
@@ -2097,7 +2084,7 @@ PerlIOBase_read(pTHX_ PerlIO *f, void *vbuf, Size_t count)
            SSize_t avail = PerlIO_get_cnt(f);
            SSize_t take = 0;
            if (avail > 0)
-               take = ((SSize_t)count < avail) ? count : avail;
+               take = ((SSize_t)count < avail) ? (SSize_t)count : avail;
            if (take > 0) {
                STDCHAR *ptr = PerlIO_get_ptr(f);
                Copy(ptr, buf, take, STDCHAR);
@@ -2260,6 +2247,7 @@ perl_mutex PerlIO_mutex;
 /* Must be called with PerlIO_mutex locked.  */
 static void
 S_more_refcounted_fds(pTHX_ const int new_fd) {
+    dVAR;
     const int old_max = PL_perlio_fd_refcnt_size;
     const int new_max = 16 + (new_fd & ~15);
     int *new_array;
@@ -2289,7 +2277,9 @@ S_more_refcounted_fds(pTHX_ const int new_fd) {
     PL_perlio_fd_refcnt_size = new_max;
     PL_perlio_fd_refcnt = new_array;
 
-    PerlIO_debug("Zeroing %p, %d\n", new_array + old_max, new_max - old_max);
+    PerlIO_debug("Zeroing %p, %d\n",
+                (void*)(new_array + old_max),
+                new_max - old_max);
 
     Zero(new_array + old_max, new_max - old_max, int);
 }
@@ -2358,7 +2348,7 @@ PerlIO_cleanup(pTHX)
     dVAR;
     int i;
 #ifdef USE_ITHREADS
-    PerlIO_debug("Cleanup layers for %p\n",aTHX);
+    PerlIO_debug("Cleanup layers for %p\n",(void*)aTHX);
 #else
     PerlIO_debug("Cleanup layers\n");
 #endif
@@ -2559,7 +2549,7 @@ PerlIOUnix_open(pTHX_ PerlIO_funcs *self, PerlIO_list_t *layers,
     }
     else {
        if (f) {
-           /*EMPTY*/;
+           NOOP;
            /*
             * FIXME: pop layers ???
             */
@@ -2864,7 +2854,6 @@ PerlIOStdio_open(pTHX_ PerlIO_funcs *self, PerlIO_list_t *layers,
 #endif
                stdio = PerlSIO_fopen(path, mode);
                if (stdio) {
-                   PerlIOStdio *s;
                    if (!f) {
                        f = PerlIO_allocate(aTHX);
                    }
@@ -2872,9 +2861,10 @@ PerlIOStdio_open(pTHX_ PerlIO_funcs *self, PerlIO_list_t *layers,
                        mode = PerlIOStdio_mode(mode, tmode);
                    f = PerlIO_push(aTHX_ f, self, mode, PerlIOArg);
                    if (f) {
-                       s = PerlIOSelf(f, PerlIOStdio);
-                       s->stdio = stdio;
-                       PerlIOUnix_refcnt_inc(fileno(s->stdio));
+                       PerlIOSelf(f, PerlIOStdio)->stdio = stdio;
+                       PerlIOUnix_refcnt_inc(fileno(stdio));
+                   } else {
+                       PerlSIO_fclose(stdio);
                    }
                    return f;
                }
@@ -2912,9 +2902,8 @@ PerlIOStdio_open(pTHX_ PerlIO_funcs *self, PerlIO_list_t *layers,
                    f = PerlIO_allocate(aTHX);
                }
                if ((f = PerlIO_push(aTHX_ f, self, mode, PerlIOArg))) {
-                   PerlIOStdio * const s = PerlIOSelf(f, PerlIOStdio);
-                   s->stdio = stdio;
-                   PerlIOUnix_refcnt_inc(fileno(s->stdio));
+                   PerlIOSelf(f, PerlIOStdio)->stdio = stdio;
+                   PerlIOUnix_refcnt_inc(fileno(stdio));
                }
                return f;
            }
@@ -2940,7 +2929,7 @@ PerlIOStdio_dup(pTHX_ PerlIO *f, PerlIO *o, CLONE_PARAMS *param, int flags)
                goto set_this;
            }
            else {
-               /*EMPTY*/;
+               NOOP;
                /* FIXME: To avoid messy error recovery if dup fails
                   re-use the existing stdio as though flag was not set
                 */
@@ -3229,7 +3218,7 @@ PerlIOStdio_flush(pTHX_ PerlIO *f)
        return PerlSIO_fflush(stdio);
     }
     else {
-       /*EMPTY*/;
+       NOOP;
 #if 0
        /*
         * FIXME: This discards ungetc() and pre-read stuff which is not
@@ -3709,7 +3698,7 @@ PerlIOBuf_fill(pTHX_ PerlIO *f)
     if (!b->buf)
        PerlIO_get_base(f);     /* allocate via vtable */
 
-    assert(b->buf);
+    assert(b->buf); /* The b->buf does get allocated via the vtable system. */
 
     b->ptr = b->end = b->buf;
 
@@ -4371,7 +4360,7 @@ PerlIOCrlf_set_ptrcnt(pTHX_ PerlIO *f, STDCHAR * ptr, SSize_t cnt)
        ptr -= cnt;
     }
     else {
-       /*EMPTY*/;
+       NOOP;
 #if 0
        /*
         * Test code - delete when it works ...
@@ -5038,6 +5027,36 @@ PerlIO_tmpfile(void)
  * Now some functions in terms of above which may be needed even if we are
  * not in true PerlIO mode
  */
+const char *
+Perl_PerlIO_context_layers(pTHX_ const char *mode)
+{
+    dVAR;
+    const char *type = NULL;
+    /*
+     * Need to supply default layer info from open.pm
+     */
+    if (PL_curcop && PL_curcop->cop_hints & HINT_LEXICAL_IO) {
+       SV * const layers
+           = Perl_refcounted_he_fetch(aTHX_ PL_curcop->cop_hints_hash, 0,
+                                      "open", 4, 0, 0);
+       assert(layers);
+       if (SvOK(layers)) {
+           STRLEN len;
+           type = SvPV_const(layers, len);
+           if (type && mode && mode[0] != 'r') {
+               /*
+                * Skip to write part, which is separated by a '\0'
+                */
+               STRLEN read_len = strlen(type);
+               if (read_len < len) {
+                   type += read_len + 1;
+               }
+           }
+       }
+    }
+    return type;
+}
+
 
 #ifndef HAS_FSETPOS
 #undef PerlIO_setpos
@@ -5128,16 +5147,15 @@ vfprintf(FILE *fd, char *pat, char *args)
 int
 PerlIO_vsprintf(char *s, int n, const char *fmt, va_list ap)
 {
-    dVAR;
-    const int val = vsprintf(s, fmt, ap);
-    if (n >= 0) {
-       if (strlen(s) >= (STRLEN) n) {
-           dTHX;
-           (void) PerlIO_puts(Perl_error_log,
-                              "panic: sprintf overflow - memory corrupted!\n");
-           my_exit(1);
-       }
+    dTHX; 
+    const int val = my_vsnprintf(s, n > 0 ? n : 0, fmt, ap);
+    PERL_UNUSED_CONTEXT;
+
+#ifndef PERL_MY_VSNPRINTF_GUARDED
+    if (val < 0 || (n > 0 ? val >= n : 0)) {
+       Perl_croak(aTHX_ "panic: my_vsnprintf overflow in PerlIO_vsprintf\n");
     }
+#endif
     return val;
 }
 #endif