xref: /freebsd/stand/ficl/loader.c (revision 8ec8413faa3573c579d9e6361de904f8251b0c0e)
1ca987d46SWarner Losh /*-
2ca987d46SWarner Losh  * Copyright (c) 2000 Daniel Capo Sobral
3ca987d46SWarner Losh  * All rights reserved.
4ca987d46SWarner Losh  *
5ca987d46SWarner Losh  * Redistribution and use in source and binary forms, with or without
6ca987d46SWarner Losh  * modification, are permitted provided that the following conditions
7ca987d46SWarner Losh  * are met:
8ca987d46SWarner Losh  * 1. Redistributions of source code must retain the above copyright
9ca987d46SWarner Losh  *    notice, this list of conditions and the following disclaimer.
10ca987d46SWarner Losh  * 2. Redistributions in binary form must reproduce the above copyright
11ca987d46SWarner Losh  *    notice, this list of conditions and the following disclaimer in the
12ca987d46SWarner Losh  *    documentation and/or other materials provided with the distribution.
13ca987d46SWarner Losh  *
14ca987d46SWarner Losh  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15ca987d46SWarner Losh  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16ca987d46SWarner Losh  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17ca987d46SWarner Losh  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18ca987d46SWarner Losh  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19ca987d46SWarner Losh  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20ca987d46SWarner Losh  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21ca987d46SWarner Losh  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22ca987d46SWarner Losh  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23ca987d46SWarner Losh  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24ca987d46SWarner Losh  * SUCH DAMAGE.
25ca987d46SWarner Losh  */
26ca987d46SWarner Losh 
27ca987d46SWarner Losh /*******************************************************************
28ca987d46SWarner Losh ** l o a d e r . c
29ca987d46SWarner Losh ** Additional FICL words designed for FreeBSD's loader
30ca987d46SWarner Losh **
31ca987d46SWarner Losh *******************************************************************/
32ca987d46SWarner Losh 
33ca987d46SWarner Losh #ifdef TESTMAIN
34ca987d46SWarner Losh #include <sys/types.h>
35ca987d46SWarner Losh #include <sys/stat.h>
36ca987d46SWarner Losh #include <dirent.h>
37ca987d46SWarner Losh #include <fcntl.h>
38ca987d46SWarner Losh #include <stdio.h>
39ca987d46SWarner Losh #include <stdlib.h>
40ca987d46SWarner Losh #include <unistd.h>
41ca987d46SWarner Losh #else
42ca987d46SWarner Losh #include <stand.h>
43ca987d46SWarner Losh #endif
44ca987d46SWarner Losh #include "bootstrap.h"
45ca987d46SWarner Losh #include <string.h>
46ca987d46SWarner Losh #include <uuid.h>
47ca987d46SWarner Losh #include "ficl.h"
48ca987d46SWarner Losh 
49ca987d46SWarner Losh /*		FreeBSD's loader interaction words and extras
50ca987d46SWarner Losh  *
51ca987d46SWarner Losh  * 		setenv      ( value n name n' -- )
52ca987d46SWarner Losh  * 		setenv?     ( value n name n' flag -- )
53ca987d46SWarner Losh  * 		getenv      ( addr n -- addr' n' | -1 )
54ca987d46SWarner Losh  * 		unsetenv    ( addr n -- )
55ca987d46SWarner Losh  * 		copyin      ( addr addr' len -- )
56ca987d46SWarner Losh  * 		copyout     ( addr addr' len -- )
57ca987d46SWarner Losh  * 		findfile    ( name len type len' -- addr )
58ca987d46SWarner Losh  * 		pnpdevices  ( -- addr )
59ca987d46SWarner Losh  * 		pnphandlers ( -- addr )
60ca987d46SWarner Losh  * 		ccall       ( [[...[p10] p9] ... p1] n addr -- result )
61ca987d46SWarner Losh  *		uuid-from-string ( addr n -- addr' )
62ca987d46SWarner Losh  *		uuid-to-string ( addr' -- addr n )
63ca987d46SWarner Losh  * 		.#	    ( value -- )
64ca987d46SWarner Losh  */
65ca987d46SWarner Losh 
66ca987d46SWarner Losh void
ficlSetenv(FICL_VM * pVM)67ca987d46SWarner Losh ficlSetenv(FICL_VM *pVM)
68ca987d46SWarner Losh {
69ca987d46SWarner Losh #ifndef TESTMAIN
70ca987d46SWarner Losh 	char	*name, *value;
71ca987d46SWarner Losh #endif
72ca987d46SWarner Losh 	char	*namep, *valuep;
73ca987d46SWarner Losh 	int	names, values;
74ca987d46SWarner Losh 
75ca987d46SWarner Losh #if FICL_ROBUST > 1
76ca987d46SWarner Losh 	vmCheckStack(pVM, 4, 0);
77ca987d46SWarner Losh #endif
78ca987d46SWarner Losh 	names = stackPopINT(pVM->pStack);
79ca987d46SWarner Losh 	namep = (char*) stackPopPtr(pVM->pStack);
80ca987d46SWarner Losh 	values = stackPopINT(pVM->pStack);
81ca987d46SWarner Losh 	valuep = (char*) stackPopPtr(pVM->pStack);
82ca987d46SWarner Losh 
83ca987d46SWarner Losh #ifndef TESTMAIN
84ca987d46SWarner Losh 	name = (char*) ficlMalloc(names+1);
85ca987d46SWarner Losh 	if (!name)
86ca987d46SWarner Losh 		vmThrowErr(pVM, "Error: out of memory");
87ca987d46SWarner Losh 	strncpy(name, namep, names);
88ca987d46SWarner Losh 	name[names] = '\0';
89ca987d46SWarner Losh 	value = (char*) ficlMalloc(values+1);
90ca987d46SWarner Losh 	if (!value)
91ca987d46SWarner Losh 		vmThrowErr(pVM, "Error: out of memory");
92ca987d46SWarner Losh 	strncpy(value, valuep, values);
93ca987d46SWarner Losh 	value[values] = '\0';
94ca987d46SWarner Losh 
95ca987d46SWarner Losh 	setenv(name, value, 1);
96ca987d46SWarner Losh 	ficlFree(name);
97ca987d46SWarner Losh 	ficlFree(value);
98ca987d46SWarner Losh #endif
99ca987d46SWarner Losh 
100ca987d46SWarner Losh 	return;
101ca987d46SWarner Losh }
102ca987d46SWarner Losh 
103ca987d46SWarner Losh void
ficlSetenvq(FICL_VM * pVM)104ca987d46SWarner Losh ficlSetenvq(FICL_VM *pVM)
105ca987d46SWarner Losh {
106ca987d46SWarner Losh #ifndef TESTMAIN
107ca987d46SWarner Losh 	char	*name, *value;
108ca987d46SWarner Losh #endif
109ca987d46SWarner Losh 	char	*namep, *valuep;
110ca987d46SWarner Losh 	int	names, values, overwrite;
111ca987d46SWarner Losh 
112ca987d46SWarner Losh #if FICL_ROBUST > 1
113ca987d46SWarner Losh 	vmCheckStack(pVM, 5, 0);
114ca987d46SWarner Losh #endif
115ca987d46SWarner Losh 	overwrite = stackPopINT(pVM->pStack);
116ca987d46SWarner Losh 	names = stackPopINT(pVM->pStack);
117ca987d46SWarner Losh 	namep = (char*) stackPopPtr(pVM->pStack);
118ca987d46SWarner Losh 	values = stackPopINT(pVM->pStack);
119ca987d46SWarner Losh 	valuep = (char*) stackPopPtr(pVM->pStack);
120ca987d46SWarner Losh 
121ca987d46SWarner Losh #ifndef TESTMAIN
122ca987d46SWarner Losh 	name = (char*) ficlMalloc(names+1);
123ca987d46SWarner Losh 	if (!name)
124ca987d46SWarner Losh 		vmThrowErr(pVM, "Error: out of memory");
125ca987d46SWarner Losh 	strncpy(name, namep, names);
126ca987d46SWarner Losh 	name[names] = '\0';
127ca987d46SWarner Losh 	value = (char*) ficlMalloc(values+1);
128ca987d46SWarner Losh 	if (!value)
129ca987d46SWarner Losh 		vmThrowErr(pVM, "Error: out of memory");
130ca987d46SWarner Losh 	strncpy(value, valuep, values);
131ca987d46SWarner Losh 	value[values] = '\0';
132ca987d46SWarner Losh 
133ca987d46SWarner Losh 	setenv(name, value, overwrite);
134ca987d46SWarner Losh 	ficlFree(name);
135ca987d46SWarner Losh 	ficlFree(value);
136ca987d46SWarner Losh #endif
137ca987d46SWarner Losh 
138ca987d46SWarner Losh 	return;
139ca987d46SWarner Losh }
140ca987d46SWarner Losh 
141ca987d46SWarner Losh void
ficlGetenv(FICL_VM * pVM)142ca987d46SWarner Losh ficlGetenv(FICL_VM *pVM)
143ca987d46SWarner Losh {
144ca987d46SWarner Losh #ifndef TESTMAIN
145ca987d46SWarner Losh 	char	*name, *value;
146ca987d46SWarner Losh #endif
147ca987d46SWarner Losh 	char	*namep;
148ca987d46SWarner Losh 	int	names;
149ca987d46SWarner Losh 
150ca987d46SWarner Losh #if FICL_ROBUST > 1
151ca987d46SWarner Losh 	vmCheckStack(pVM, 2, 2);
152ca987d46SWarner Losh #endif
153ca987d46SWarner Losh 	names = stackPopINT(pVM->pStack);
154ca987d46SWarner Losh 	namep = (char*) stackPopPtr(pVM->pStack);
155ca987d46SWarner Losh 
156ca987d46SWarner Losh #ifndef TESTMAIN
157ca987d46SWarner Losh 	name = (char*) ficlMalloc(names+1);
158ca987d46SWarner Losh 	if (!name)
159ca987d46SWarner Losh 		vmThrowErr(pVM, "Error: out of memory");
160ca987d46SWarner Losh 	strncpy(name, namep, names);
161ca987d46SWarner Losh 	name[names] = '\0';
162ca987d46SWarner Losh 
163ca987d46SWarner Losh 	value = getenv(name);
164ca987d46SWarner Losh 	ficlFree(name);
165ca987d46SWarner Losh 
166ca987d46SWarner Losh 	if(value != NULL) {
167ca987d46SWarner Losh 		stackPushPtr(pVM->pStack, value);
168ca987d46SWarner Losh 		stackPushINT(pVM->pStack, strlen(value));
169ca987d46SWarner Losh 	} else
170ca987d46SWarner Losh #endif
171ca987d46SWarner Losh 		stackPushINT(pVM->pStack, -1);
172ca987d46SWarner Losh 
173ca987d46SWarner Losh 	return;
174ca987d46SWarner Losh }
175ca987d46SWarner Losh 
176ca987d46SWarner Losh void
ficlUnsetenv(FICL_VM * pVM)177ca987d46SWarner Losh ficlUnsetenv(FICL_VM *pVM)
178ca987d46SWarner Losh {
179ca987d46SWarner Losh #ifndef TESTMAIN
180ca987d46SWarner Losh 	char	*name;
181ca987d46SWarner Losh #endif
182ca987d46SWarner Losh 	char	*namep;
183ca987d46SWarner Losh 	int	names;
184ca987d46SWarner Losh 
185ca987d46SWarner Losh #if FICL_ROBUST > 1
186ca987d46SWarner Losh 	vmCheckStack(pVM, 2, 0);
187ca987d46SWarner Losh #endif
188ca987d46SWarner Losh 	names = stackPopINT(pVM->pStack);
189ca987d46SWarner Losh 	namep = (char*) stackPopPtr(pVM->pStack);
190ca987d46SWarner Losh 
191ca987d46SWarner Losh #ifndef TESTMAIN
192ca987d46SWarner Losh 	name = (char*) ficlMalloc(names+1);
193ca987d46SWarner Losh 	if (!name)
194ca987d46SWarner Losh 		vmThrowErr(pVM, "Error: out of memory");
195ca987d46SWarner Losh 	strncpy(name, namep, names);
196ca987d46SWarner Losh 	name[names] = '\0';
197ca987d46SWarner Losh 
198ca987d46SWarner Losh 	unsetenv(name);
199ca987d46SWarner Losh 	ficlFree(name);
200ca987d46SWarner Losh #endif
201ca987d46SWarner Losh 
202ca987d46SWarner Losh 	return;
203ca987d46SWarner Losh }
204ca987d46SWarner Losh 
205ca987d46SWarner Losh void
ficlCopyin(FICL_VM * pVM)206ca987d46SWarner Losh ficlCopyin(FICL_VM *pVM)
207ca987d46SWarner Losh {
208ca987d46SWarner Losh 	void*		src;
209ca987d46SWarner Losh 	vm_offset_t	dest;
210ca987d46SWarner Losh 	size_t		len;
211ca987d46SWarner Losh 
212ca987d46SWarner Losh #if FICL_ROBUST > 1
213ca987d46SWarner Losh 	vmCheckStack(pVM, 3, 0);
214ca987d46SWarner Losh #endif
215ca987d46SWarner Losh 
216ca987d46SWarner Losh 	len = stackPopINT(pVM->pStack);
217ca987d46SWarner Losh 	dest = stackPopINT(pVM->pStack);
218ca987d46SWarner Losh 	src = stackPopPtr(pVM->pStack);
219ca987d46SWarner Losh 
220ca987d46SWarner Losh #ifndef TESTMAIN
221ca987d46SWarner Losh 	archsw.arch_copyin(src, dest, len);
222ca987d46SWarner Losh #endif
223ca987d46SWarner Losh 
224ca987d46SWarner Losh 	return;
225ca987d46SWarner Losh }
226ca987d46SWarner Losh 
227ca987d46SWarner Losh void
ficlCopyout(FICL_VM * pVM)228ca987d46SWarner Losh ficlCopyout(FICL_VM *pVM)
229ca987d46SWarner Losh {
230ca987d46SWarner Losh 	void*		dest;
231ca987d46SWarner Losh 	vm_offset_t	src;
232ca987d46SWarner Losh 	size_t		len;
233ca987d46SWarner Losh 
234ca987d46SWarner Losh #if FICL_ROBUST > 1
235ca987d46SWarner Losh 	vmCheckStack(pVM, 3, 0);
236ca987d46SWarner Losh #endif
237ca987d46SWarner Losh 
238ca987d46SWarner Losh 	len = stackPopINT(pVM->pStack);
239ca987d46SWarner Losh 	dest = stackPopPtr(pVM->pStack);
240ca987d46SWarner Losh 	src = stackPopINT(pVM->pStack);
241ca987d46SWarner Losh 
242ca987d46SWarner Losh #ifndef TESTMAIN
243ca987d46SWarner Losh 	archsw.arch_copyout(src, dest, len);
244ca987d46SWarner Losh #endif
245ca987d46SWarner Losh 
246ca987d46SWarner Losh 	return;
247ca987d46SWarner Losh }
248ca987d46SWarner Losh 
249ca987d46SWarner Losh void
ficlFindfile(FICL_VM * pVM)250ca987d46SWarner Losh ficlFindfile(FICL_VM *pVM)
251ca987d46SWarner Losh {
252ca987d46SWarner Losh #ifndef TESTMAIN
253ca987d46SWarner Losh 	char	*name, *type;
254ca987d46SWarner Losh #endif
255ca987d46SWarner Losh 	char	*namep, *typep;
256ca987d46SWarner Losh 	struct	preloaded_file* fp;
257ca987d46SWarner Losh 	int	names, types;
258ca987d46SWarner Losh 
259ca987d46SWarner Losh #if FICL_ROBUST > 1
260ca987d46SWarner Losh 	vmCheckStack(pVM, 4, 1);
261ca987d46SWarner Losh #endif
262ca987d46SWarner Losh 
263ca987d46SWarner Losh 	types = stackPopINT(pVM->pStack);
264ca987d46SWarner Losh 	typep = (char*) stackPopPtr(pVM->pStack);
265ca987d46SWarner Losh 	names = stackPopINT(pVM->pStack);
266ca987d46SWarner Losh 	namep = (char*) stackPopPtr(pVM->pStack);
267ca987d46SWarner Losh #ifndef TESTMAIN
268ca987d46SWarner Losh 	name = (char*) ficlMalloc(names+1);
269ca987d46SWarner Losh 	if (!name)
270ca987d46SWarner Losh 		vmThrowErr(pVM, "Error: out of memory");
271ca987d46SWarner Losh 	strncpy(name, namep, names);
272ca987d46SWarner Losh 	name[names] = '\0';
273ca987d46SWarner Losh 	type = (char*) ficlMalloc(types+1);
274ca987d46SWarner Losh 	if (!type)
275ca987d46SWarner Losh 		vmThrowErr(pVM, "Error: out of memory");
276ca987d46SWarner Losh 	strncpy(type, typep, types);
277ca987d46SWarner Losh 	type[types] = '\0';
278ca987d46SWarner Losh 
279ca987d46SWarner Losh 	fp = file_findfile(name, type);
280ca987d46SWarner Losh #else
281ca987d46SWarner Losh 	fp = NULL;
282ca987d46SWarner Losh #endif
283ca987d46SWarner Losh 	stackPushPtr(pVM->pStack, fp);
284ca987d46SWarner Losh 
285ca987d46SWarner Losh 	return;
286ca987d46SWarner Losh }
287ca987d46SWarner Losh 
288e9b148a3SSimon J. Gerraty #ifndef TESTMAIN
289e9b148a3SSimon J. Gerraty 
290e9b148a3SSimon J. Gerraty /*	isvirtualized? - Return whether the loader runs under a
291e9b148a3SSimon J. Gerraty  *			hypervisor.
292e9b148a3SSimon J. Gerraty  *
293e9b148a3SSimon J. Gerraty  * isvirtualized? ( -- flag )
294e9b148a3SSimon J. Gerraty  */
295e9b148a3SSimon J. Gerraty static void
ficlIsvirtualizedQ(FICL_VM * pVM)296e9b148a3SSimon J. Gerraty ficlIsvirtualizedQ(FICL_VM *pVM)
297e9b148a3SSimon J. Gerraty {
298e9b148a3SSimon J. Gerraty 	FICL_INT flag;
299e9b148a3SSimon J. Gerraty 	const char *hv;
300e9b148a3SSimon J. Gerraty 
301e9b148a3SSimon J. Gerraty #if FICL_ROBUST > 1
302e9b148a3SSimon J. Gerraty 	vmCheckStack(pVM, 0, 1);
303e9b148a3SSimon J. Gerraty #endif
304e9b148a3SSimon J. Gerraty 
305e9b148a3SSimon J. Gerraty 	hv = (archsw.arch_hypervisor != NULL)
306e9b148a3SSimon J. Gerraty 	    ? (*archsw.arch_hypervisor)()
307e9b148a3SSimon J. Gerraty 	    : NULL;
308e9b148a3SSimon J. Gerraty 	flag = (hv != NULL) ? FICL_TRUE : FICL_FALSE;
309e9b148a3SSimon J. Gerraty 	stackPushINT(pVM->pStack, flag);
310e9b148a3SSimon J. Gerraty }
311e9b148a3SSimon J. Gerraty 
312e9b148a3SSimon J. Gerraty #endif /* ndef TESTMAIN */
313e9b148a3SSimon J. Gerraty 
314ca987d46SWarner Losh void
ficlCcall(FICL_VM * pVM)315ca987d46SWarner Losh ficlCcall(FICL_VM *pVM)
316ca987d46SWarner Losh {
317ca987d46SWarner Losh 	int (*func)(int, ...);
318ca987d46SWarner Losh 	int result, p[10];
319ca987d46SWarner Losh 	int nparam, i;
320ca987d46SWarner Losh 
321ca987d46SWarner Losh #if FICL_ROBUST > 1
322ca987d46SWarner Losh 	vmCheckStack(pVM, 2, 0);
323ca987d46SWarner Losh #endif
324ca987d46SWarner Losh 
325ca987d46SWarner Losh 	func = stackPopPtr(pVM->pStack);
326ca987d46SWarner Losh 	nparam = stackPopINT(pVM->pStack);
327ca987d46SWarner Losh 
328ca987d46SWarner Losh #if FICL_ROBUST > 1
329ca987d46SWarner Losh 	vmCheckStack(pVM, nparam, 1);
330ca987d46SWarner Losh #endif
331ca987d46SWarner Losh 
332ca987d46SWarner Losh 	for (i = 0; i < nparam; i++)
333ca987d46SWarner Losh 		p[i] = stackPopINT(pVM->pStack);
334ca987d46SWarner Losh 
335ca987d46SWarner Losh 	result = func(p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8],
336ca987d46SWarner Losh 	    p[9]);
337ca987d46SWarner Losh 
338ca987d46SWarner Losh 	stackPushINT(pVM->pStack, result);
339ca987d46SWarner Losh 
340ca987d46SWarner Losh 	return;
341ca987d46SWarner Losh }
342ca987d46SWarner Losh 
343ca987d46SWarner Losh void
ficlUuidFromString(FICL_VM * pVM)344ca987d46SWarner Losh ficlUuidFromString(FICL_VM *pVM)
345ca987d46SWarner Losh {
346ca987d46SWarner Losh #ifndef	TESTMAIN
347ca987d46SWarner Losh 	char	*uuid;
348ca987d46SWarner Losh 	uint32_t status;
349ca987d46SWarner Losh #endif
350ca987d46SWarner Losh 	char	*uuidp;
351ca987d46SWarner Losh 	int	uuids;
352ca987d46SWarner Losh 	uuid_t	*u;
353ca987d46SWarner Losh 
354ca987d46SWarner Losh #if FICL_ROBUST > 1
355ca987d46SWarner Losh 	vmCheckStack(pVM, 2, 0);
356ca987d46SWarner Losh #endif
357ca987d46SWarner Losh 
358ca987d46SWarner Losh 	uuids = stackPopINT(pVM->pStack);
359ca987d46SWarner Losh 	uuidp = (char *) stackPopPtr(pVM->pStack);
360ca987d46SWarner Losh 
361ca987d46SWarner Losh #ifndef	TESTMAIN
362ca987d46SWarner Losh 	uuid = (char *)ficlMalloc(uuids + 1);
363ca987d46SWarner Losh 	if (!uuid)
364ca987d46SWarner Losh 		vmThrowErr(pVM, "Error: out of memory");
365ca987d46SWarner Losh 	strncpy(uuid, uuidp, uuids);
366ca987d46SWarner Losh 	uuid[uuids] = '\0';
367ca987d46SWarner Losh 
368ca987d46SWarner Losh 	u = (uuid_t *)ficlMalloc(sizeof (*u));
369ca987d46SWarner Losh 
370ca987d46SWarner Losh 	uuid_from_string(uuid, u, &status);
371ca987d46SWarner Losh 	ficlFree(uuid);
372ca987d46SWarner Losh 	if (status != uuid_s_ok) {
373ca987d46SWarner Losh 		ficlFree(u);
374ca987d46SWarner Losh 		u = NULL;
375ca987d46SWarner Losh 	}
376ca987d46SWarner Losh #else
377ca987d46SWarner Losh 	u = NULL;
378ca987d46SWarner Losh #endif
379ca987d46SWarner Losh 	stackPushPtr(pVM->pStack, u);
380ca987d46SWarner Losh 
381ca987d46SWarner Losh 
382ca987d46SWarner Losh 	return;
383ca987d46SWarner Losh }
384ca987d46SWarner Losh 
385ca987d46SWarner Losh void
ficlUuidToString(FICL_VM * pVM)386ca987d46SWarner Losh ficlUuidToString(FICL_VM *pVM)
387ca987d46SWarner Losh {
388ca987d46SWarner Losh #ifndef	TESTMAIN
389ca987d46SWarner Losh 	char	*uuid;
390ca987d46SWarner Losh 	uint32_t status;
391ca987d46SWarner Losh #endif
392ca987d46SWarner Losh 	uuid_t	*u;
393ca987d46SWarner Losh 
394ca987d46SWarner Losh #if FICL_ROBUST > 1
395ca987d46SWarner Losh 	vmCheckStack(pVM, 1, 0);
396ca987d46SWarner Losh #endif
397ca987d46SWarner Losh 
398ca987d46SWarner Losh 	u = (uuid_t *)stackPopPtr(pVM->pStack);
399ca987d46SWarner Losh 
400ca987d46SWarner Losh #ifndef	TESTMAIN
401ca987d46SWarner Losh 	uuid_to_string(u, &uuid, &status);
402ca987d46SWarner Losh 	if (status != uuid_s_ok) {
403ca987d46SWarner Losh 		stackPushPtr(pVM->pStack, uuid);
404ca987d46SWarner Losh 		stackPushINT(pVM->pStack, strlen(uuid));
405ca987d46SWarner Losh 	} else
406ca987d46SWarner Losh #endif
407ca987d46SWarner Losh 		stackPushINT(pVM->pStack, -1);
408ca987d46SWarner Losh 
409ca987d46SWarner Losh 	return;
410ca987d46SWarner Losh }
411ca987d46SWarner Losh 
412ca987d46SWarner Losh /**************************************************************************
413ca987d46SWarner Losh                         f i c l E x e c F D
414ca987d46SWarner Losh ** reads in text from file fd and passes it to ficlExec()
415ca987d46SWarner Losh  * returns VM_OUTOFTEXT on success or the ficlExec() error code on
416ca987d46SWarner Losh  * failure.
417ca987d46SWarner Losh  */
418ca987d46SWarner Losh #define nLINEBUF 256
ficlExecFD(FICL_VM * pVM,int fd)419ca987d46SWarner Losh int ficlExecFD(FICL_VM *pVM, int fd)
420ca987d46SWarner Losh {
421ca987d46SWarner Losh     char    cp[nLINEBUF];
422ca987d46SWarner Losh     int     nLine = 0, rval = VM_OUTOFTEXT;
423ca987d46SWarner Losh     char    ch;
424ca987d46SWarner Losh     CELL    id;
425ca987d46SWarner Losh 
426ca987d46SWarner Losh     id = pVM->sourceID;
427ca987d46SWarner Losh     pVM->sourceID.i = fd;
428ca987d46SWarner Losh 
429ca987d46SWarner Losh     /* feed each line to ficlExec */
430ca987d46SWarner Losh     while (1) {
431ca987d46SWarner Losh 	int status, i;
432ca987d46SWarner Losh 
433ca987d46SWarner Losh 	i = 0;
434ca987d46SWarner Losh 	while ((status = read(fd, &ch, 1)) > 0 && ch != '\n')
435ca987d46SWarner Losh 	    cp[i++] = ch;
436ca987d46SWarner Losh         nLine++;
437ca987d46SWarner Losh 	if (!i) {
438ca987d46SWarner Losh 	    if (status < 1)
439ca987d46SWarner Losh 		break;
440ca987d46SWarner Losh 	    continue;
441ca987d46SWarner Losh 	}
442ca987d46SWarner Losh         rval = ficlExecC(pVM, cp, i);
443ca987d46SWarner Losh 	if(rval != VM_QUIT && rval != VM_USEREXIT && rval != VM_OUTOFTEXT)
444ca987d46SWarner Losh         {
445ca987d46SWarner Losh             pVM->sourceID = id;
446ca987d46SWarner Losh             return rval;
447ca987d46SWarner Losh         }
448ca987d46SWarner Losh     }
449ca987d46SWarner Losh     /*
450ca987d46SWarner Losh     ** Pass an empty line with SOURCE-ID == -1 to flush
451ca987d46SWarner Losh     ** any pending REFILLs (as required by FILE wordset)
452ca987d46SWarner Losh     */
453ca987d46SWarner Losh     pVM->sourceID.i = -1;
454ca987d46SWarner Losh     ficlExec(pVM, "");
455ca987d46SWarner Losh 
456ca987d46SWarner Losh     pVM->sourceID = id;
457ca987d46SWarner Losh     return rval;
458ca987d46SWarner Losh }
459ca987d46SWarner Losh 
displayCellNoPad(FICL_VM * pVM)460ca987d46SWarner Losh static void displayCellNoPad(FICL_VM *pVM)
461ca987d46SWarner Losh {
462ca987d46SWarner Losh     CELL c;
463ca987d46SWarner Losh #if FICL_ROBUST > 1
464ca987d46SWarner Losh     vmCheckStack(pVM, 1, 0);
465ca987d46SWarner Losh #endif
466ca987d46SWarner Losh     c = stackPop(pVM->pStack);
467ca987d46SWarner Losh     ltoa((c).i, pVM->pad, pVM->base);
468ca987d46SWarner Losh     vmTextOut(pVM, pVM->pad, 0);
469ca987d46SWarner Losh     return;
470ca987d46SWarner Losh }
471ca987d46SWarner Losh 
472ca987d46SWarner Losh /*      isdir? - Return whether an fd corresponds to a directory.
473ca987d46SWarner Losh  *
474ca987d46SWarner Losh  * isdir? ( fd -- bool )
475ca987d46SWarner Losh  */
isdirQuestion(FICL_VM * pVM)476ca987d46SWarner Losh static void isdirQuestion(FICL_VM *pVM)
477ca987d46SWarner Losh {
478ca987d46SWarner Losh     struct stat sb;
479ca987d46SWarner Losh     FICL_INT flag;
480ca987d46SWarner Losh     int fd;
481ca987d46SWarner Losh 
482ca987d46SWarner Losh #if FICL_ROBUST > 1
483ca987d46SWarner Losh     vmCheckStack(pVM, 1, 1);
484ca987d46SWarner Losh #endif
485ca987d46SWarner Losh 
486ca987d46SWarner Losh     fd = stackPopINT(pVM->pStack);
487ca987d46SWarner Losh     flag = FICL_FALSE;
488ca987d46SWarner Losh     do {
489ca987d46SWarner Losh         if (fd < 0)
490ca987d46SWarner Losh             break;
491ca987d46SWarner Losh         if (fstat(fd, &sb) < 0)
492ca987d46SWarner Losh             break;
493ca987d46SWarner Losh         if (!S_ISDIR(sb.st_mode))
494ca987d46SWarner Losh             break;
495ca987d46SWarner Losh         flag = FICL_TRUE;
496ca987d46SWarner Losh     } while (0);
497ca987d46SWarner Losh     stackPushINT(pVM->pStack, flag);
498ca987d46SWarner Losh }
499ca987d46SWarner Losh 
500ca987d46SWarner Losh /*          fopen - open a file and return new fd on stack.
501ca987d46SWarner Losh  *
502ca987d46SWarner Losh  * fopen ( ptr count mode -- fd )
503ca987d46SWarner Losh  */
pfopen(FICL_VM * pVM)504ca987d46SWarner Losh static void pfopen(FICL_VM *pVM)
505ca987d46SWarner Losh {
506ca987d46SWarner Losh     int     mode, fd, count;
507ca987d46SWarner Losh     char    *ptr, *name;
508ca987d46SWarner Losh 
509ca987d46SWarner Losh #if FICL_ROBUST > 1
510ca987d46SWarner Losh     vmCheckStack(pVM, 3, 1);
511ca987d46SWarner Losh #endif
512ca987d46SWarner Losh 
513ca987d46SWarner Losh     mode = stackPopINT(pVM->pStack);    /* get mode */
514ca987d46SWarner Losh     count = stackPopINT(pVM->pStack);   /* get count */
515ca987d46SWarner Losh     ptr = stackPopPtr(pVM->pStack);     /* get ptr */
516ca987d46SWarner Losh 
517ca987d46SWarner Losh     if ((count < 0) || (ptr == NULL)) {
518ca987d46SWarner Losh         stackPushINT(pVM->pStack, -1);
519ca987d46SWarner Losh         return;
520ca987d46SWarner Losh     }
521ca987d46SWarner Losh 
522ca987d46SWarner Losh     /* ensure that the string is null terminated */
523ca987d46SWarner Losh     name = (char *)malloc(count+1);
524ca987d46SWarner Losh     bcopy(ptr,name,count);
525ca987d46SWarner Losh     name[count] = 0;
526ca987d46SWarner Losh 
527ca987d46SWarner Losh     /* open the file */
528ca987d46SWarner Losh     fd = open(name, mode);
5292ef9ff7dSSimon J. Gerraty #ifdef LOADER_VERIEXEC
5302ef9ff7dSSimon J. Gerraty     if (fd >= 0) {
531afc571b1SSimon J. Gerraty 	if (verify_file(fd, name, 0, VE_GUESS, __func__) < 0) {
5322ef9ff7dSSimon J. Gerraty 	    /* not verified writing ok but reading is not */
5332ef9ff7dSSimon J. Gerraty 	    if ((mode & O_ACCMODE) != O_WRONLY) {
5342ef9ff7dSSimon J. Gerraty 		close(fd);
5352ef9ff7dSSimon J. Gerraty 		fd = -1;
5362ef9ff7dSSimon J. Gerraty 	    }
5372ef9ff7dSSimon J. Gerraty 	} else {
5382ef9ff7dSSimon J. Gerraty 	    /* verified reading ok but writing is not */
5392ef9ff7dSSimon J. Gerraty 	    if ((mode & O_ACCMODE) != O_RDONLY) {
5402ef9ff7dSSimon J. Gerraty 		close(fd);
5412ef9ff7dSSimon J. Gerraty 		fd = -1;
5422ef9ff7dSSimon J. Gerraty 	    }
5432ef9ff7dSSimon J. Gerraty 	}
5442ef9ff7dSSimon J. Gerraty     }
5452ef9ff7dSSimon J. Gerraty #endif
546ca987d46SWarner Losh     free(name);
547ca987d46SWarner Losh     stackPushINT(pVM->pStack, fd);
548ca987d46SWarner Losh     return;
549ca987d46SWarner Losh }
550ca987d46SWarner Losh 
551ca987d46SWarner Losh /*          fclose - close a file who's fd is on stack.
552ca987d46SWarner Losh  *
553ca987d46SWarner Losh  * fclose ( fd -- )
554ca987d46SWarner Losh  */
pfclose(FICL_VM * pVM)555ca987d46SWarner Losh static void pfclose(FICL_VM *pVM)
556ca987d46SWarner Losh {
557ca987d46SWarner Losh     int fd;
558ca987d46SWarner Losh 
559ca987d46SWarner Losh #if FICL_ROBUST > 1
560ca987d46SWarner Losh     vmCheckStack(pVM, 1, 0);
561ca987d46SWarner Losh #endif
562ca987d46SWarner Losh     fd = stackPopINT(pVM->pStack); /* get fd */
563ca987d46SWarner Losh     if (fd != -1)
564ca987d46SWarner Losh 	close(fd);
565ca987d46SWarner Losh     return;
566ca987d46SWarner Losh }
567ca987d46SWarner Losh 
568ca987d46SWarner Losh /*          fread - read file contents
569ca987d46SWarner Losh  *
570ca987d46SWarner Losh  * fread  ( fd buf nbytes  -- nread )
571ca987d46SWarner Losh  */
pfread(FICL_VM * pVM)572ca987d46SWarner Losh static void pfread(FICL_VM *pVM)
573ca987d46SWarner Losh {
574ca987d46SWarner Losh     int     fd, len;
575ca987d46SWarner Losh     char *buf;
576ca987d46SWarner Losh 
577ca987d46SWarner Losh #if FICL_ROBUST > 1
578ca987d46SWarner Losh     vmCheckStack(pVM, 3, 1);
579ca987d46SWarner Losh #endif
580ca987d46SWarner Losh     len = stackPopINT(pVM->pStack); /* get number of bytes to read */
581ca987d46SWarner Losh     buf = stackPopPtr(pVM->pStack); /* get buffer */
582ca987d46SWarner Losh     fd = stackPopINT(pVM->pStack); /* get fd */
583ca987d46SWarner Losh     if (len > 0 && buf && fd != -1)
584ca987d46SWarner Losh 	stackPushINT(pVM->pStack, read(fd, buf, len));
585ca987d46SWarner Losh     else
586ca987d46SWarner Losh 	stackPushINT(pVM->pStack, -1);
587ca987d46SWarner Losh     return;
588ca987d46SWarner Losh }
589ca987d46SWarner Losh 
590ca987d46SWarner Losh /*      freaddir - read directory contents
591ca987d46SWarner Losh  *
592ca987d46SWarner Losh  * freaddir ( fd -- ptr len TRUE | FALSE )
593ca987d46SWarner Losh  */
pfreaddir(FICL_VM * pVM)594ca987d46SWarner Losh static void pfreaddir(FICL_VM *pVM)
595ca987d46SWarner Losh {
596ca987d46SWarner Losh #ifdef TESTMAIN
597ca987d46SWarner Losh     static struct dirent dirent;
598ca987d46SWarner Losh     struct stat sb;
599ca987d46SWarner Losh     char *buf;
600ca987d46SWarner Losh     off_t off, ptr;
601ca987d46SWarner Losh     u_int blksz;
602ca987d46SWarner Losh     int bufsz;
603ca987d46SWarner Losh #endif
604ca987d46SWarner Losh     struct dirent *d;
605ca987d46SWarner Losh     int fd;
606ca987d46SWarner Losh 
607ca987d46SWarner Losh #if FICL_ROBUST > 1
608ca987d46SWarner Losh     vmCheckStack(pVM, 1, 3);
609ca987d46SWarner Losh #endif
610ca987d46SWarner Losh 
611ca987d46SWarner Losh     fd = stackPopINT(pVM->pStack);
612ca987d46SWarner Losh #if TESTMAIN
613ca987d46SWarner Losh     /*
614ca987d46SWarner Losh      * The readdirfd() function is specific to the loader environment.
615ca987d46SWarner Losh      * We do the best we can to make freaddir work, but it's not at
616ca987d46SWarner Losh      * all guaranteed.
617ca987d46SWarner Losh      */
618ca987d46SWarner Losh     d = NULL;
619ca987d46SWarner Losh     buf = NULL;
620ca987d46SWarner Losh     do {
621ca987d46SWarner Losh 	if (fd == -1)
622ca987d46SWarner Losh 	    break;
623ca987d46SWarner Losh 	if (fstat(fd, &sb) == -1)
624ca987d46SWarner Losh 	    break;
625ca987d46SWarner Losh 	blksz = (sb.st_blksize) ? sb.st_blksize : getpagesize();
626ca987d46SWarner Losh 	if ((blksz & (blksz - 1)) != 0)
627ca987d46SWarner Losh 	    break;
628ca987d46SWarner Losh 	buf = malloc(blksz);
629ca987d46SWarner Losh 	if (buf == NULL)
630ca987d46SWarner Losh 	    break;
631ca987d46SWarner Losh 	off = lseek(fd, 0LL, SEEK_CUR);
632ca987d46SWarner Losh 	if (off == -1)
633ca987d46SWarner Losh 	    break;
634ca987d46SWarner Losh 	ptr = off;
635ca987d46SWarner Losh 	if (lseek(fd, 0, SEEK_SET) == -1)
636ca987d46SWarner Losh 	    break;
637ca987d46SWarner Losh 	bufsz = getdents(fd, buf, blksz);
638ca987d46SWarner Losh 	while (bufsz > 0 && bufsz <= ptr) {
639ca987d46SWarner Losh 	    ptr -= bufsz;
640ca987d46SWarner Losh 	    bufsz = getdents(fd, buf, blksz);
641ca987d46SWarner Losh 	}
642ca987d46SWarner Losh 	if (bufsz <= 0)
643ca987d46SWarner Losh 	    break;
644ca987d46SWarner Losh 	d = (void *)(buf + ptr);
645ca987d46SWarner Losh 	dirent = *d;
646ca987d46SWarner Losh 	off += d->d_reclen;
647ca987d46SWarner Losh 	d = (lseek(fd, off, SEEK_SET) != off) ? NULL : &dirent;
648ca987d46SWarner Losh     } while (0);
649ca987d46SWarner Losh     if (buf != NULL)
650ca987d46SWarner Losh 	free(buf);
651ca987d46SWarner Losh #else
652ca987d46SWarner Losh     d = readdirfd(fd);
653ca987d46SWarner Losh #endif
654ca987d46SWarner Losh     if (d != NULL) {
655ca987d46SWarner Losh         stackPushPtr(pVM->pStack, d->d_name);
656ca987d46SWarner Losh         stackPushINT(pVM->pStack, strlen(d->d_name));
657ca987d46SWarner Losh         stackPushINT(pVM->pStack, FICL_TRUE);
658ca987d46SWarner Losh     } else {
659ca987d46SWarner Losh         stackPushINT(pVM->pStack, FICL_FALSE);
660ca987d46SWarner Losh     }
661ca987d46SWarner Losh }
662ca987d46SWarner Losh 
663ca987d46SWarner Losh /*          fload - interpret file contents
664ca987d46SWarner Losh  *
665ca987d46SWarner Losh  * fload  ( fd -- )
666ca987d46SWarner Losh  */
pfload(FICL_VM * pVM)667ca987d46SWarner Losh static void pfload(FICL_VM *pVM)
668ca987d46SWarner Losh {
669ca987d46SWarner Losh     int     fd;
670ca987d46SWarner Losh 
671ca987d46SWarner Losh #if FICL_ROBUST > 1
672ca987d46SWarner Losh     vmCheckStack(pVM, 1, 0);
673ca987d46SWarner Losh #endif
674ca987d46SWarner Losh     fd = stackPopINT(pVM->pStack); /* get fd */
675ca987d46SWarner Losh     if (fd != -1)
676ca987d46SWarner Losh 	ficlExecFD(pVM, fd);
677ca987d46SWarner Losh     return;
678ca987d46SWarner Losh }
679ca987d46SWarner Losh 
680ca987d46SWarner Losh /*          fwrite - write file contents
681ca987d46SWarner Losh  *
682ca987d46SWarner Losh  * fwrite  ( fd buf nbytes  -- nwritten )
683ca987d46SWarner Losh  */
pfwrite(FICL_VM * pVM)684ca987d46SWarner Losh static void pfwrite(FICL_VM *pVM)
685ca987d46SWarner Losh {
686ca987d46SWarner Losh     int     fd, len;
687ca987d46SWarner Losh     char *buf;
688ca987d46SWarner Losh 
689ca987d46SWarner Losh #if FICL_ROBUST > 1
690ca987d46SWarner Losh     vmCheckStack(pVM, 3, 1);
691ca987d46SWarner Losh #endif
692ca987d46SWarner Losh     len = stackPopINT(pVM->pStack); /* get number of bytes to read */
693ca987d46SWarner Losh     buf = stackPopPtr(pVM->pStack); /* get buffer */
694ca987d46SWarner Losh     fd = stackPopINT(pVM->pStack); /* get fd */
695ca987d46SWarner Losh     if (len > 0 && buf && fd != -1)
696ca987d46SWarner Losh 	stackPushINT(pVM->pStack, write(fd, buf, len));
697ca987d46SWarner Losh     else
698ca987d46SWarner Losh 	stackPushINT(pVM->pStack, -1);
699ca987d46SWarner Losh     return;
700ca987d46SWarner Losh }
701ca987d46SWarner Losh 
702ca987d46SWarner Losh /*          fseek - seek to a new position in a file
703ca987d46SWarner Losh  *
704ca987d46SWarner Losh  * fseek  ( fd ofs whence  -- pos )
705ca987d46SWarner Losh  */
pfseek(FICL_VM * pVM)706ca987d46SWarner Losh static void pfseek(FICL_VM *pVM)
707ca987d46SWarner Losh {
708ca987d46SWarner Losh     int     fd, pos, whence;
709ca987d46SWarner Losh 
710ca987d46SWarner Losh #if FICL_ROBUST > 1
711ca987d46SWarner Losh     vmCheckStack(pVM, 3, 1);
712ca987d46SWarner Losh #endif
713ca987d46SWarner Losh     whence = stackPopINT(pVM->pStack);
714ca987d46SWarner Losh     pos = stackPopINT(pVM->pStack);
715ca987d46SWarner Losh     fd = stackPopINT(pVM->pStack);
716ca987d46SWarner Losh     stackPushINT(pVM->pStack, lseek(fd, pos, whence));
717ca987d46SWarner Losh     return;
718ca987d46SWarner Losh }
719ca987d46SWarner Losh 
720ca987d46SWarner Losh /*           key - get a character from stdin
721ca987d46SWarner Losh  *
722ca987d46SWarner Losh  * key ( -- char )
723ca987d46SWarner Losh  */
key(FICL_VM * pVM)724ca987d46SWarner Losh static void key(FICL_VM *pVM)
725ca987d46SWarner Losh {
726ca987d46SWarner Losh #if FICL_ROBUST > 1
727ca987d46SWarner Losh     vmCheckStack(pVM, 0, 1);
728ca987d46SWarner Losh #endif
729ca987d46SWarner Losh     stackPushINT(pVM->pStack, getchar());
730ca987d46SWarner Losh     return;
731ca987d46SWarner Losh }
732ca987d46SWarner Losh 
733ca987d46SWarner Losh /*           key? - check for a character from stdin (FACILITY)
734ca987d46SWarner Losh  *
735ca987d46SWarner Losh  * key? ( -- flag )
736ca987d46SWarner Losh  */
keyQuestion(FICL_VM * pVM)737ca987d46SWarner Losh static void keyQuestion(FICL_VM *pVM)
738ca987d46SWarner Losh {
739ca987d46SWarner Losh #if FICL_ROBUST > 1
740ca987d46SWarner Losh     vmCheckStack(pVM, 0, 1);
741ca987d46SWarner Losh #endif
742ca987d46SWarner Losh #ifdef TESTMAIN
743ca987d46SWarner Losh     /* XXX Since we don't fiddle with termios, let it always succeed... */
744ca987d46SWarner Losh     stackPushINT(pVM->pStack, FICL_TRUE);
745ca987d46SWarner Losh #else
746ca987d46SWarner Losh     /* But here do the right thing. */
747ca987d46SWarner Losh     stackPushINT(pVM->pStack, ischar()? FICL_TRUE : FICL_FALSE);
748ca987d46SWarner Losh #endif
749ca987d46SWarner Losh     return;
750ca987d46SWarner Losh }
751ca987d46SWarner Losh 
752ca987d46SWarner Losh /* seconds - gives number of seconds since beginning of time
753ca987d46SWarner Losh  *
754ca987d46SWarner Losh  * beginning of time is defined as:
755ca987d46SWarner Losh  *
756ca987d46SWarner Losh  *	BTX	- number of seconds since midnight
757ca987d46SWarner Losh  *	FreeBSD	- number of seconds since Jan 1 1970
758ca987d46SWarner Losh  *
759ca987d46SWarner Losh  * seconds ( -- u )
760ca987d46SWarner Losh  */
pseconds(FICL_VM * pVM)761ca987d46SWarner Losh static void pseconds(FICL_VM *pVM)
762ca987d46SWarner Losh {
763ca987d46SWarner Losh #if FICL_ROBUST > 1
764ca987d46SWarner Losh     vmCheckStack(pVM,0,1);
765ca987d46SWarner Losh #endif
766ca987d46SWarner Losh     stackPushUNS(pVM->pStack, (FICL_UNS) time(NULL));
767ca987d46SWarner Losh     return;
768ca987d46SWarner Losh }
769ca987d46SWarner Losh 
770ca987d46SWarner Losh /* ms - wait at least that many milliseconds (FACILITY)
771ca987d46SWarner Losh  *
772ca987d46SWarner Losh  * ms ( u -- )
773ca987d46SWarner Losh  *
774ca987d46SWarner Losh  */
ms(FICL_VM * pVM)775ca987d46SWarner Losh static void ms(FICL_VM *pVM)
776ca987d46SWarner Losh {
777ca987d46SWarner Losh #if FICL_ROBUST > 1
778ca987d46SWarner Losh     vmCheckStack(pVM,1,0);
779ca987d46SWarner Losh #endif
780ca987d46SWarner Losh #ifdef TESTMAIN
781ca987d46SWarner Losh     usleep(stackPopUNS(pVM->pStack)*1000);
782ca987d46SWarner Losh #else
783ca987d46SWarner Losh     delay(stackPopUNS(pVM->pStack)*1000);
784ca987d46SWarner Losh #endif
785ca987d46SWarner Losh     return;
786ca987d46SWarner Losh }
787ca987d46SWarner Losh 
788ca987d46SWarner Losh /*           fkey - get a character from a file
789ca987d46SWarner Losh  *
790ca987d46SWarner Losh  * fkey ( file -- char )
791ca987d46SWarner Losh  */
fkey(FICL_VM * pVM)792ca987d46SWarner Losh static void fkey(FICL_VM *pVM)
793ca987d46SWarner Losh {
794ca987d46SWarner Losh     int i, fd;
795ca987d46SWarner Losh     char ch;
796ca987d46SWarner Losh 
797ca987d46SWarner Losh #if FICL_ROBUST > 1
798ca987d46SWarner Losh     vmCheckStack(pVM, 1, 1);
799ca987d46SWarner Losh #endif
800ca987d46SWarner Losh     fd = stackPopINT(pVM->pStack);
801ca987d46SWarner Losh     i = read(fd, &ch, 1);
802ca987d46SWarner Losh     stackPushINT(pVM->pStack, i > 0 ? ch : -1);
803ca987d46SWarner Losh     return;
804ca987d46SWarner Losh }
805ca987d46SWarner Losh 
806ca987d46SWarner Losh 
807ca987d46SWarner Losh /*
808ca987d46SWarner Losh ** Retrieves free space remaining on the dictionary
809ca987d46SWarner Losh */
810ca987d46SWarner Losh 
freeHeap(FICL_VM * pVM)811ca987d46SWarner Losh static void freeHeap(FICL_VM *pVM)
812ca987d46SWarner Losh {
813ca987d46SWarner Losh     stackPushINT(pVM->pStack, dictCellsAvail(ficlGetDict(pVM->pSys)));
814ca987d46SWarner Losh }
815ca987d46SWarner Losh 
816ca987d46SWarner Losh 
817ca987d46SWarner Losh /******************* Increase dictionary size on-demand ******************/
818ca987d46SWarner Losh 
ficlDictThreshold(FICL_VM * pVM)819ca987d46SWarner Losh static void ficlDictThreshold(FICL_VM *pVM)
820ca987d46SWarner Losh {
821ca987d46SWarner Losh     stackPushPtr(pVM->pStack, &dictThreshold);
822ca987d46SWarner Losh }
823ca987d46SWarner Losh 
ficlDictIncrease(FICL_VM * pVM)824ca987d46SWarner Losh static void ficlDictIncrease(FICL_VM *pVM)
825ca987d46SWarner Losh {
826ca987d46SWarner Losh     stackPushPtr(pVM->pStack, &dictIncrease);
827ca987d46SWarner Losh }
828ca987d46SWarner Losh 
829ca987d46SWarner Losh /**************************************************************************
830ca987d46SWarner Losh                         f i c l C o m p i l e P l a t f o r m
831ca987d46SWarner Losh ** Build FreeBSD platform extensions into the system dictionary
832ca987d46SWarner Losh **************************************************************************/
ficlCompilePlatform(FICL_SYSTEM * pSys)833ca987d46SWarner Losh void ficlCompilePlatform(FICL_SYSTEM *pSys)
834ca987d46SWarner Losh {
835ca987d46SWarner Losh     ficlCompileFcn **fnpp;
836ca987d46SWarner Losh     FICL_DICT *dp = pSys->dp;
837ca987d46SWarner Losh     assert (dp);
838ca987d46SWarner Losh 
839ca987d46SWarner Losh     dictAppendWord(dp, ".#",        displayCellNoPad,    FW_DEFAULT);
840ca987d46SWarner Losh     dictAppendWord(dp, "isdir?",    isdirQuestion,  FW_DEFAULT);
841ca987d46SWarner Losh     dictAppendWord(dp, "fopen",	    pfopen,	    FW_DEFAULT);
842ca987d46SWarner Losh     dictAppendWord(dp, "fclose",    pfclose,	    FW_DEFAULT);
843ca987d46SWarner Losh     dictAppendWord(dp, "fread",	    pfread,	    FW_DEFAULT);
844ca987d46SWarner Losh     dictAppendWord(dp, "freaddir",  pfreaddir,	    FW_DEFAULT);
845ca987d46SWarner Losh     dictAppendWord(dp, "fload",	    pfload,	    FW_DEFAULT);
846ca987d46SWarner Losh     dictAppendWord(dp, "fkey",	    fkey,	    FW_DEFAULT);
847ca987d46SWarner Losh     dictAppendWord(dp, "fseek",     pfseek,	    FW_DEFAULT);
848ca987d46SWarner Losh     dictAppendWord(dp, "fwrite",    pfwrite,	    FW_DEFAULT);
849ca987d46SWarner Losh     dictAppendWord(dp, "key",	    key,	    FW_DEFAULT);
850ca987d46SWarner Losh     dictAppendWord(dp, "key?",	    keyQuestion,    FW_DEFAULT);
851ca987d46SWarner Losh     dictAppendWord(dp, "ms",        ms,             FW_DEFAULT);
852ca987d46SWarner Losh     dictAppendWord(dp, "seconds",   pseconds,       FW_DEFAULT);
853ca987d46SWarner Losh     dictAppendWord(dp, "heap?",     freeHeap,       FW_DEFAULT);
854ca987d46SWarner Losh     dictAppendWord(dp, "dictthreshold", ficlDictThreshold, FW_DEFAULT);
855ca987d46SWarner Losh     dictAppendWord(dp, "dictincrease", ficlDictIncrease, FW_DEFAULT);
856ca987d46SWarner Losh 
857ca987d46SWarner Losh     dictAppendWord(dp, "setenv",    ficlSetenv,	    FW_DEFAULT);
858ca987d46SWarner Losh     dictAppendWord(dp, "setenv?",   ficlSetenvq,    FW_DEFAULT);
859ca987d46SWarner Losh     dictAppendWord(dp, "getenv",    ficlGetenv,	    FW_DEFAULT);
860ca987d46SWarner Losh     dictAppendWord(dp, "unsetenv",  ficlUnsetenv,   FW_DEFAULT);
861ca987d46SWarner Losh     dictAppendWord(dp, "copyin",    ficlCopyin,	    FW_DEFAULT);
862ca987d46SWarner Losh     dictAppendWord(dp, "copyout",   ficlCopyout,    FW_DEFAULT);
863ca987d46SWarner Losh     dictAppendWord(dp, "findfile",  ficlFindfile,   FW_DEFAULT);
864ca987d46SWarner Losh     dictAppendWord(dp, "ccall",	    ficlCcall,	    FW_DEFAULT);
865ca987d46SWarner Losh     dictAppendWord(dp, "uuid-from-string", ficlUuidFromString, FW_DEFAULT);
866ca987d46SWarner Losh     dictAppendWord(dp, "uuid-to-string", ficlUuidToString, FW_DEFAULT);
867ca987d46SWarner Losh 
868*8ec8413fSWarner Losh     SET_FOREACH(fnpp, X4th_compile_set)
869ca987d46SWarner Losh 	(*fnpp)(pSys);
870ca987d46SWarner Losh 
871ca987d46SWarner Losh #if defined(__i386__)
872ca987d46SWarner Losh     ficlSetEnv(pSys, "arch-i386",         FICL_TRUE);
873ca987d46SWarner Losh     ficlSetEnv(pSys, "arch-powerpc",      FICL_FALSE);
874ca987d46SWarner Losh #elif defined(__powerpc__)
875ca987d46SWarner Losh     ficlSetEnv(pSys, "arch-i386",         FICL_FALSE);
876ca987d46SWarner Losh     ficlSetEnv(pSys, "arch-powerpc",      FICL_TRUE);
877ca987d46SWarner Losh #endif
878ca987d46SWarner Losh 
879ca987d46SWarner Losh     return;
880ca987d46SWarner Losh }
881