This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Various updates and fixes to some of the SysV IPC ops and their tests
[perl5.git] / util.c
diff --git a/util.c b/util.c
index 5d2d1ba..5989a58 100644 (file)
--- a/util.c
+++ b/util.c
@@ -542,55 +542,68 @@ Free_t   Perl_mfree (Malloc_t where)
 #define DELIMCPY_OUT_OF_BOUNDS_RET  I32_MAX
 
 /*
 #define DELIMCPY_OUT_OF_BOUNDS_RET  I32_MAX
 
 /*
-=for apidoc_section String Handling
+=for apidoc_section $string
 =for apidoc delimcpy_no_escape
 
 Copy a source buffer to a destination buffer, stopping at (but not including)
 =for apidoc delimcpy_no_escape
 
 Copy a source buffer to a destination buffer, stopping at (but not including)
-the first occurrence of the delimiter byte C<delim>, in the source.  The source
-is the bytes between C<from> and C<fromend> inclusive.  The dest is C<to>
-through C<toend>.
+the first occurrence in the source of the delimiter byte, C<delim>.  The source
+is the bytes between S<C<from> and C<from_end> - 1>.  Similarly, the dest is
+C<to> up to C<to_end>.
 
 
-Nothing is copied beyond what fits between C<to> through C<toend>.  If C<delim>
-doesn't occur in the source buffer, as much of the source as will fit is copied
-to the destination.
+The number of bytes copied is written to C<*retlen>.
 
 
-The actual number of bytes copied is written to C<*retlen>.
+Returns the position of C<delim> in the C<from> buffer, but if there is no
+such occurrence before C<from_end>, then C<from_end> is returned, and the entire
+buffer S<C<from> .. C<from_end> - 1> is copied.
 
 If there is room in the destination available after the copy, an extra
 
 If there is room in the destination available after the copy, an extra
-terminating safety NUL byte is written (not included in the returned length).
+terminating safety C<NUL> byte is appended (not included in the returned
+length).
+
+The error case is if the destination buffer is not large enough to accommodate
+everything that should be copied.  In this situation, a value larger than
+S<C<to_end> - C<to>> is written to C<*retlen>, and as much of the source as
+fits will be written to the destination.  Not having room for the safety C<NUL>
+is not considered an error.
 
 =cut
 */
 char *
 
 =cut
 */
 char *
-Perl_delimcpy_no_escape(char *to, const char *toend, const char *from,
-                       const char *fromend, int delim, I32 *retlen)
+Perl_delimcpy_no_escape(char *to, const char *to_end,
+                        const char *from, const char *from_end,
+                        const int delim, I32 *retlen)
 {
     const char * delim_pos;
 {
     const char * delim_pos;
-    Ptrdiff_t to_len = toend - to;
-
-    /* Only use the minimum of the available source/dest */
-    Ptrdiff_t copy_len = MIN(fromend - from, to_len);
+    Ptrdiff_t from_len = from_end - from;
+    Ptrdiff_t to_len = to_end - to;
+    SSize_t copy_len;
 
     PERL_ARGS_ASSERT_DELIMCPY_NO_ESCAPE;
 
 
     PERL_ARGS_ASSERT_DELIMCPY_NO_ESCAPE;
 
-    assert(copy_len >= 0);
+    assert(from_len >= 0);
+    assert(to_len >= 0);
 
 
-    /* Look for the first delimiter in the portion of the source we are allowed
-     * to look at (determined by the input bounds). */
-    delim_pos = (const char *) memchr(from, delim, copy_len);
-    if (delim_pos) {
-        copy_len = delim_pos - from;
-    } /* else didn't find it: copy all of the source permitted */
+    /* Look for the first delimiter in the source */
+    delim_pos = (const char *) memchr(from, delim, from_len);
 
 
-    Copy(from, to, copy_len, char);
+    /* Copy up to where the delimiter was found, or the entire buffer if not
+     * found */
+    copy_len = (delim_pos) ? delim_pos - from : from_len;
 
 
-    if (retlen) {
-        *retlen = copy_len;
+    /* If not enough room, copy as much as can fit, and set error return */
+    if (copy_len > to_len) {
+        Copy(from, to, to_len, char);
+        *retlen = DELIMCPY_OUT_OF_BOUNDS_RET;
     }
     }
+    else {
+        Copy(from, to, copy_len, char);
 
 
-    /* If there is extra space available, add a trailing NUL */
-    if (copy_len < to_len) {
-        to[copy_len] = '\0';
+        /* If there is extra space available, add a trailing NUL */
+        if (copy_len < to_len) {
+            to[copy_len] = '\0';
+        }
+
+        *retlen = copy_len;
     }
 
     return (char *) from + copy_len;
     }
 
     return (char *) from + copy_len;
@@ -1288,7 +1301,7 @@ Perl_cntrl_to_mnemonic(const U8 c)
 /* copy a string to a safe spot */
 
 /*
 /* copy a string to a safe spot */
 
 /*
-=for apidoc_section String Handling
+=for apidoc_section $string
 =for apidoc savepv
 
 Perl's version of C<strdup()>.  Returns a pointer to a newly allocated
 =for apidoc savepv
 
 Perl's version of C<strdup()>.  Returns a pointer to a newly allocated
@@ -1495,7 +1508,7 @@ Perl_form_nocontext(const char* pat, ...)
 #endif /* PERL_IMPLICIT_CONTEXT */
 
 /*
 #endif /* PERL_IMPLICIT_CONTEXT */
 
 /*
-=for apidoc_section Display and Dump functions
+=for apidoc_section $display
 =for apidoc form
 =for apidoc_item form_nocontext
 
 =for apidoc form
 =for apidoc_item form_nocontext
 
@@ -1783,7 +1796,7 @@ Perl_write_to_stderr(pTHX_ SV* msv)
 }
 
 /*
 }
 
 /*
-=for apidoc_section Warning and Dieing
+=for apidoc_section $warning
 */
 
 /* Common code used in dieing and warning */
 */
 
 /* Common code used in dieing and warning */
@@ -2435,7 +2448,7 @@ S_env_alloc(void *current, Size_t l1, Size_t l2, Size_t l3, Size_t size)
 #  if !defined(WIN32) && !defined(NETWARE)
 
 /*
 #  if !defined(WIN32) && !defined(NETWARE)
 
 /*
-=for apidoc_section Utility Functions
+=for apidoc_section $utility
 =for apidoc my_setenv
 
 A wrapper for the C library L<setenv(3)>.  Don't use the latter, as the perl
 =for apidoc my_setenv
 
 A wrapper for the C library L<setenv(3)>.  Don't use the latter, as the perl
@@ -3022,7 +3035,7 @@ dup2(int oldfd, int newfd)
 #ifdef HAS_SIGACTION
 
 /*
 #ifdef HAS_SIGACTION
 
 /*
-=for apidoc_section Signals
+=for apidoc_section $signals
 =for apidoc rsignal
 
 A wrapper for the C library L<signal(2)>.  Don't use the latter, as the Perl
 =for apidoc rsignal
 
 A wrapper for the C library L<signal(2)>.  Don't use the latter, as the Perl
@@ -3933,7 +3946,7 @@ Perl_init_tm(pTHX_ struct tm *ptm)        /* see mktime, strftime and asctime */
 }
 
 /*
 }
 
 /*
-=for apidoc_section Time
+=for apidoc_section $time
 =for apidoc mini_mktime
 normalise S<C<struct tm>> values without the localtime() semantics (and
 overhead) of mktime().
 =for apidoc mini_mktime
 normalise S<C<struct tm>> values without the localtime() semantics (and
 overhead) of mktime().
@@ -4133,7 +4146,7 @@ Perl_my_strftime(pTHX_ const char *fmt, int sec, int min, int hour, int mday, in
 #ifdef HAS_STRFTIME
 
 /*
 #ifdef HAS_STRFTIME
 
 /*
-=for apidoc_section Time
+=for apidoc_section $time
 =for apidoc my_strftime
 strftime(), but with a different API so that the return value is a pointer
 to the formatted result (which MUST be arranged to be FREED BY THE
 =for apidoc my_strftime
 strftime(), but with a different API so that the return value is a pointer
 to the formatted result (which MUST be arranged to be FREED BY THE
@@ -4242,7 +4255,7 @@ mini_mktime() overwrites them
        (dp->d_name[1] == '.' && dp->d_name[2] == '\0')))
 
 /*
        (dp->d_name[1] == '.' && dp->d_name[2] == '\0')))
 
 /*
-=for apidoc_section Utility Functions
+=for apidoc_section $utility
 
 =for apidoc getcwd_sv
 
 
 =for apidoc getcwd_sv
 
@@ -5150,7 +5163,7 @@ Perl_mem_log_del_sv(const SV *sv,
 #endif /* PERL_MEM_LOG */
 
 /*
 #endif /* PERL_MEM_LOG */
 
 /*
-=for apidoc_section String Handling
+=for apidoc_section $string
 =for apidoc quadmath_format_valid
 
 C<quadmath_snprintf()> is very strict about its C<format> string and will
 =for apidoc quadmath_format_valid
 
 C<quadmath_snprintf()> is very strict about its C<format> string and will
@@ -6327,7 +6340,7 @@ static void atos_symbolize(atos_context* ctx,
 #endif /* #ifdef PERL_DARWIN */
 
 /*
 #endif /* #ifdef PERL_DARWIN */
 
 /*
-=for apidoc_section Display and Dump functions
+=for apidoc_section $debugging
 =for apidoc get_c_backtrace
 
 Collects the backtrace (aka "stacktrace") into a single linear
 =for apidoc get_c_backtrace
 
 Collects the backtrace (aka "stacktrace") into a single linear
@@ -6579,7 +6592,6 @@ Deallocates a backtrace received from get_c_backtrace.
 */
 
 /*
 */
 
 /*
-=for apidoc_section Display and Dump functions
 =for apidoc get_c_backtrace_dump
 
 Returns a SV containing a dump of C<depth> frames of the call stack, skipping
 =for apidoc get_c_backtrace_dump
 
 Returns a SV containing a dump of C<depth> frames of the call stack, skipping