From c0c7180bba2530470f37ea0c85b8435f5ff8dfc6 Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Fri, 24 Apr 2009 18:53:15 +0000 Subject: [PATCH] setenv(3) in Linux treats a NUL value as the empty string setenv(3) in BSD doesn't return an error if the name has '=' in it, it just treats the '=' as end of string. --- env.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/env.c b/env.c index 0a86a03aa..eca2fcb85 100644 --- a/env.c +++ b/env.c @@ -250,23 +250,27 @@ setenv(var, val, overwrite) int overwrite; { char *estring; + const char *varend; size_t esize; + int len; - if (strchr(var, '=') != NULL) { - errno = EINVAL; - return(-1); - } + /* + * POSIX says a var name with '=' is an error but BSD + * just ignores the '=' and anything after it. + */ + for (varend = var; *varend && *varend != '='; varend++) + ; - esize = strlen(var) + 1 + strlen(val) + 1; + if (val == NULL) + val = ""; /* glibc treats a NULL val as "" */ + + esize = (size_t)(varend - var) + 1 + strlen(val) + 1; estring = emalloc(esize); - /* Build environment string and insert it. */ - if (strlcpy(estring, var, esize) >= esize || - strlcat(estring, "=", esize) >= esize || - strlcat(estring, val, esize) >= esize) { - + len = snprintf(estring, esize, "%.*s=%s", (int)(varend - var), var, val); + if (len < 0 && len >= esize) errorx(1, "internal error, setenv() overflow"); - } + /* Sync env.envp with environ as needed. */ if (env.envp != environ) { char **ep;