| 1 | /****************************************************************/ |
| 2 | /* */ |
| 3 | /* putenv(3) */ |
| 4 | /* */ |
| 5 | /* Change or add an environment entry */ |
| 6 | /* */ |
| 7 | /****************************************************************/ |
| 8 | /* origination 1987-Oct-7 T. Holm */ |
| 9 | /****************************************************************/ |
| 10 | |
| 11 | /* |
| 12 | Path: hoptoad!pacbell!ames!ll-xn!mit-eddie!uw-beaver!ssc-vax!uvicctr!tholm |
| 13 | From: tholm@uvicctr.UUCP (Terrence W. Holm) |
| 14 | Newsgroups: comp.os.minix |
| 15 | Subject: putenv(3) |
| 16 | Message-ID: <395@uvicctr.UUCP> |
| 17 | Date: 5 May 88 06:40:52 GMT |
| 18 | Organization: University of Victoria, Victoria B.C. Canada |
| 19 | |
| 20 | EFTH Minix report #2 - May 1988 - putenv(3) |
| 21 | |
| 22 | This is an implementation of putenv(3) that we |
| 23 | wrote for Minix. Please consider this a public |
| 24 | domain program. |
| 25 | */ |
| 26 | |
| 27 | #include <stdio.h> |
| 28 | |
| 29 | #define PSIZE sizeof(char *) |
| 30 | |
| 31 | extern char **environ; |
| 32 | |
| 33 | char *strchr(); |
| 34 | char *malloc(); |
| 35 | |
| 36 | /****************************************************************/ |
| 37 | /* */ |
| 38 | /* int */ |
| 39 | /* putenv( entry ) */ |
| 40 | /* */ |
| 41 | /* The "entry" should follow the form */ |
| 42 | /* "NAME=VALUE". This routine will search the */ |
| 43 | /* user environment for "NAME" and replace its */ |
| 44 | /* value with "VALUE". */ |
| 45 | /* */ |
| 46 | /* Note that "entry" is not copied, it is used */ |
| 47 | /* as the environment entry. This means that it */ |
| 48 | /* must not be unallocated or otherwise modifed */ |
| 49 | /* by the caller, unless it is replaced by a */ |
| 50 | /* subsequent putenv(). */ |
| 51 | /* */ |
| 52 | /* If the name is not found in the environment, */ |
| 53 | /* then a new vector of pointers is allocated, */ |
| 54 | /* "entry" is put at the end and the global */ |
| 55 | /* variable "environ" is updated. */ |
| 56 | /* */ |
| 57 | /* This function normally returns NULL, but -1 */ |
| 58 | /* is returned if it can not allocate enough */ |
| 59 | /* space using malloc(3), or "entry" does not */ |
| 60 | /* contain a '='. */ |
| 61 | /* */ |
| 62 | /****************************************************************/ |
| 63 | |
| 64 | |
| 65 | int |
| 66 | putenv( entry ) |
| 67 | char *entry; |
| 68 | { |
| 69 | unsigned length; |
| 70 | unsigned size; |
| 71 | char *temp; |
| 72 | char **p; |
| 73 | char **new_environ; |
| 74 | |
| 75 | /* Find the length of the "NAME=" */ |
| 76 | |
| 77 | temp = strchr(entry,'='); |
| 78 | if ( temp == 0 ) |
| 79 | return( -1 ); |
| 80 | |
| 81 | length = (unsigned) (temp - entry + 1); |
| 82 | |
| 83 | |
| 84 | /* Scan through the environment looking for "NAME=" */ |
| 85 | |
| 86 | for ( p=environ; *p != 0 ; p++ ) |
| 87 | if ( strncmp( entry, *p, length ) == 0 ) |
| 88 | { |
| 89 | *p = entry; |
| 90 | return( 0 ); |
| 91 | } |
| 92 | |
| 93 | |
| 94 | /* The name was not found, build a bigger environment */ |
| 95 | |
| 96 | size = p - environ; |
| 97 | |
| 98 | new_environ = (char **) malloc( (size+2)*PSIZE ); |
| 99 | |
| 100 | if ( new_environ == (char **) NULL ) |
| 101 | return( -1 ); |
| 102 | |
| 103 | memcpy ((char *) new_environ, (char *) environ, size*PSIZE ); |
| 104 | |
| 105 | new_environ[size] = entry; |
| 106 | new_environ[size+1] = NULL; |
| 107 | |
| 108 | environ = new_environ; |
| 109 | |
| 110 | return(0); |
| 111 | } |