cdc05dd7e737c931874fc1fdc647618b6111792b
[bpt/guile.git] / libguile / putenv.c
1 /* Copyright (C) 1991, 2000, 2001, 2004, 2005, 2006 Free Software Foundation, Inc.
2
3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public License
5 * as published by the Free Software Foundation; either version 3 of
6 * the License, or (at your option) any later version.
7 *
8 * This library is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16 * 02110-1301 USA
17 */
18
19
20 #ifdef HAVE_CONFIG_H
21 # include <config.h>
22 #endif
23
24 #include "libguile/scmconfig.h"
25
26 #include <sys/types.h>
27 #include <errno.h>
28
29 /* Don't include stdlib.h for non-GNU C libraries because some of them
30 contain conflicting prototypes for getopt.
31 This needs to come after some library #include
32 to get __GNU_LIBRARY__ defined. */
33 #ifdef __GNU_LIBRARY__
34 #include <stdlib.h>
35 #else
36 char *malloc ();
37 #endif /* GNU C library. */
38
39 #if defined(STDC_HEADERS) || defined(HAVE_STRING_H)
40 #include <string.h>
41 #else
42 #include <strings.h>
43 #ifndef strchr
44 #define strchr index
45 #endif
46 #ifndef memcpy
47 #define memcpy(d, s, n) bcopy((s), (d), (n))
48 #endif
49 #endif
50
51 #ifdef HAVE_UNISTD_H
52 #include <unistd.h>
53 #endif
54
55 #if HAVE_CRT_EXTERNS_H
56 #include <crt_externs.h> /* for Darwin _NSGetEnviron */
57 #endif
58
59 #ifndef NULL
60 #define NULL 0
61 #endif
62
63 extern char **environ;
64
65 /* On Apple Darwin in a shared library there's no "environ" to access
66 directly, instead the address of that variable must be obtained with
67 _NSGetEnviron(). */
68 #if HAVE__NSGETENVIRON && defined (PIC)
69 #define environ (*_NSGetEnviron())
70 #endif
71
72 /* Put STRING, which is of the form "NAME=VALUE", in the environment. */
73 int
74 putenv (const char *string)
75 {
76 char *name_end = strchr (string, '=');
77 register size_t size;
78 register char **ep;
79
80 if (name_end == NULL)
81 {
82 /* Remove the variable from the environment. */
83 size = strlen (string);
84 for (ep = environ; *ep != NULL; ++ep)
85 if (!strncmp (*ep, string, size) && (*ep)[size] == '=')
86 {
87 while (ep[1] != NULL)
88 {
89 ep[0] = ep[1];
90 ++ep;
91 }
92 *ep = NULL;
93 return 0;
94 }
95 }
96
97 size = 0;
98 for (ep = environ; *ep != NULL; ++ep)
99 if (!strncmp (*ep, string, name_end - string) &&
100 (*ep)[name_end - string] == '=')
101 break;
102 else
103 ++size;
104
105 if (*ep == NULL)
106 {
107 static char **last_environ = NULL;
108 char **new_environ = (char **) scm_malloc ((size + 2) * sizeof (char *));
109 memcpy ((char *) new_environ, (char *) environ, size * sizeof (char *));
110 new_environ[size] = (char *) string;
111 new_environ[size + 1] = NULL;
112 if (last_environ != NULL)
113 free ((char *) last_environ);
114 last_environ = new_environ;
115 environ = new_environ;
116 }
117 else
118 *ep = (char *) string;
119
120 return 0;
121 }
122
123 /*
124 Local Variables:
125 c-file-style: "gnu"
126 End:
127 */