1 /*-------------------------------------------------------------------------
2  *
3  * unsetenv.c
4  *	  unsetenv() emulation for machines without it
5  *
6  * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  *
10  * IDENTIFICATION
11  *	  src/port/unsetenv.c
12  *
13  *-------------------------------------------------------------------------
14  */
15 
16 #include "c.h"
17 
18 
19 int
unsetenv(const char * name)20 unsetenv(const char *name)
21 {
22 	char	   *envstr;
23 
24 	/* Error conditions, per POSIX */
25 	if (name == NULL || name[0] == '\0' || strchr(name, '=') != NULL)
26 	{
27 		errno = EINVAL;
28 		return -1;
29 	}
30 
31 	if (getenv(name) == NULL)
32 		return 0;				/* no work */
33 
34 	/*
35 	 * The technique embodied here works if libc follows the Single Unix Spec
36 	 * and actually uses the storage passed to putenv() to hold the environ
37 	 * entry.  When we clobber the entry in the second step we are ensuring
38 	 * that we zap the actual environ member.  However, there are some libc
39 	 * implementations (notably recent BSDs) that do not obey SUS but copy the
40 	 * presented string.  This method fails on such platforms.  Hopefully all
41 	 * such platforms have unsetenv() and thus won't be using this hack. See:
42 	 * http://www.greenend.org.uk/rjk/2008/putenv.html
43 	 *
44 	 * Note that repeatedly setting and unsetting a var using this code will
45 	 * leak memory.
46 	 */
47 
48 	envstr = (char *) malloc(strlen(name) + 2);
49 	if (!envstr)				/* not much we can do if no memory */
50 		return -1;
51 
52 	/* Override the existing setting by forcibly defining the var */
53 	sprintf(envstr, "%s=", name);
54 	if (putenv(envstr))
55 		return -1;
56 
57 	/* Now we can clobber the variable definition this way: */
58 	strcpy(envstr, "=");
59 
60 	/*
61 	 * This last putenv cleans up if we have multiple zero-length names as a
62 	 * result of unsetting multiple things.
63 	 */
64 	return putenv(envstr);
65 }
66