summaryrefslogtreecommitdiffstats
path: root/private/crt32/startup/stdenvp.c
blob: 7ebdfa806436dea1f47bfd191c6f21af2a094c25 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
/***
*stdenvp.c - OS/2 standard _setenvp routine
*
*	Copyright (c) 1989-1992, Microsoft Corporation. All rights reserved.
*
*Purpose:
*	This module is called by the C start-up routine to set up "_environ".
*	Its sets up an array of pointers to strings in the environment.
*	The global symbol "_environ" is set to point to this array.
*
*Revision History:
*	11-07-84  GFW	initial version
*	01-08-86  SKS	Modified for OS/2
*	05-21-86  SKS	Call _stdalloc to get memory for strings
*	09-04-86  SKS	Added check to skip the "*C_FILE_INFO" string
*	10-21-86  SKS	Improved check for "*C_FILE_INFO"/"_C_FILE_INFO"
*	02-19-88  SKS	Handle case where environment starts with a single null
*	05-10-88  JCR	Modified code to accept far pointer from _stdalloc
*	06-01-88  PHG	Merged DLL and normal versions
*	07-12-88  JCR	Largely re-written: (1) split mem allocation into two
*			seperate malloc() calls to help simplify putenv(),
*			(2) stdalloc() no longer robs from stack, (3) cProc/cEnd
*			sequence, (4) misc cleanup
*	09-20-88  WAJ	Initial 386 version
*	12-13-88  JCR	Use rterr.inc parameters for runtime errors
*	04-09-90  GJF	Added #include <cruntime.h>. Made the calling type
*			_CALLTYPE1. Also, fixed the copyright and cleaned up
*			up the formatting a bit.
*	06-05-90  GJF	Changed error message interface.
*	10-08-90  GJF	New-style function declarator.
*	10-31-90  GJF	Fixed statement appending the final NULL (Stevewo
*			found the bug).
*       12-11-90  SRW   Changed to include <oscalls.h> and setup _environ
*			correctly for Win32
*	01-21-91  GJF	ANSI naming.
*       02-07-91  SRW   Change _WIN32_ specific code to allocate static copy (_WIN32_)
*       02-18-91  SRW   Change _WIN32_ specific code to allocate copy of
*			variable strings as well [_WIN32_]
*	07-25-91  GJF	Changed strupr to _strupr.
*	03-31-92  DJM	POSIX support.
*	04-20-92  GJF	Removed conversion to upper-case code for Win32.
*
*******************************************************************************/

#include <cruntime.h>
#include <string.h>
#include <stdlib.h>
#include <internal.h>
#include <rterr.h>
#include <oscalls.h>

/* C file info string */
extern char _cfinfo[];

/***
*_setenvp - set up "envp" for C programs
*
*Purpose:
*	Reads the environment and build the envp array for C programs.
*
*Entry:
*	The environment strings occur at _aenvptr.
*	The list of environment strings is terminated by an extra null
*	byte.  Thus two null bytes in a row indicate the end of the
*	last environment string and the end of the environment, resp.
*
*Exit:
*	"environ" points to a null-terminated list of pointers to ASCIZ
*	strings, each of which is of the form "VAR=VALUE".  The strings
*	are not copied from the environment area.  Instead, the array of
*	pointers will point into the OS environment area.  This array of
*	pointers will be malloc'ed
*
*Uses:
*	Allocates space on the heap for the environment pointers.
*
*Exceptions:
*	If space cannot be allocated, program is terminated.
*
*******************************************************************************/

void _CALLTYPE1 _setenvp (
	void
	)
{
	char *p;
	char **env;		    /* _environ ptr traversal pointer */
	int numstrings; 	    /* number of environment strings */

#ifdef	_CRUISER_

	numstrings = 0;
	p = _aenvptr;

	/* NOTE: starting with single null indicates no environ */
	/* count the number of strings */
	while (*p != '\0') {
		p += strlen(p) + 1;
		++numstrings;
	}

	/* need pointer for each string, plus one null ptr at end */
	_environ = env = malloc((numstrings+1) * sizeof(char *));
	if (_environ == NULL)
		_amsg_exit(_RT_SPACEENV);

	p = _aenvptr;
	/* copy pointers to strings into env - don't copy _C_FILEINFO string */
	while (*p != '\0') {

		if (strncmp(p, _acfinfo, CFI_LENGTH) != 0)
			*env++ = p;
		p += strlen(p) + 1;
	}

	/* and a final NULL pointer */
	*env = NULL;

#else	/* ndef _CRUISER_ */

#ifdef	_WIN32_
        int cb;

	numstrings = 0;
	p = _aenvptr;

	/* NOTE: starting with single null indicates no environ */
	/* count the number of strings */
	while (*p != '\0') {
		p += strlen(p) + 1;
		++numstrings;
	}

	/* need pointer for each string, plus one null ptr at end */
	if ( (_environ = env = malloc((numstrings+1) * sizeof(char *)))
	    == NULL )
		_amsg_exit(_RT_SPACEENV);

	/* copy strings to malloc'd memory and save pointers in _environ */
	for ( p = _aenvptr ; *p != '\0' ; env++, p += cb ) {
                cb = strlen(p) + 1;
		if ( (*env = malloc(cb)) == NULL )
			_amsg_exit(_RT_SPACEENV);
		strcpy(*env, p);
	}

	/* and a final NULL pointer */
	*env = NULL;

#else	/* ndef _WIN32_ */

#ifdef	_POSIX_

#if 0   /* it would seem that this code is unnecessary for POSIX */
	/* since it is never called! */

	numstrings = 0;
	p = _aenvptr;

	/* NOTE: starting with single null indicates no environ */
	/* count the number of strings */
	while (*p != '\0') {
	 p += strlen(p) + 1;
	 ++numstrings;
	}

	/* need pointer for each string, plus one null ptr at end */
	_environ = env = malloc((numstrings+1) * sizeof(char *));

	p = _aenvptr;
	while (*p != '\0') {
		*env = p++;
		while (*p++ != '\0')
		    ;
		env++;
	}

	/* and a final NULL pointer */
	*env = NULL;

#endif /* 0 */

#else

#error ERROR - ONLY CRUISER, POSIX, OR WIN32 TARGET SUPPORTED!

#endif /* _POSIX_ */

#endif	/* _WIN32_ */

#endif	/* _CRUISER_ */
}