summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--config_h.SH8
-rw-r--r--embed.fnc4
-rw-r--r--embed.h4
-rw-r--r--global.sym1
-rw-r--r--makedef.pl5
-rw-r--r--perl.h10
-rw-r--r--proto.h7
-rw-r--r--util.c25
8 files changed, 62 insertions, 2 deletions
diff --git a/config_h.SH b/config_h.SH
index 15d8b43749..e6e7f9b7c8 100644
--- a/config_h.SH
+++ b/config_h.SH
@@ -4378,5 +4378,13 @@ sed <<!GROK!THIS! >$CONFIG_H -e 's!^#undef\(.*/\)\*!/\*#define\1 \*!' -e 's!^#un
#$d_ttyname_r HAS_TTYNAME_R /**/
#define TTYNAME_R_PROTO $ttyname_r_proto /**/
+/* SPRINTF_RETURNS_STRLEN:
+ * This variable defines whether sprintf returns the length of the string
+ * (as per the ANSI spec). Some C libraries retain compatibility with
+ * pre-ANSI C and return a pointer to the passed in buffer; for these
+ * this variable will be undef.
+ */
+#$d_sprintf_returns_strlen SPRINTF_RETURNS_STRLEN /**/
+
#endif
!GROK!THIS!
diff --git a/embed.fnc b/embed.fnc
index 320c6388f4..f00f7227dd 100644
--- a/embed.fnc
+++ b/embed.fnc
@@ -1545,6 +1545,10 @@ Apo |bool |ckwarn_d |U32 w
p |void |offer_nice_chunk |NN void *chunk|U32 chunk_size
+#ifndef SPRINTF_RETURNS_STRLEN
+Apnod |int |my_sprintf |NN char *buffer|NN const char *pat|...
+#endif
+
END_EXTERN_C
/*
* ex: set ts=8 sts=4 sw=4 noet:
diff --git a/embed.h b/embed.h
index 9ccf80d0cd..d39d4c2d4e 100644
--- a/embed.h
+++ b/embed.h
@@ -1653,6 +1653,8 @@
#ifdef PERL_CORE
#define offer_nice_chunk Perl_offer_nice_chunk
#endif
+#ifndef SPRINTF_RETURNS_STRLEN
+#endif
#define ck_anoncode Perl_ck_anoncode
#define ck_bitop Perl_ck_bitop
#define ck_concat Perl_ck_concat
@@ -3639,6 +3641,8 @@
#ifdef PERL_CORE
#define offer_nice_chunk(a,b) Perl_offer_nice_chunk(aTHX_ a,b)
#endif
+#ifndef SPRINTF_RETURNS_STRLEN
+#endif
#define ck_anoncode(a) Perl_ck_anoncode(aTHX_ a)
#define ck_bitop(a) Perl_ck_bitop(aTHX_ a)
#define ck_concat(a) Perl_ck_concat(aTHX_ a)
diff --git a/global.sym b/global.sym
index fac84a0fb6..e90127d152 100644
--- a/global.sym
+++ b/global.sym
@@ -699,4 +699,5 @@ Perl_stashpv_hvname_match
Perl_gv_SVadd
Perl_ckwarn
Perl_ckwarn_d
+Perl_my_sprintf
# ex: set ro:
diff --git a/makedef.pl b/makedef.pl
index 0ee159d6cf..8975d50d72 100644
--- a/makedef.pl
+++ b/makedef.pl
@@ -819,6 +819,11 @@ unless ($define{'PERL_DONT_CREATE_GVSV'}) {
Perl_gv_SVadd
)];
}
+if ($define{'SPRINTF_RETURNS_STRLEN'}) {
+ skip_symbols [qw(
+ Perl_my_sprintf
+ )];
+}
unless ($define{'d_mmap'}) {
skip_symbols [qw(
diff --git a/perl.h b/perl.h
index 11cfc75fdb..28d2ad81a0 100644
--- a/perl.h
+++ b/perl.h
@@ -1402,6 +1402,16 @@ int sockatmark(int);
# define sprintf UTS_sprintf_wrap
#endif
+/* For the times when you want the return value of sprintf, and you want it
+ to be the length. Can't have a thread variable passed in, because C89 has
+ no varargs macros.
+*/
+#ifdef SPRINTF_RETURNS_STRLEN
+# define my_sprintf sprintf
+#else
+# define my_sprintf Perl_my_sprintf
+#endif
+
/* Configure gets this right but the UTS compiler gets it wrong.
-- Hal Morris <hom00@utsglobal.com> */
#ifdef UTS
diff --git a/proto.h b/proto.h
index 2b028a190b..08399458f8 100644
--- a/proto.h
+++ b/proto.h
@@ -4052,6 +4052,13 @@ PERL_CALLCONV void Perl_offer_nice_chunk(pTHX_ void *chunk, U32 chunk_size)
__attribute__nonnull__(pTHX_1);
+#ifndef SPRINTF_RETURNS_STRLEN
+PERL_CALLCONV int Perl_my_sprintf(char *buffer, const char *pat, ...)
+ __attribute__nonnull__(1)
+ __attribute__nonnull__(2);
+
+#endif
+
END_EXTERN_C
/*
* ex: set ts=8 sts=4 sw=4 noet:
diff --git a/util.c b/util.c
index c46a40ed04..6df7d8d29a 100644
--- a/util.c
+++ b/util.c
@@ -2707,9 +2707,9 @@ Perl_pidgone(pTHX_ Pid_t pid, int status)
{
register SV *sv;
char spid[TYPE_CHARS(IV)];
+ size_t len = my_sprintf(spid, "%"IVdf, (IV)pid);
- sprintf(spid, "%"IVdf, (IV)pid);
- sv = *hv_fetch(PL_pidstatus,spid,strlen(spid),TRUE);
+ sv = *hv_fetch(PL_pidstatus,spid,len,TRUE);
SvUPGRADE(sv,SVt_IV);
SvIV_set(sv, status);
return;
@@ -5081,6 +5081,27 @@ Perl_mem_log_free(Malloc_t oldalloc, const char *filename, const int linenumber,
#endif /* PERL_MEM_LOG */
/*
+=for apidoc my_sprintf
+
+The C library C<sprintf>, wrapped if necessary, to ensure that it will return
+the length of the string written to the buffer. Only rare pre-ANSI systems
+need the wrapper function - usually this is a direct call to C<sprintf>.
+
+=cut
+*/
+#ifndef SPRINTF_RETURNS_STRLEN
+int
+Perl_my_sprintf(char *buffer, const char* pat, ...)
+{
+ va_list args;
+ va_start(args, pat);
+ vsprintf(buffer, pat, args);
+ va_end(args);
+ return strlen(buffer);
+}
+#endif
+
+/*
* Local variables:
* c-indentation-style: bsd
* c-basic-offset: 4