/ stdlib / FreeBSD / putenv.c
putenv.c
  1  /*-
  2   * Copyright (c) 1988, 1993
  3   *	The Regents of the University of California.  All rights reserved.
  4   *
  5   * Redistribution and use in source and binary forms, with or without
  6   * modification, are permitted provided that the following conditions
  7   * are met:
  8   * 1. Redistributions of source code must retain the above copyright
  9   *    notice, this list of conditions and the following disclaimer.
 10   * 2. Redistributions in binary form must reproduce the above copyright
 11   *    notice, this list of conditions and the following disclaimer in the
 12   *    documentation and/or other materials provided with the distribution.
 13   * 4. Neither the name of the University nor the names of its contributors
 14   *    may be used to endorse or promote products derived from this software
 15   *    without specific prior written permission.
 16   *
 17   * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 18   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 19   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 20   * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 21   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 22   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 23   * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 24   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 25   * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 26   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 27   * SUCH DAMAGE.
 28   */
 29  
 30  #if defined(LIBC_SCCS) && !defined(lint)
 31  static char sccsid[] = "@(#)putenv.c	8.2 (Berkeley) 3/27/94";
 32  #endif /* LIBC_SCCS and not lint */
 33  #include <sys/cdefs.h>
 34  __FBSDID("$FreeBSD: src/lib/libc/stdlib/putenv.c,v 1.6 2007/05/01 16:02:41 ache Exp $");
 35  
 36  #include <stdlib.h>
 37  #include <string.h>
 38  #include <sys/types.h>
 39  #include <db.h>
 40  #include <crt_externs.h>
 41  #include <errno.h> 
 42  
 43  extern struct owned_ptr *__env_owned;
 44  
 45  #ifdef LEGACY_CRT1_ENVIRON
 46  extern char **_saved_environ;
 47  #endif /* LEGACY_CRT1_ENVIRON */
 48  
 49  __private_extern__ int __init__env_owned_locked(int);
 50  __private_extern__ int __setenv_locked(const char *, const char *, int, int, char ***, struct owned_ptr *);
 51  __private_extern__ void __environ_lock(void);
 52  __private_extern__ void __environ_unlock(void);
 53  
 54  #ifndef BUILDING_VARIANT
 55  /*
 56   * _putenvp -- SPI using an arbitrary pointer to string array (the array must
 57   * have been created with malloc) and an env state, created by _allocenvstate().
 58   *	Returns ptr to value associated with name, if any, else NULL.
 59   */
 60  int
 61  _putenvp(char *str, char ***envp, void *state)
 62  {
 63  	__environ_lock();
 64  	if (__init__env_owned_locked(1)) {
 65  		__environ_unlock();
 66  		return (-1);
 67  	}
 68  	int ret = __setenv_locked(str, NULL, 1, 0, envp,
 69  			(state ? (struct owned_ptr *)state : __env_owned));
 70  	__environ_unlock();
 71  	return ret;
 72  }
 73  #endif /* BUILDING_VARIANT */
 74  
 75  int
 76  putenv(str)
 77  	char *str;
 78  {
 79  	int ret;
 80  	int copy;
 81  
 82  #if __DARWIN_UNIX03
 83  	if (str == NULL || *str == 0 || index(str, '=') == NULL) {
 84  		errno = EINVAL;
 85  		return (-1);
 86  	}
 87  #else /* !__DARWIN_UNIX03 */
 88  	if (index(str, '=') == NULL)
 89  		return (-1);
 90  #endif /* __DARWIN_UNIX03 */
 91  
 92  #if __DARWIN_UNIX03
 93  	copy = 0;
 94  #else /* !__DARWIN_UNIX03 */
 95  	copy = -1;
 96  #endif /* __DARWIN_UNIX03 */
 97  
 98  	__environ_lock();
 99  	if (__init__env_owned_locked(1)) {
100  		__environ_unlock();
101  		return (-1);
102  	}
103  	ret = __setenv_locked(str, NULL, 1, copy, _NSGetEnviron(), __env_owned);
104  #ifdef LEGACY_CRT1_ENVIRON
105  	_saved_environ = *_NSGetEnviron();
106  #endif /* LEGACY_CRT1_ENVIRON */
107  	__environ_unlock();
108  	return ret;
109  }