Branch: Tag:

2008-07-08

2008-07-08 12:27:05 by Henrik Grubbström (Grubba) <grubba@grubba.org>

Now uses {,un}setenv(3) in preference to putenv(3).

Rev: src/builtin.cmod:1.222

2:   || This file is part of Pike. For copyright information see COPYRIGHT.   || Pike is distributed under GPL, LGPL and MPL. See the file COPYING   || for more information. - || $Id: builtin.cmod,v 1.221 2008/06/30 10:01:54 grubba Exp $ + || $Id: builtin.cmod,v 1.222 2008/07/08 12:27:05 grubba Exp $   */      #include "global.h"
1250:    pop_stack();   }    + #if defined(HAVE_SETENV) && defined(HAVE_UNSETENV) + #define USE_SETENV + #else   /* Used to hold refs to the strings that we feed to putenv. Indexed on -  * variable names, values are the "name=value" strings. */ +  * variable names, values are the "name=value" strings. +  * +  * This is not needed when using {,un}setenv(), since they maintain +  * their own corresponding table. */   static struct mapping *env_allocs = NULL; -  + #endif      /* Works exactly like the getenv efun defined in the master, but only    * accesses the real environment. Everyone should use the caching
1300:    for (n = 0; environ[n]; n++) {}       m = allocate_mapping (n); + #ifndef USE_SETENV    if (env_allocs)    new_env_allocs = allocate_mapping (m_sizeof (env_allocs)); -  + #endif /* !USE_SETENV */       while (--n >= 0) {    char *entry = environ[n], *eq = STRCHR (entry, '=');
1310:    struct pike_string *val = make_shared_string (eq + 1);    mapping_string_insert_string (m, var, val);    + #ifndef USE_SETENV    /* Populate new_env_allocs with the env_allocs entries that    * are still in use. */    if (env_allocs) {
1317:    if (ea_val && ea_val->u.string->str == entry)    mapping_string_insert (new_env_allocs, var, ea_val);    } + #endif /* !USE_SETENV */       free_string (var);    free_string (val);    }    }    -  + #ifndef USE_SETENV    if (env_allocs) {    free_mapping (env_allocs);    env_allocs = new_env_allocs;    } -  + #endif /* !USE_SETENV */       push_mapping (m);    }
1337:    * the master instead so that the cache doesn't get stale. */   PIKEFUN void _putenv (string var, void|string val)   { + #ifndef USE_SETENV    struct pike_string *putenv_str, *env_alloc_var; -  + #endif       if (var->size_shift)    SIMPLE_ARG_TYPE_ERROR ("putenv", 1, "string(0..255)");
1345:    SIMPLE_ARG_ERROR ("putenv", 1, "Variable name cannot contain '=' or NUL.");       if (val) { + #ifndef USE_SETENV    struct string_builder sb; -  + #endif       if (val->size_shift)    SIMPLE_ARG_TYPE_ERROR ("putenv", 2, "void|string(0..255)");    if (string_has_null (val))    SIMPLE_ARG_ERROR ("putenv", 2, "Variable value cannot contain NUL.");    -  + #ifdef USE_SETENV +  if (setenv(var->str, val->str, 1)) { +  if (errno == ENOMEM) +  SIMPLE_OUT_OF_MEMORY_ERROR ("putenv", 0); +  else +  Pike_error ("Error from setenv(3): %s\n", strerror (errno)); +  } + #else /* !USE_SETENV */    init_string_builder (&sb, 0);    string_builder_shared_strcat (&sb, var);    string_builder_putchar (&sb, '=');    string_builder_shared_strcat (&sb, val);    putenv_str = finish_string_builder (&sb);    push_string (putenv_str); /* Let mega_apply pop. */ -  + #endif /* USE_SETENV */    }    else { -  + #ifdef USE_SETENV +  /* Note: Some versions of glibc have a unsetenv(3) that returns void, +  * thus no checking of the return value here. +  */ +  unsetenv(var->str); + #else /* !USE_SETENV */   #ifdef PUTENV_ALWAYS_REQUIRES_EQUAL    /* Windows can never get things quite right.. :P */    struct string_builder sb;
1371:   #else    putenv_str = var;   #endif + #endif /* USE_SETENV */    }    -  + #ifndef USE_SETENV    if (putenv (putenv_str->str)) {    if (errno == ENOMEM)    SIMPLE_OUT_OF_MEMORY_ERROR ("putenv", 0);
1402:    key.u.string = env_alloc_var;    map_delete (env_allocs, &key);    } + #endif /* !USE_SETENV */   }      /*
3932:   {    EXIT    free_all_pike_list_node_blocks(); + #ifndef USE_SETENV    if (env_allocs) free_mapping (env_allocs); -  + #endif   }