Re: g_setenv g_unsetenv
- From: Maciej Stachowiak <mjs eazel com>
- To: George <jirka 5z com>
- Cc: Tim Janik <timj gtk org>, gtk-devel-list gnome org
- Subject: Re: g_setenv g_unsetenv
- Date: 07 Sep 2000 03:28:20 -0700
George <jirka 5z com> writes:
> On Wed, Sep 06, 2000 at 12:37:39PM +0200, Tim Janik wrote:
> > > I think this should go into glib and I'd be willing to write it. Now the
> > > question is, would it be accepted?
> >
> > i'd love to see portable versions for this.
>
> Here's what I have after about an hour of research. First after looking and
> seeing that while putenv is on most systems, it works somewhat differently, I
> started implementing a scheme that something like "screen" uses. That is on
> first g_putenv (or whatever it would be named), the entire environment is
> copied onto the heap. Then we can do good memory management upon it. Then
> it hit me. If another part of the program did a putenv, we'd get majorly
> screwed, so I think that approach is too fragile. Another approach might be
> keeping some bookkeeping information, however, I'm not sure that the cost of
> this is actually worth plugging the leaks which are not too bad. So I
> decided that on systems without setenv, g_setenv would just leak each time
> you do it, that's the only sane / portable way to get this to work
> apparently. The other problem is unsetenv. Different systems with putenv
> seem to handle it differently, namely either putenv("name") or
> putenv("name="), if they handle the case at all. It's however quite easy to
> implement unsetenv by hand by just twiddling the "environ" global (which
> should be standard C as far as I know). In fact as far as I could tell, the
> only ANSI-C parts are the environ, and getenv. So apparently there could be
> systems out there that do not have setenv nor putenv.
putenv is POSIX so I think we can assume it on all Unixish platforms.
Also, I think twiddling environ is dangerous, neither ANSI nor POSIX
nor anything else guarantees that modifying environ will result in
those changes propogating to child processes. I think a configure
check should be able to determine if putenv("name=") or putenv
("name") is the right thing.
> So I intend to write
> support for those as well. Well here's my current stab at it (doesn't
> include windows stuff as apparently it would need to use some windows
> specific functions, but as far as I could tell those should be in the spirit
> of setenv, also this is not tested at all, just posted here as food for
> thought):
>
> gint
> g_setenv (const gchar *name, const gchar *value, gboolean overwrite)
> {
> #if defined(HAVE_SETENV)
> return setenv (name, value, overwrite);
> #elif defined(G_OS_WIN32)
> /* FOO */
Should probably not even define the function in this case, I think.
> #else
> gchar *string;
>
> if ( ! overwrite &&
> g_getenv (name) != NULL)
> return 0;
>
> /* A leak. But there is absolutely no apparent
> * way to get around this other then an incredible
> * mess with the environ variable */
> string = g_strconcat (name, '=', value, NULL);
You mean "=", not '='
> return putenv (string);
> #endif
> }
>
> /* We will need this for unsetenv if there
> * is no unsetenv */
> #if !defined(HAVE_SETENV) && !defined(G_OS_WIN32)
> extern gchar **environ;
> #endif
>
> void
> g_unsetenv (const gchar *name)
> {
> #if defined(HAVE_SETENV)
> unsetenv (name);
> #elif defined(G_OS_WIN32)
> /* FOO */
> #else
> gint i;
> gint len;
>
> len = strlen (name);
>
> /* Mess directly with the environ array, apparently
> * this seems to be the only portable way to do this */
As I said above, I'd suggest using putenv if available.
> for (i = 0; environ[i] != NULL; i++)
> {
> if (strncmp (environ[i], name, len) == 0 &&
> environ[i][len + 1] == '=')
> break;
> }
>
> while (environ[i] != NULL)
> {
> environ[i] = environ[i + 1];
> i++;
> }
> #endif
> }
>
>
> Now the question is, how far should this be taken. Do we want book keeping?
> Or do we just accept memleaks. Note that bookkeeping will never be perfect
> if intermixed with normal setenv, putenv calls, and may be more expensive
> then the memleaks.
>
Well you can never guarantee that some library out there won't call
setenv() or putenv(), it's probably safer not to leak.
- Maciej
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]