From 10fd3e073fa937e173e5a6e90aa7f27462675433 Mon Sep 17 00:00:00 2001 From: Karl Williamson Date: Wed, 16 Dec 2020 13:17:56 -0700 Subject: [PATCH] XXX incomplete perlhacktips: --- pod/perlhacktips.pod | 51 ++++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/pod/perlhacktips.pod b/pod/perlhacktips.pod index 769c2f6714d4..bb7cf7719c60 100644 --- a/pod/perlhacktips.pod +++ b/pod/perlhacktips.pod @@ -607,32 +607,31 @@ 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 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 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 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-terminated; otherwise -you have to pass its length to C. +light-weight wrappers for some of these functions, and which propagate +this issue on to the caller, you. You'll have to save or finish using +the result before calling the function again. In some cases they aren't +thread safe, and you'll need to save or use the value before any other +thread can call that function. You don't generally have control over +when such a thread might want to use that function, so this can cause a +race. L has some information on +such functions, and ways to cope. But it may come down to not using a +problematic function at all, or protecting its use with a mutex, and +being sure that any other applications that might be running in another +thread also use that mutex. Until Perl 5.32, C was such +a function, but now it returns a mortalized copy of the result. But +again, if someone is writing to the environment without using the mutext +that C<> expects, they can memory in the C library, which could be +overwritten at any time by another thread accessing the environment in +some way, or on some platforms, by a subsequent C call. + +the interface to the + +environment variables that are in effect for the program. Prior to Perl +5.32, C, to get values from the environment, also was +such a function. But starting in that release, the return is a mortal +copy of what is in the environment, so is safe to use in the remainder +of the calling function, but needs to be copied if you want a stable +value beyond that. =back