putenv.c raw

   1  #include <stdlib.h>
   2  #include <string.h>
   3  #include <unistd.h>
   4  
   5  static void dummy(char *old, char *new) {}
   6  weak_alias(dummy, __env_rm_add);
   7  
   8  int __putenv(char *s, size_t l, char *r)
   9  {
  10  	size_t i=0;
  11  	if (__environ) {
  12  		for (char **e = __environ; *e; e++, i++)
  13  			if (!strncmp(s, *e, l+1)) {
  14  				char *tmp = *e;
  15  				*e = s;
  16  				__env_rm_add(tmp, r);
  17  				return 0;
  18  			}
  19  	}
  20  	static char **oldenv;
  21  	char **newenv;
  22  	if (__environ == oldenv) {
  23  		newenv = realloc(oldenv, sizeof *newenv * (i+2));
  24  		if (!newenv) goto oom;
  25  	} else {
  26  		newenv = malloc(sizeof *newenv * (i+2));
  27  		if (!newenv) goto oom;
  28  		if (i) memcpy(newenv, __environ, sizeof *newenv * i);
  29  		free(oldenv);
  30  	}
  31  	newenv[i] = s;
  32  	newenv[i+1] = 0;
  33  	__environ = oldenv = newenv;
  34  	if (r) __env_rm_add(0, r);
  35  	return 0;
  36  oom:
  37  	free(r);
  38  	return -1;
  39  }
  40  
  41  int putenv(char *s)
  42  {
  43  	size_t l = __strchrnul(s, '=') - s;
  44  	if (!l || !s[l]) return unsetenv(s);
  45  	return __putenv(s, l, 0);
  46  }
  47