Re: [exim] Returning static strings from dlfunc?

Top Page
Delete this message
Reply to this message
Author: Phil Pennock
Date:  
To: Janne Snabb
CC: exim-users
Subject: Re: [exim] Returning static strings from dlfunc?
On 2012-05-07 at 10:44 +0700, Janne Snabb wrote:
> I am writing my first dlfunc. My question is: Is it ok to return a
> pointer to a static string? I could not find answer to this in the
> documentation.


It Depends. What is the caller going to do with the result, and might
it try to modify it with strtok(), for instance?

Also, my knowledge of Exim is not encyclopaedic, so there may be some
place where it would break.

> int foobar(uschar **yield, int argc, uschar *argv[])
> {
>         *yield = US"foobar";
>         return OK;
> }

>
> Is the above correct, or should I write the following instead?


It's not valid C, since you're assigning a const unsigned char * to a
place which is not const, so with warnings turned up you'll get
complaints about assignment dropping const.

>     *yield = string_copy(US"foobar");


This is safer. It will make a copy which should be valid for the
lifetime of the current memory allocation pool, and the caller should
have made that a longer-lived pool if necessary for its purposes.
Memory allocation of smaller objects is lighter-weight than malloc, so
you *should* be okay with just doing this.

The benefit of allocation pools is that you can have a pool for a
particular context and, when you finish with that context, throw away
the pool in one go, knowing that anything which still wants a copy past
that context was responsible for keeping a copy of the variable in a
different context with the requisite lifetime. So there's one free()
instead of hundreds or thousands. For small strings, this is a major
win.

So: string_copy() will place the memory in context the caller wants,
will be const-safe, is fairly lightweight and, if something *does*
depend upon being able to modify the string in-place (replacing
whitespace with NUL characters, for instance), then you won't end up
trying to modify contents of a read-only page of memory.

Using string_copy() means that a crash outside your code is probably not
your fault. Go ahead, shift the blame onto the Exim Maintainers and any
problems with the robustness of our APIs. :)

-Phil