4 * Implementation of POSIX standard IEEE 1003.1-2001 setenv() function;
5 * may also be invoked inline, as "retval = setenv( varname, NULL, 1 )",
6 * to implement the complementary unsetenv() function.
10 * Written by Keith Marshall <keith@users.osdn.me>
11 * Copyright (C) 2016, 2021, MinGW.org Project
14 * Permission is hereby granted, free of charge, to any person obtaining a
15 * copy of this software and associated documentation files (the "Software"),
16 * to deal in the Software without restriction, including without limitation
17 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
18 * and/or sell copies of the Software, and to permit persons to whom the
19 * Software is furnished to do so, subject to the following conditions:
21 * The above copyright notice and this permission notice shall be included
22 * in all copies or substantial portions of the Software.
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
25 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
27 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
30 * DEALINGS IN THE SOFTWARE.
33 #define _POSIX_C_SOURCE 200112L
40 int __mingw_setenv( const char *var, const char *value, int overwrite )
42 /* Core implementation for both setenv() and unsetenv() functions;
43 * at the outset, assume that the requested operation may fail.
47 /* The specified "var" name MUST be non-NULL, not a zero-length
48 * string, and must not include any '=' character.
50 if( var && *var && (strchr( var, '=' ) == NULL) )
52 /* A properly named variable may be added to, removed from,
53 * or modified within the environment, ONLY if "overwrite"
54 * mode is enabled, OR if the named variable does not yet
57 if( overwrite || getenv( var ) == NULL )
59 /* ... in which cases, we convert the specified name and
60 * value into the appropriate form for use with putenv(),
61 * (noting that we accept a NULL "value" as equivalent to
62 * a zero-length string, which renders putenv() as the
63 * equivalent of unsetenv()).
65 const char *fmt = "%s=%s";
66 const char *val = value ? value : "";
67 char buf[1 + __mingw_snprintf( NULL, 0, fmt, var, val )];
68 __mingw_snprintf( buf, sizeof( buf ), fmt, var, val );
70 /* "buf" is now formatted as "var=value", in the form
71 * required by putenv(), but it exists only within our
72 * volatile stack-frame space. POSIX.1 suggests that we
73 * should copy it to more persistent storage, before it
74 * is passed to putenv(), to associate an environment
75 * pointer with it. However, we note that Microsoft's
76 * putenv() implementation appears to make such a copy
77 * in any case, so we do not do so; (in fact, if we did
78 * strdup() it (say), then we would leak memory).
80 if( (retval = putenv( buf )) != 0 )
82 * If putenv() returns non-zero, indicating failure, the
83 * most probable explanation is that there wasn't enough
84 * free memory; ensure that errno is set accordingly.
89 /* The named variable already exists, and overwrite mode
90 * was not enabled; there is nothing to be done.
95 /* The specified environment variable name was invalid.
99 /* Succeed or fail, "retval" has now been set to indicate the
100 * appropriate status for return.
105 /* $RCSfile$: end of file */