putenv.c 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. /*
  2. * (c) copyright 1989 by the Vrije Universiteit, Amsterdam, The Netherlands.
  3. * See the copyright notice in the ACK home directory, in the file "Copyright".
  4. */
  5. /* $Id$ */
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #define ENTRY_INC 10
  9. #define rounded(x) (((x / ENTRY_INC) + 1) * ENTRY_INC)
  10. extern const char **_penvp;
  11. extern const char **environ; /* environ is a shadow name for _penvp */
  12. int
  13. putenv(char *name)
  14. {
  15. register const char **v = _penvp;
  16. register char *r;
  17. static int size = 0;
  18. /* When size != 0, it contains the number of entries in the
  19. * table (including the final NULL pointer). This means that the
  20. * last non-null entry is _penvp[size - 2].
  21. */
  22. if (!name) return 0;
  23. if (r = strchr(name, '=')) {
  24. register const char *p, *q;
  25. *r = '\0';
  26. if (v != NULL) {
  27. while ((p = *v) != NULL) {
  28. q = name;
  29. while (*q && (*q++ == *p++))
  30. /* EMPTY */ ;
  31. if (*q || (*p != '=')) {
  32. v++;
  33. } else {
  34. /* The name was already in the
  35. * environment.
  36. */
  37. *r = '=';
  38. *v = name;
  39. return 0;
  40. }
  41. }
  42. }
  43. *r = '=';
  44. v = _penvp;
  45. }
  46. if (!size) {
  47. register const char **p;
  48. register int i = 0;
  49. if (v)
  50. do {
  51. i++;
  52. } while (*v++);
  53. if (!(v = malloc(rounded(i) * sizeof(char **))))
  54. return 1;
  55. size = i;
  56. p = _penvp;
  57. _penvp = v;
  58. while (*v++ = *p++); /* copy the environment */
  59. v = _penvp;
  60. } else if (!(size % ENTRY_INC)) {
  61. if (!(v = realloc(_penvp, rounded(size) * sizeof(char **))))
  62. return 1;
  63. _penvp = v;
  64. }
  65. v[size - 1] = name;
  66. v[size] = NULL;
  67. size++;
  68. environ = _penvp;
  69. return 0;
  70. }