commit 4789e27968b8a0830c7a9bebfd6a2e6cc96cb9c6 Author: Christian Höltje Date: Tue Nov 10 14:22:45 2009 -0500 Fixed ruby_setenv for Solaris. Older versions of Solaris don't have setenv()/unsetenv(). If you use the environment manipulation that is the fallback, then ruby will crash sometimes. In addition, the resulting binary will not be portable to newer versions of Solaris causing crashes everytime the environment is set. diff --git a/hash.c b/hash.c index 8b1c68f..6e8e359 100644 --- a/hash.c +++ b/hash.c @@ -2057,6 +2057,45 @@ ruby_setenv(const char *name, const char *value) setenv(name,value,1); else unsetenv(name); +#elif defined (__SVR4) && defined (__sun) + /* + * Older versions of Solaris don't have a working setenv/unsetenv. + * + * However, using the realloc method below (in the #else) will + * causes segfaults and "unable to allocate memory" errors in + * some situations. In addition, in newer version of Solaris it + * will fail nearly all the time since the environment mechanism + * has changed. + * + * Note: This does leak memory and there isn't anything we can do + * about it. + */ + size_t len; + if (value) { + /* setenv() behavior */ + char *str; + len = strlen(name) + strlen(value) + 2; + str = ALLOC_N(char, len); + snprintf(str, len, "%s=%s", name, value); + putenv(str); + } else { + /* unsetenv() behavior */ + char **env_ptr; + len = strlen(name); + env_ptr = GET_ENVIRON(environ); + while (*env_ptr != NULL) { + if (!strncmp(*env_ptr, name, len) && (*env_ptr)[len] == '=') { + /* Found the variable name. */ + char **tmp_env_ptr = env_ptr; + do { + tmp_env_ptr[0] = tmp_env_ptr[1]; + } while (*tmp_env_ptr++); + /* Continue the loop in case name appears again. */ + } else { + ++env_ptr; + } + } + } #else /* WIN32 */ size_t len; int i=envix(name); /* where does it go? */