0

The pointer returned by getenv should not be stored, as future calls to getenv could change it (or calls to setenv, etc). I am attempting to write a convenience wrapper around getenv which returns a default value if the environment variable is not found. I would prefer to not leak memory.

Options I've thought of:
Have the wrapper function copy the string getenv returns, either using malloc and strcpy or strdup (this is on a POSIX-compliant system). This works and allows error handling, but requires the caller to remember to free the pointer. That creates room for a memory leak.
Don't bother trying to cache the value, have each caller do that instead. This makes it easy to leave the race condition in. Use a global variable to store a copy of the string getenv returns. This would avoid the need for callers to free the memory, but would risk race conditions just like getenv alone unless I add some sort of locking/atomic updates.
Use a static variable in the function to cache the value. This is probably the best option, as it reuses the memory for subsequent calls, but can lead to race conditions.

I'm reasonably certain I'm missing something.

  • What are you using the `getenv` value for? Why do you want `getenv` to return a fictitious default value? Why not call `getenv` whenever you need to read the value instead of trying to store it? – fbynite Nov 26 '18 at 18:15
  • 1. Getting values and logging an error if it hasn't been set. 2. It's a real default, it's just for the case when someone forgot to initialize the environment variable. 3. Legacy code, more risk of breaking things if devs have to remember to check that getenv returned a result. – Carl Mitchell Nov 26 '18 at 18:37
  • I would initalize/set-up the environment when the program begins to run, this is when the default value will be set. On point 3, devs will still have to check the returned value of your wrapper function to be sure it suceeded. – fbynite Nov 26 '18 at 19:19
  • Are you just trying to prevent your devs from getting NULL as the result, or do you also want to hide real pointer getenv returns from them for some reason? – Lev M. Nov 26 '18 at 20:30
  • Both. There are possible calls to setenv which would invalidate the pointer getenv returns. – Carl Mitchell Nov 26 '18 at 21:24

1 Answers1

2

This is not true:

The pointer returned by getenv should not be stored, as future calls to getenv could change it

The following is:

(or calls to setenv, etc...

However, the conclusion here is just that you can't use setenv (or anything that modifies the environment) in a multithreaded process. Doing so also renders thread-unsafe any standard function which uses the environment.

So, go ahead using getenv and treat the strings its return values point to as immutable.

R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711