putenv.c 922 B

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