source: trunk/libs/newlib/src/newlib/libc/stdlib/setenv_r.c

Last change on this file was 444, checked in by satin@…, 6 years ago

add newlib,libalmos-mkh, restructure shared_syscalls.h and mini-libc

File size: 4.1 KB
Line 
1/* This file may have been modified by DJ Delorie (Jan 1991).  If so,
2** these modifications are Copyright (C) 1991 DJ Delorie.
3*/
4
5/*
6 * Copyright (c) 1987 Regents of the University of California.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms are permitted
10 * provided that: (1) source distributions retain this entire copyright
11 * notice and comment, and (2) distributions including binaries display
12 * the following acknowledgement:  ``This product includes software
13 * developed by the University of California, Berkeley and its contributors''
14 * in the documentation or other materials provided with the distribution
15 * and in all advertising materials mentioning features or use of this
16 * software. Neither the name of the University nor the names of its
17 * contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22 */
23
24#include <reent.h>
25
26#include <stddef.h>
27#include <stdlib.h>
28#include <string.h>
29#include <time.h>
30#include <errno.h>
31#include "envlock.h"
32
33extern char **environ;
34
35/* Only deal with a pointer to environ, to work around subtle bugs with shared
36   libraries and/or small data systems where the user declares his own
37   'environ'.  */
38static char ***p_environ = &environ;
39
40/* _findenv_r is defined in getenv_r.c.  */
41extern char *_findenv_r (struct _reent *, const char *, int *);
42
43/*
44 * _setenv_r --
45 *      Set the value of the environmental variable "name" to be
46 *      "value".  If rewrite is set, replace any current value.
47 *      If "name" contains equal sign, -1 is returned, and errno is
48 *      set to EINVAL;
49 */
50
51int
52_setenv_r (struct _reent *reent_ptr,
53        const char *name,
54        const char *value,
55        int rewrite)
56{
57  static int alloced;           /* if allocated space before */
58  register char *C;
59  int l_value, offset;
60
61  if (strchr(name, '='))
62    {
63      errno = EINVAL;
64      return -1;
65    }
66
67  ENV_LOCK;
68
69  l_value = strlen (value);
70  if ((C = _findenv_r (reent_ptr, name, &offset)))
71    {                           /* find if already exists */
72      if (!rewrite)
73        {
74          ENV_UNLOCK;
75          return 0;
76        }
77      if (strlen (C) >= l_value)
78        {                       /* old larger; copy over */
79          while ((*C++ = *value++) != 0);
80          ENV_UNLOCK;
81          return 0;
82        }
83    }
84  else
85    {                           /* create new slot */
86      register int cnt;
87      register char **P;
88
89      for (P = *p_environ, cnt = 0; *P; ++P, ++cnt);
90      if (alloced)
91        {                       /* just increase size */
92          *p_environ = (char **) _realloc_r (reent_ptr, (char *) environ,
93                                             (size_t) (sizeof (char *) * (cnt + 2)));
94          if (!*p_environ)
95            {
96              ENV_UNLOCK;
97              return -1;
98            }
99        }
100      else
101        {                       /* get new space */
102          alloced = 1;          /* copy old entries into it */
103          P = (char **) _malloc_r (reent_ptr, (size_t) (sizeof (char *) * (cnt + 2)));
104          if (!P)
105            {
106              ENV_UNLOCK;
107              return (-1);
108            }
109          memcpy((char *) P,(char *) *p_environ, cnt * sizeof (char *));
110          *p_environ = P;
111        }
112      (*p_environ)[cnt + 1] = NULL;
113      offset = cnt;
114    }
115  for (C = (char *) name; *C && *C != '='; ++C);        /* no `=' in name */
116  if (!((*p_environ)[offset] =  /* name + `=' + value */
117        _malloc_r (reent_ptr, (size_t) ((int) (C - name) + l_value + 2))))
118    {
119      ENV_UNLOCK;
120      return -1;
121    }
122  for (C = (*p_environ)[offset]; (*C = *name++) && *C != '='; ++C);
123  for (*C++ = '='; (*C++ = *value++) != 0;);
124
125  ENV_UNLOCK;
126
127  return 0;
128}
129
130/*
131 * _unsetenv_r(name) --
132 *      Delete environmental variable "name".
133 */
134int
135_unsetenv_r (struct _reent *reent_ptr,
136        const char *name)
137{
138  register char **P;
139  int offset;
140 
141  /* Name cannot be NULL, empty, or contain an equal sign.  */ 
142  if (name == NULL || name[0] == '\0' || strchr(name, '='))
143    {
144      errno = EINVAL;
145      return -1;
146    }
147
148  ENV_LOCK;
149
150  while (_findenv_r (reent_ptr, name, &offset)) /* if set multiple times */
151    { 
152      for (P = &(*p_environ)[offset];; ++P)
153        if (!(*P = *(P + 1)))
154          break;
155    }
156
157  ENV_UNLOCK;
158  return 0;
159}
Note: See TracBrowser for help on using the repository browser.