00001 /*------------------------------------------------------------------------- 00002 * 00003 * unsetenv.c 00004 * unsetenv() emulation for machines without it 00005 * 00006 * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group 00007 * Portions Copyright (c) 1994, Regents of the University of California 00008 * 00009 * 00010 * IDENTIFICATION 00011 * src/port/unsetenv.c 00012 * 00013 *------------------------------------------------------------------------- 00014 */ 00015 00016 #include "c.h" 00017 00018 00019 void 00020 unsetenv(const char *name) 00021 { 00022 char *envstr; 00023 00024 if (getenv(name) == NULL) 00025 return; /* no work */ 00026 00027 /* 00028 * The technique embodied here works if libc follows the Single Unix Spec 00029 * and actually uses the storage passed to putenv() to hold the environ 00030 * entry. When we clobber the entry in the second step we are ensuring 00031 * that we zap the actual environ member. However, there are some libc 00032 * implementations (notably recent BSDs) that do not obey SUS but copy the 00033 * presented string. This method fails on such platforms. Hopefully all 00034 * such platforms have unsetenv() and thus won't be using this hack. See: 00035 * http://www.greenend.org.uk/rjk/2008/putenv.html 00036 * 00037 * Note that repeatedly setting and unsetting a var using this code will 00038 * leak memory. 00039 */ 00040 00041 envstr = (char *) malloc(strlen(name) + 2); 00042 if (!envstr) /* not much we can do if no memory */ 00043 return; 00044 00045 /* Override the existing setting by forcibly defining the var */ 00046 sprintf(envstr, "%s=", name); 00047 putenv(envstr); 00048 00049 /* Now we can clobber the variable definition this way: */ 00050 strcpy(envstr, "="); 00051 00052 /* 00053 * This last putenv cleans up if we have multiple zero-length names as a 00054 * result of unsetting multiple things. 00055 */ 00056 putenv(envstr); 00057 }