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