summaryrefslogtreecommitdiff
path: root/pod/perlhacktips.pod
diff options
context:
space:
mode:
authorKarl Williamson <khw@cpan.org>2015-03-28 20:54:49 -0600
committerKarl Williamson <khw@cpan.org>2015-03-28 20:58:54 -0600
commit38f18a308b948c6eaf187519a16d060e1ec7cc20 (patch)
treeaea52bc4f6f7535f3d00cc811bc8953603d8b222 /pod/perlhacktips.pod
parent008e8e82d7383361068156624879df7566121878 (diff)
downloadperl-38f18a308b948c6eaf187519a16d060e1ec7cc20.tar.gz
perlhacktips: Add caution about clib ptr returns to static memory
Diffstat (limited to 'pod/perlhacktips.pod')
-rw-r--r--pod/perlhacktips.pod33
1 files changed, 33 insertions, 0 deletions
diff --git a/pod/perlhacktips.pod b/pod/perlhacktips.pod
index 7b345167b8..834c8c8766 100644
--- a/pod/perlhacktips.pod
+++ b/pod/perlhacktips.pod
@@ -574,6 +574,39 @@ temporarily try the following:
But in any case, try to keep the features and operating systems
separate.
+=item *
+
+Assuming the contents of static memory pointed to by the return values
+of Perl wrappers for C library functions doesn't change. Many C library
+functions return pointers to static storage that can be overwritten by
+subsequent calls to the same or related functions. Perl has
+light-weight wrappers for some of these functions, and which don't make
+copies of the static memory. A good example is the interface to the
+environment variables that are in effect for the program. Perl has
+C<PerlEnv_getenv> to get values from the environment. But the return is
+a pointer to static memory in the C library. If you are using the value
+to immediately test for something, that's fine, but if you save the
+value and expect it to be unchanged by later processing, you would be
+wrong, but perhaps you wouldn't know it because different C library
+implementations behave differently, and the one on the platform you're
+testing on might work for your situation. But on some platforms, a
+subsequent call to C<PerlEnv_getenv> or related function WILL overwrite
+the memory that your first call points to. This has led to some
+hard-to-debug problems. Do a L<perlapi/savepv> to make a copy, thus
+avoiding these problems. You will have to free the copy when you're
+done to avoid memory leaks. If you don't have control over when it gets
+freed, you'll need to make the copy in a mortal scalar, like so:
+
+ if ((s = PerlEnv_getenv("foo") == NULL) {
+ ... /* handle NULL case */
+ }
+ else {
+ s = SvPVX(sv_2mortal(newSVpv(s, 0)));
+ }
+
+The above example works only if C<"s"> is C<NUL>-terminated; otherwise
+you have to pass its length to C<newSVpv>.
+
=back
=head2 Problematic System Interfaces