|
|
1.1 root 1: TITLE stdenvp - OS/2 standard _setenvp routine
2: ;***
3: ;5stdenvp.asm - OS/2 standard _setenvp routine
4: ;
5: ; Copyright (c) 1985-1987, Microsoft Corporation. All rights reserved.
6: ;
7: ;Purpose:
8: ; This module is called by the C start-up routine to set up "environ".
9: ; It copies the environment strings into the heap/stack, preceded by a
10: ; null-terminated array of pointers to those strings.
11: ; The global symbol "_environ" is set to point to this array.
12: ;
13: ;*******************************************************************************
14:
15: include version.inc
16: .xlist
17: include cmacros.inc
18: include msdos.inc
19: .list
20:
21: sBegin data
22: assumes ds,data
23:
24: externDP environ ; environment pointer
25: externW _aenvseg ; Environment segment
26: externB _acfinfo ; C_FILE_INFO string
27:
28: staticCP retadr,0 ; return address
29:
30: sEnd data
31:
32:
33: sBegin code
34:
35: externNP _stdalloc ; routine to allocate heap/stack space
36: externNP _amsg_exit ; Routine for error messages.
37:
38: assumes ds,data
39: assumes cs,code
40:
41: page
42: ;***
43: ;_stdenvp - set up "envp" for C programs
44: ;
45: ;Purpose:
46: ; Reads the environment and build the envp array for C programs.
47: ;
48: ;Entry:
49: ; The environment strings occur at the beginning of the segment.
50: ; The list of environment strings is terminated by an extra null
51: ; byte. Thus two null bytes in a row indicate the end of the
52: ; last environment string and the end of the environment, resp.
53: ;
54: ;Exit:
55: ; "environ" points to a null-terminated list of pointers to ASCIZ
56: ; strings, each of which is of the form "VAR=VALUE". The strings
57: ; are copied from the environment segment into space allocated on
58: ; the heap/stack. The list of pointers is also located on there.
59: ;
60: ;Uses:
61: ; Locks the environment segment before use, and unlocks afterward
62: ; Allocates space on the heap/stack for the environment strings
63: ; and a list of pointers to them.
64: ;
65: ; All registers except DS, SS, and BP are modified
66: ; Note especially that SI and DI are NOT preserved!
67: ;
68: ;Exceptions:
69: ;
70: ;*******************************************************************************
71:
72: labelP <PUBLIC,_setenvp>
73:
74: pop word ptr [retadr] ; get return address (offset)
75:
76: if sizeC
77: pop word ptr [retadr+2] ; get return address (segment)
78: endif
79:
80: assumes ds,data
81:
82: mov es,_aenvseg ; point to environment segment
83: assumes es,nothing
84:
85: ; setup envp vector and move environment to heap/stack
86: ;
87: ; ES = environment segment, DS = SS = DGROUP
88:
89: xor ax,ax ; ax = 0 (search byte)
90: xor si,si ; si = 0 (envp count)
91: xor di,di ; di = 0 (initial offset)
92: mov cx,-1 ; cx = ffff (infinite count)
93:
94: ;*
95: ; Scan past the list of environment strings
96: ; Stop on a double null byte
97: ; SI will count the number of environment strings
98: ; DI will count the number of bytes the strings occupy
99: ;
100: cmp ax,ES:[di]
101: je noenv
102: scanenv:
103: repnz scasb
104: inc si ; si = envp count
105: scasb
106: jnz scanenv
107: ; di = count of string bytes
108: noenv:
109: inc si ; si = envp count + 1
110: mov ax,di ; ax = envlen
111: inc ax
112: and al,not 1 ; round up to even
113: mov di,si ; di = argument count
114: shl si,1 ; argument count*2
115: if sizeD
116: shl si,1 ; argument count*2
117: endif
118: ;
119: ; Need to allocate space for environment strings on the heap/stack
120: ; Number bytes needed = 2[4] * (Number of Strings + 1)
121: ; + Number of Bytes in Strings
122: ;
123: add ax,si ; ax = space to allocate
124: ;
125: ; _stdalloc allocates (AX) bytes from the heap or the stack
126: ;
127: call _stdalloc ; preserves bp, si, di
128: jnc env_ok
129:
130: mov ax,9 ;Memory error.
131: jmp _amsg_exit
132:
133: env_ok:
134: mov word ptr [environ],ax ; save envp[]
135:
136: if sizeD
137: mov word ptr [environ+2],ss ; segment address for large model
138: endif
139:
140: envnext:
141: mov cx,di ; cx = envcnt
142: mov di,ax
143: add di,si ; di = env strings area
144: mov bx,ax ; bx = env pointers area
145: ;
146: ; BX points to where envp[0], envp[1], ... will be stored
147: ; DI points to where *envp[0], *envp[1], ... will be stored
148: ;
149: push es
150: pop ds
151: xor si,si ; ds:si = environment table
152:
153: push ss
154: pop es ; es:di = env dest
155:
156: assumes es,data
157: assumes ds,nothing
158:
159: dec cx ; adjust for the last entry of 0000
160: jcxz envdone ; done - no environment
161:
162: ;
163: ; Copy each null-terminated environment string from DS:SI to ES:DI
164: ; Add the address of each string to the list at ES:BX
165: ; Skip the "_C_FILE_INFO" entry by not putting it in the pointer list
166: ;
167: envloop:
168: mov ax,[si]
169: cmp ax,word ptr [_acfinfo]
170: jne not_cfi ; don't save pointer if '_C'...
171: ;
172: may_be_cfi:
173: push cx
174: push si
175: push di ; preserve context
176:
177: mov di,dataOFFSET _acfinfo ; ES:DI points to C_FILE_INFO string
178: mov cx,6 ; length of that string in words
179: repe cmpsw ; cmpsw is faster than cmpsb
180:
181: pop di
182: pop si
183: pop cx ; restore context
184: je envstr ; if match, skip this pointer
185: ;
186: not_cfi:
187: mov es:[bx],di ; save pointer to start of string
188: if sizeD
189: mov es:[bx+2],ss ; segment address for large model
190: add bx,4
191: else
192: inc bx
193: inc bx
194: endif
195:
196: envstr:
197: lodsb
198: stosb
199: or al,al
200: jnz envstr ; keep copying string
201:
202: loop envloop ; more strings to copy
203:
204: ;
205: ; DS:SI points after the environment strings
206: ;
207: envdone:
208: mov es:[bx],cx ; zero terminate envp table
209: if sizeD
210: mov es:[bx+2],cx ; extra zero for large model
211: endif
212:
213: push ss
214: pop ds
215: push ss
216: pop es ; ES = DS = DGROUP
217:
218: assumes ds,data
219:
220: jmp [retadr]
221:
222: sEnd code
223:
224: end
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.