go-setenv.c 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. /* go-setenv.c -- set the C environment from Go.
  2. Copyright 2011 The Go Authors. All rights reserved.
  3. Use of this source code is governed by a BSD-style
  4. license that can be found in the LICENSE file. */
  5. #include "config.h"
  6. #include <stddef.h>
  7. #include <stdlib.h>
  8. #include "go-alloc.h"
  9. #include "runtime.h"
  10. #include "arch.h"
  11. #include "malloc.h"
  12. /* Set the C environment from Go. This is called by syscall.Setenv. */
  13. void setenv_c (String, String) __asm__ (GOSYM_PREFIX "syscall.setenv_c");
  14. void
  15. setenv_c (String k, String v)
  16. {
  17. const byte *ks;
  18. unsigned char *kn;
  19. const byte *vs;
  20. unsigned char *vn;
  21. intgo len;
  22. ks = k.str;
  23. if (ks == NULL)
  24. ks = (const byte *) "";
  25. kn = NULL;
  26. vs = v.str;
  27. if (vs == NULL)
  28. vs = (const byte *) "";
  29. vn = NULL;
  30. #ifdef HAVE_SETENV
  31. if (ks != NULL && ks[k.len] != 0)
  32. {
  33. // Objects that are explicitly freed must be at least 16 bytes in size,
  34. // so that they are not allocated using tiny alloc.
  35. len = k.len + 1;
  36. if (len < TinySize)
  37. len = TinySize;
  38. kn = __go_alloc (len);
  39. __builtin_memcpy (kn, ks, k.len);
  40. ks = kn;
  41. }
  42. if (vs != NULL && vs[v.len] != 0)
  43. {
  44. len = v.len + 1;
  45. if (len < TinySize)
  46. len = TinySize;
  47. vn = __go_alloc (len);
  48. __builtin_memcpy (vn, vs, v.len);
  49. vs = vn;
  50. }
  51. setenv ((const char *) ks, (const char *) vs, 1);
  52. #else /* !defined(HAVE_SETENV) */
  53. len = k.len + v.len + 2;
  54. if (len < TinySize)
  55. len = TinySize;
  56. kn = __go_alloc (len);
  57. __builtin_memcpy (kn, ks, k.len);
  58. kn[k.len] = '=';
  59. __builtin_memcpy (kn + k.len + 1, vs, v.len);
  60. kn[k.len + v.len + 1] = '\0';
  61. putenv ((char *) kn);
  62. #endif /* !defined(HAVE_SETENV) */
  63. if (kn != NULL)
  64. __go_free (kn);
  65. if (vn != NULL)
  66. __go_free (vn);
  67. }