1a1bf3f78SToomas Soome /*
2a1bf3f78SToomas Soome * Copyright (c) 2000 Daniel Capo Sobral
3a1bf3f78SToomas Soome * All rights reserved.
4a1bf3f78SToomas Soome *
5a1bf3f78SToomas Soome * Redistribution and use in source and binary forms, with or without
6a1bf3f78SToomas Soome * modification, are permitted provided that the following conditions
7a1bf3f78SToomas Soome * are met:
8a1bf3f78SToomas Soome * 1. Redistributions of source code must retain the above copyright
9a1bf3f78SToomas Soome * notice, this list of conditions and the following disclaimer.
10a1bf3f78SToomas Soome * 2. Redistributions in binary form must reproduce the above copyright
11a1bf3f78SToomas Soome * notice, this list of conditions and the following disclaimer in the
12a1bf3f78SToomas Soome * documentation and/or other materials provided with the distribution.
13a1bf3f78SToomas Soome *
14a1bf3f78SToomas Soome * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15a1bf3f78SToomas Soome * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16a1bf3f78SToomas Soome * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17a1bf3f78SToomas Soome * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18a1bf3f78SToomas Soome * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19a1bf3f78SToomas Soome * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20a1bf3f78SToomas Soome * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21a1bf3f78SToomas Soome * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22a1bf3f78SToomas Soome * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23a1bf3f78SToomas Soome * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24a1bf3f78SToomas Soome * SUCH DAMAGE.
25a1bf3f78SToomas Soome *
26a1bf3f78SToomas Soome * $FreeBSD$
27a1bf3f78SToomas Soome */
28a1bf3f78SToomas Soome
29a1bf3f78SToomas Soome /*
30a1bf3f78SToomas Soome * l o a d e r . c
31a1bf3f78SToomas Soome * Additional FICL words designed for FreeBSD's loader
32a1bf3f78SToomas Soome */
33a1bf3f78SToomas Soome
34*e09118e4SToomas Soome #ifndef _STANDALONE
35a1bf3f78SToomas Soome #include <sys/types.h>
36a1bf3f78SToomas Soome #include <sys/stat.h>
37a1bf3f78SToomas Soome #include <dirent.h>
38a1bf3f78SToomas Soome #include <fcntl.h>
39a1bf3f78SToomas Soome #include <stdio.h>
40a1bf3f78SToomas Soome #include <stdlib.h>
41a1bf3f78SToomas Soome #include <unistd.h>
42a1bf3f78SToomas Soome #include <strings.h>
43a1bf3f78SToomas Soome #include <termios.h>
44a1bf3f78SToomas Soome #else
45a1bf3f78SToomas Soome #include <stand.h>
46a1bf3f78SToomas Soome #include "bootstrap.h"
47a1bf3f78SToomas Soome #endif
48*e09118e4SToomas Soome #ifdef _STANDALONE
49065446baSToomas Soome #include <uuid.h>
50065446baSToomas Soome #else
51065446baSToomas Soome #include <uuid/uuid.h>
52065446baSToomas Soome #endif
53a1bf3f78SToomas Soome #include <string.h>
54a1bf3f78SToomas Soome #include "ficl.h"
55a1bf3f78SToomas Soome
56a1bf3f78SToomas Soome /*
57a1bf3f78SToomas Soome * FreeBSD's loader interaction words and extras
58a1bf3f78SToomas Soome *
59a1bf3f78SToomas Soome * setenv ( value n name n' -- )
60a1bf3f78SToomas Soome * setenv? ( value n name n' flag -- )
61a1bf3f78SToomas Soome * getenv ( addr n -- addr' n' | -1 )
62a1bf3f78SToomas Soome * unsetenv ( addr n -- )
63a1bf3f78SToomas Soome * copyin ( addr addr' len -- )
64a1bf3f78SToomas Soome * copyout ( addr addr' len -- )
65a1bf3f78SToomas Soome * findfile ( name len type len' -- addr )
66a1bf3f78SToomas Soome * ccall ( [[...[p10] p9] ... p1] n addr -- result )
67065446baSToomas Soome * uuid-from-string ( addr n -- addr' )
68065446baSToomas Soome * uuid-to-string ( addr' -- addr n | -1 )
69a1bf3f78SToomas Soome * .# ( value -- )
70a1bf3f78SToomas Soome */
71a1bf3f78SToomas Soome
72a1bf3f78SToomas Soome void
ficlSetenv(ficlVm * pVM)73a1bf3f78SToomas Soome ficlSetenv(ficlVm *pVM)
74a1bf3f78SToomas Soome {
75a1bf3f78SToomas Soome char *name, *value;
76a1bf3f78SToomas Soome char *namep, *valuep;
77a1bf3f78SToomas Soome int names, values;
78a1bf3f78SToomas Soome
79a1bf3f78SToomas Soome FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 4, 0);
80a1bf3f78SToomas Soome
81a1bf3f78SToomas Soome names = ficlStackPopInteger(ficlVmGetDataStack(pVM));
82a1bf3f78SToomas Soome namep = (char *)ficlStackPopPointer(ficlVmGetDataStack(pVM));
83a1bf3f78SToomas Soome values = ficlStackPopInteger(ficlVmGetDataStack(pVM));
84a1bf3f78SToomas Soome valuep = (char *)ficlStackPopPointer(ficlVmGetDataStack(pVM));
85a1bf3f78SToomas Soome
86a1bf3f78SToomas Soome name = (char *)ficlMalloc(names+1);
87a1bf3f78SToomas Soome if (!name)
88a1bf3f78SToomas Soome ficlVmThrowError(pVM, "Error: out of memory");
89a1bf3f78SToomas Soome strncpy(name, namep, names);
90a1bf3f78SToomas Soome name[names] = '\0';
91a1bf3f78SToomas Soome value = (char *)ficlMalloc(values+1);
92a1bf3f78SToomas Soome if (!value)
93a1bf3f78SToomas Soome ficlVmThrowError(pVM, "Error: out of memory");
94a1bf3f78SToomas Soome strncpy(value, valuep, values);
95a1bf3f78SToomas Soome value[values] = '\0';
96a1bf3f78SToomas Soome
97a1bf3f78SToomas Soome setenv(name, value, 1);
98a1bf3f78SToomas Soome ficlFree(name);
99a1bf3f78SToomas Soome ficlFree(value);
100a1bf3f78SToomas Soome }
101a1bf3f78SToomas Soome
102a1bf3f78SToomas Soome void
ficlSetenvq(ficlVm * pVM)103a1bf3f78SToomas Soome ficlSetenvq(ficlVm *pVM)
104a1bf3f78SToomas Soome {
105a1bf3f78SToomas Soome char *name, *value;
106a1bf3f78SToomas Soome char *namep, *valuep;
107a1bf3f78SToomas Soome int names, values, overwrite;
108a1bf3f78SToomas Soome
109a1bf3f78SToomas Soome FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 5, 0);
110a1bf3f78SToomas Soome
111a1bf3f78SToomas Soome overwrite = ficlStackPopInteger(ficlVmGetDataStack(pVM));
112a1bf3f78SToomas Soome names = ficlStackPopInteger(ficlVmGetDataStack(pVM));
113a1bf3f78SToomas Soome namep = (char *)ficlStackPopPointer(ficlVmGetDataStack(pVM));
114a1bf3f78SToomas Soome values = ficlStackPopInteger(ficlVmGetDataStack(pVM));
115a1bf3f78SToomas Soome valuep = (char *)ficlStackPopPointer(ficlVmGetDataStack(pVM));
116a1bf3f78SToomas Soome
117a1bf3f78SToomas Soome name = (char *)ficlMalloc(names+1);
118a1bf3f78SToomas Soome if (!name)
119a1bf3f78SToomas Soome ficlVmThrowError(pVM, "Error: out of memory");
120a1bf3f78SToomas Soome strncpy(name, namep, names);
121a1bf3f78SToomas Soome name[names] = '\0';
122a1bf3f78SToomas Soome value = (char *)ficlMalloc(values+1);
123a1bf3f78SToomas Soome if (!value)
124a1bf3f78SToomas Soome ficlVmThrowError(pVM, "Error: out of memory");
125a1bf3f78SToomas Soome strncpy(value, valuep, values);
126a1bf3f78SToomas Soome value[values] = '\0';
127a1bf3f78SToomas Soome
128a1bf3f78SToomas Soome setenv(name, value, overwrite);
129a1bf3f78SToomas Soome ficlFree(name);
130a1bf3f78SToomas Soome ficlFree(value);
131a1bf3f78SToomas Soome }
132a1bf3f78SToomas Soome
133a1bf3f78SToomas Soome void
ficlGetenv(ficlVm * pVM)134a1bf3f78SToomas Soome ficlGetenv(ficlVm *pVM)
135a1bf3f78SToomas Soome {
136a1bf3f78SToomas Soome char *name, *value;
137a1bf3f78SToomas Soome char *namep;
138a1bf3f78SToomas Soome int names;
139a1bf3f78SToomas Soome
140a1bf3f78SToomas Soome FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 2, 2);
141a1bf3f78SToomas Soome
142a1bf3f78SToomas Soome names = ficlStackPopInteger(ficlVmGetDataStack(pVM));
143a1bf3f78SToomas Soome namep = (char *)ficlStackPopPointer(ficlVmGetDataStack(pVM));
144a1bf3f78SToomas Soome
145a1bf3f78SToomas Soome name = (char *)ficlMalloc(names+1);
146a1bf3f78SToomas Soome if (!name)
147a1bf3f78SToomas Soome ficlVmThrowError(pVM, "Error: out of memory");
148a1bf3f78SToomas Soome strncpy(name, namep, names);
149a1bf3f78SToomas Soome name[names] = '\0';
150a1bf3f78SToomas Soome
151a1bf3f78SToomas Soome value = getenv(name);
152a1bf3f78SToomas Soome ficlFree(name);
153a1bf3f78SToomas Soome
154a1bf3f78SToomas Soome if (value != NULL) {
155a1bf3f78SToomas Soome ficlStackPushPointer(ficlVmGetDataStack(pVM), value);
156a1bf3f78SToomas Soome ficlStackPushInteger(ficlVmGetDataStack(pVM), strlen(value));
157a1bf3f78SToomas Soome } else
158a1bf3f78SToomas Soome ficlStackPushInteger(ficlVmGetDataStack(pVM), -1);
159a1bf3f78SToomas Soome }
160a1bf3f78SToomas Soome
161a1bf3f78SToomas Soome void
ficlUnsetenv(ficlVm * pVM)162a1bf3f78SToomas Soome ficlUnsetenv(ficlVm *pVM)
163a1bf3f78SToomas Soome {
164a1bf3f78SToomas Soome char *name;
165a1bf3f78SToomas Soome char *namep;
166a1bf3f78SToomas Soome int names;
167a1bf3f78SToomas Soome
168a1bf3f78SToomas Soome FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 2, 0);
169a1bf3f78SToomas Soome
170a1bf3f78SToomas Soome names = ficlStackPopInteger(ficlVmGetDataStack(pVM));
171a1bf3f78SToomas Soome namep = (char *)ficlStackPopPointer(ficlVmGetDataStack(pVM));
172a1bf3f78SToomas Soome
173a1bf3f78SToomas Soome name = (char *)ficlMalloc(names+1);
174a1bf3f78SToomas Soome if (!name)
175a1bf3f78SToomas Soome ficlVmThrowError(pVM, "Error: out of memory");
176a1bf3f78SToomas Soome strncpy(name, namep, names);
177a1bf3f78SToomas Soome name[names] = '\0';
178a1bf3f78SToomas Soome
179a1bf3f78SToomas Soome unsetenv(name);
180a1bf3f78SToomas Soome ficlFree(name);
181a1bf3f78SToomas Soome }
182a1bf3f78SToomas Soome
183a1bf3f78SToomas Soome void
ficlCopyin(ficlVm * pVM)184a1bf3f78SToomas Soome ficlCopyin(ficlVm *pVM)
185a1bf3f78SToomas Soome {
186*e09118e4SToomas Soome #ifdef _STANDALONE
187a1bf3f78SToomas Soome void* src;
188a1bf3f78SToomas Soome vm_offset_t dest;
189a1bf3f78SToomas Soome size_t len;
190a1bf3f78SToomas Soome #endif
191a1bf3f78SToomas Soome
192a1bf3f78SToomas Soome FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 3, 0);
193a1bf3f78SToomas Soome
194*e09118e4SToomas Soome #ifdef _STANDALONE
195a1bf3f78SToomas Soome len = ficlStackPopInteger(ficlVmGetDataStack(pVM));
196a1bf3f78SToomas Soome dest = ficlStackPopInteger(ficlVmGetDataStack(pVM));
197a1bf3f78SToomas Soome src = ficlStackPopPointer(ficlVmGetDataStack(pVM));
198a1bf3f78SToomas Soome archsw.arch_copyin(src, dest, len);
199a1bf3f78SToomas Soome #else
200a1bf3f78SToomas Soome (void) ficlStackPopInteger(ficlVmGetDataStack(pVM));
201a1bf3f78SToomas Soome (void) ficlStackPopInteger(ficlVmGetDataStack(pVM));
202a1bf3f78SToomas Soome (void) ficlStackPopPointer(ficlVmGetDataStack(pVM));
203a1bf3f78SToomas Soome #endif
204a1bf3f78SToomas Soome }
205a1bf3f78SToomas Soome
206a1bf3f78SToomas Soome void
ficlCopyout(ficlVm * pVM)207a1bf3f78SToomas Soome ficlCopyout(ficlVm *pVM)
208a1bf3f78SToomas Soome {
209*e09118e4SToomas Soome #ifdef _STANDALONE
210a1bf3f78SToomas Soome void* dest;
211a1bf3f78SToomas Soome vm_offset_t src;
212a1bf3f78SToomas Soome size_t len;
213a1bf3f78SToomas Soome #endif
214a1bf3f78SToomas Soome
215a1bf3f78SToomas Soome FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 3, 0);
216a1bf3f78SToomas Soome
217*e09118e4SToomas Soome #ifdef _STANDALONE
218a1bf3f78SToomas Soome len = ficlStackPopInteger(ficlVmGetDataStack(pVM));
219a1bf3f78SToomas Soome dest = ficlStackPopPointer(ficlVmGetDataStack(pVM));
220a1bf3f78SToomas Soome src = ficlStackPopInteger(ficlVmGetDataStack(pVM));
221a1bf3f78SToomas Soome archsw.arch_copyout(src, dest, len);
222a1bf3f78SToomas Soome #else
223a1bf3f78SToomas Soome (void) ficlStackPopInteger(ficlVmGetDataStack(pVM));
224a1bf3f78SToomas Soome (void) ficlStackPopPointer(ficlVmGetDataStack(pVM));
225a1bf3f78SToomas Soome (void) ficlStackPopInteger(ficlVmGetDataStack(pVM));
226a1bf3f78SToomas Soome #endif
227a1bf3f78SToomas Soome }
228a1bf3f78SToomas Soome
229a1bf3f78SToomas Soome void
ficlFindfile(ficlVm * pVM)230a1bf3f78SToomas Soome ficlFindfile(ficlVm *pVM)
231a1bf3f78SToomas Soome {
232*e09118e4SToomas Soome #ifdef _STANDALONE
233a1bf3f78SToomas Soome char *name, *type;
234a1bf3f78SToomas Soome char *namep, *typep;
235a1bf3f78SToomas Soome int names, types;
236a1bf3f78SToomas Soome #endif
237a1bf3f78SToomas Soome struct preloaded_file *fp;
238a1bf3f78SToomas Soome
239a1bf3f78SToomas Soome FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 4, 1);
240a1bf3f78SToomas Soome
241*e09118e4SToomas Soome #ifdef _STANDALONE
242a1bf3f78SToomas Soome types = ficlStackPopInteger(ficlVmGetDataStack(pVM));
243a1bf3f78SToomas Soome typep = (char *)ficlStackPopPointer(ficlVmGetDataStack(pVM));
244a1bf3f78SToomas Soome names = ficlStackPopInteger(ficlVmGetDataStack(pVM));
245a1bf3f78SToomas Soome namep = (char *)ficlStackPopPointer(ficlVmGetDataStack(pVM));
246a1bf3f78SToomas Soome
247a1bf3f78SToomas Soome name = (char *)ficlMalloc(names+1);
248a1bf3f78SToomas Soome if (!name)
249a1bf3f78SToomas Soome ficlVmThrowError(pVM, "Error: out of memory");
250a1bf3f78SToomas Soome strncpy(name, namep, names);
251a1bf3f78SToomas Soome name[names] = '\0';
252a1bf3f78SToomas Soome type = (char *)ficlMalloc(types+1);
253a1bf3f78SToomas Soome if (!type)
254a1bf3f78SToomas Soome ficlVmThrowError(pVM, "Error: out of memory");
255a1bf3f78SToomas Soome strncpy(type, typep, types);
256a1bf3f78SToomas Soome type[types] = '\0';
257a1bf3f78SToomas Soome
258a1bf3f78SToomas Soome fp = file_findfile(name, type);
259a1bf3f78SToomas Soome #else
260a1bf3f78SToomas Soome (void) ficlStackPopInteger(ficlVmGetDataStack(pVM));
261a1bf3f78SToomas Soome (void) ficlStackPopPointer(ficlVmGetDataStack(pVM));
262a1bf3f78SToomas Soome (void) ficlStackPopInteger(ficlVmGetDataStack(pVM));
263a1bf3f78SToomas Soome (void) ficlStackPopPointer(ficlVmGetDataStack(pVM));
264a1bf3f78SToomas Soome
265a1bf3f78SToomas Soome fp = NULL;
266a1bf3f78SToomas Soome #endif
267a1bf3f78SToomas Soome ficlStackPushPointer(ficlVmGetDataStack(pVM), fp);
268a1bf3f78SToomas Soome }
269a1bf3f78SToomas Soome
270a1bf3f78SToomas Soome void
ficlCcall(ficlVm * pVM)271a1bf3f78SToomas Soome ficlCcall(ficlVm *pVM)
272a1bf3f78SToomas Soome {
273a1bf3f78SToomas Soome int (*func)(int, ...);
274a1bf3f78SToomas Soome int result, p[10];
275a1bf3f78SToomas Soome int nparam, i;
276a1bf3f78SToomas Soome
277a1bf3f78SToomas Soome FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 2, 0);
278a1bf3f78SToomas Soome
279a1bf3f78SToomas Soome func = (int (*)(int, ...))ficlStackPopPointer(ficlVmGetDataStack(pVM));
280a1bf3f78SToomas Soome nparam = ficlStackPopInteger(ficlVmGetDataStack(pVM));
281a1bf3f78SToomas Soome
282a1bf3f78SToomas Soome FICL_STACK_CHECK(ficlVmGetDataStack(pVM), nparam, 1);
283a1bf3f78SToomas Soome
284a1bf3f78SToomas Soome for (i = 0; i < nparam; i++)
285a1bf3f78SToomas Soome p[i] = ficlStackPopInteger(ficlVmGetDataStack(pVM));
286a1bf3f78SToomas Soome
287a1bf3f78SToomas Soome result = func(p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8],
288a1bf3f78SToomas Soome p[9]);
289a1bf3f78SToomas Soome
290a1bf3f78SToomas Soome ficlStackPushInteger(ficlVmGetDataStack(pVM), result);
291a1bf3f78SToomas Soome }
292a1bf3f78SToomas Soome
293065446baSToomas Soome void
ficlUuidFromString(ficlVm * pVM)294065446baSToomas Soome ficlUuidFromString(ficlVm *pVM)
295065446baSToomas Soome {
296065446baSToomas Soome char *uuid;
297065446baSToomas Soome char *uuid_ptr;
298065446baSToomas Soome int uuid_size;
299065446baSToomas Soome uuid_t *u;
300*e09118e4SToomas Soome #ifdef _STANDALONE
301065446baSToomas Soome uint32_t status;
302065446baSToomas Soome #else
303065446baSToomas Soome int status;
304065446baSToomas Soome #endif
305065446baSToomas Soome
306065446baSToomas Soome FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 2, 0);
307065446baSToomas Soome
308065446baSToomas Soome uuid_size = ficlStackPopInteger(ficlVmGetDataStack(pVM));
309065446baSToomas Soome uuid_ptr = ficlStackPopPointer(ficlVmGetDataStack(pVM));
310065446baSToomas Soome
311065446baSToomas Soome uuid = ficlMalloc(uuid_size + 1);
312065446baSToomas Soome if (!uuid)
313065446baSToomas Soome ficlVmThrowError(pVM, "Error: out of memory");
314065446baSToomas Soome (void) memcpy(uuid, uuid_ptr, uuid_size);
315065446baSToomas Soome uuid[uuid_size] = '\0';
316065446baSToomas Soome
317065446baSToomas Soome u = ficlMalloc(sizeof (*u));
318*e09118e4SToomas Soome #ifdef _STANDALONE
319065446baSToomas Soome uuid_from_string(uuid, u, &status);
320065446baSToomas Soome ficlFree(uuid);
321065446baSToomas Soome if (status != uuid_s_ok) {
322065446baSToomas Soome ficlFree(u);
323065446baSToomas Soome u = NULL;
324065446baSToomas Soome }
325065446baSToomas Soome #else
326065446baSToomas Soome status = uuid_parse(uuid, *u);
327065446baSToomas Soome ficlFree(uuid);
328065446baSToomas Soome if (status != 0) {
329065446baSToomas Soome ficlFree(u);
330065446baSToomas Soome u = NULL;
331065446baSToomas Soome }
332065446baSToomas Soome #endif
333065446baSToomas Soome ficlStackPushPointer(ficlVmGetDataStack(pVM), u);
334065446baSToomas Soome }
335065446baSToomas Soome
336065446baSToomas Soome void
ficlUuidToString(ficlVm * pVM)337065446baSToomas Soome ficlUuidToString(ficlVm *pVM)
338065446baSToomas Soome {
339065446baSToomas Soome char *uuid;
340065446baSToomas Soome uuid_t *u;
341*e09118e4SToomas Soome #ifdef _STANDALONE
342065446baSToomas Soome uint32_t status;
343065446baSToomas Soome #endif
344065446baSToomas Soome
345065446baSToomas Soome FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 1, 0);
346065446baSToomas Soome
347065446baSToomas Soome u = ficlStackPopPointer(ficlVmGetDataStack(pVM));
348*e09118e4SToomas Soome #ifdef _STANDALONE
349065446baSToomas Soome uuid_to_string(u, &uuid, &status);
350065446baSToomas Soome if (status == uuid_s_ok) {
351065446baSToomas Soome ficlStackPushPointer(ficlVmGetDataStack(pVM), uuid);
352065446baSToomas Soome ficlStackPushInteger(ficlVmGetDataStack(pVM), strlen(uuid));
353065446baSToomas Soome } else
354065446baSToomas Soome #else
355065446baSToomas Soome uuid = ficlMalloc(UUID_PRINTABLE_STRING_LENGTH);
356065446baSToomas Soome if (uuid != NULL) {
357065446baSToomas Soome uuid_unparse(*u, uuid);
358065446baSToomas Soome ficlStackPushPointer(ficlVmGetDataStack(pVM), uuid);
359065446baSToomas Soome ficlStackPushInteger(ficlVmGetDataStack(pVM), strlen(uuid));
360065446baSToomas Soome } else
361065446baSToomas Soome #endif
362065446baSToomas Soome ficlStackPushInteger(ficlVmGetDataStack(pVM), -1);
363065446baSToomas Soome }
364065446baSToomas Soome
365a1bf3f78SToomas Soome /*
366a1bf3f78SToomas Soome * f i c l E x e c F D
367a1bf3f78SToomas Soome * reads in text from file fd and passes it to ficlExec()
368a1bf3f78SToomas Soome * returns FICL_VM_STATUS_OUT_OF_TEXT on success or the ficlExec() error
369a1bf3f78SToomas Soome * code on failure.
370a1bf3f78SToomas Soome */
371a1bf3f78SToomas Soome #define nLINEBUF 256
372a1bf3f78SToomas Soome int
ficlExecFD(ficlVm * pVM,int fd)373a1bf3f78SToomas Soome ficlExecFD(ficlVm *pVM, int fd)
374a1bf3f78SToomas Soome {
375a1bf3f78SToomas Soome char cp[nLINEBUF];
376a1bf3f78SToomas Soome int nLine = 0, rval = FICL_VM_STATUS_OUT_OF_TEXT;
377a1bf3f78SToomas Soome char ch;
378a1bf3f78SToomas Soome ficlCell id;
379a1bf3f78SToomas Soome ficlString s;
380a1bf3f78SToomas Soome
381a1bf3f78SToomas Soome id = pVM->sourceId;
382a1bf3f78SToomas Soome pVM->sourceId.i = fd+1; /* in loader we can get 0, there is no stdin */
383a1bf3f78SToomas Soome
384a1bf3f78SToomas Soome /* feed each line to ficlExec */
385a1bf3f78SToomas Soome while (1) {
386a1bf3f78SToomas Soome int status, i;
387a1bf3f78SToomas Soome
388a1bf3f78SToomas Soome i = 0;
389a1bf3f78SToomas Soome while ((status = read(fd, &ch, 1)) > 0 && ch != '\n')
390a1bf3f78SToomas Soome cp[i++] = ch;
391a1bf3f78SToomas Soome nLine++;
392a1bf3f78SToomas Soome if (!i) {
393a1bf3f78SToomas Soome if (status < 1)
394a1bf3f78SToomas Soome break;
395a1bf3f78SToomas Soome continue;
396a1bf3f78SToomas Soome }
397a1bf3f78SToomas Soome if (cp[i] == '\n')
398a1bf3f78SToomas Soome cp[i] = '\0';
399a1bf3f78SToomas Soome
400a1bf3f78SToomas Soome FICL_STRING_SET_POINTER(s, cp);
401a1bf3f78SToomas Soome FICL_STRING_SET_LENGTH(s, i);
402a1bf3f78SToomas Soome
403a1bf3f78SToomas Soome rval = ficlVmExecuteString(pVM, s);
404a1bf3f78SToomas Soome if (rval != FICL_VM_STATUS_QUIT &&
405a1bf3f78SToomas Soome rval != FICL_VM_STATUS_USER_EXIT &&
406a1bf3f78SToomas Soome rval != FICL_VM_STATUS_OUT_OF_TEXT) {
407a1bf3f78SToomas Soome pVM->sourceId = id;
408a1bf3f78SToomas Soome (void) ficlVmEvaluate(pVM, "");
409a1bf3f78SToomas Soome return (rval);
410a1bf3f78SToomas Soome }
411a1bf3f78SToomas Soome }
412a1bf3f78SToomas Soome pVM->sourceId = id;
413a1bf3f78SToomas Soome
414a1bf3f78SToomas Soome /*
415a1bf3f78SToomas Soome * Pass an empty line with SOURCE-ID == -1 to flush
416a1bf3f78SToomas Soome * any pending REFILLs (as required by FILE wordset)
417a1bf3f78SToomas Soome */
418a1bf3f78SToomas Soome (void) ficlVmEvaluate(pVM, "");
419a1bf3f78SToomas Soome
420a1bf3f78SToomas Soome if (rval == FICL_VM_STATUS_USER_EXIT)
421a1bf3f78SToomas Soome ficlVmThrow(pVM, FICL_VM_STATUS_USER_EXIT);
422a1bf3f78SToomas Soome
423a1bf3f78SToomas Soome return (rval);
424a1bf3f78SToomas Soome }
425a1bf3f78SToomas Soome
displayCellNoPad(ficlVm * pVM)426a1bf3f78SToomas Soome static void displayCellNoPad(ficlVm *pVM)
427a1bf3f78SToomas Soome {
428a1bf3f78SToomas Soome ficlCell c;
429a1bf3f78SToomas Soome FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 1, 0);
430a1bf3f78SToomas Soome
431a1bf3f78SToomas Soome c = ficlStackPop(ficlVmGetDataStack(pVM));
432a1bf3f78SToomas Soome ficlLtoa((c).i, pVM->pad, pVM->base);
433a1bf3f78SToomas Soome ficlVmTextOut(pVM, pVM->pad);
434a1bf3f78SToomas Soome }
435a1bf3f78SToomas Soome
436a1bf3f78SToomas Soome /*
437a1bf3f78SToomas Soome * isdir? - Return whether an fd corresponds to a directory.
438a1bf3f78SToomas Soome *
439a1bf3f78SToomas Soome * isdir? ( fd -- bool )
440a1bf3f78SToomas Soome */
441a1bf3f78SToomas Soome static void
isdirQuestion(ficlVm * pVM)442a1bf3f78SToomas Soome isdirQuestion(ficlVm *pVM)
443a1bf3f78SToomas Soome {
444a1bf3f78SToomas Soome struct stat sb;
445a1bf3f78SToomas Soome ficlInteger flag;
446a1bf3f78SToomas Soome int fd;
447a1bf3f78SToomas Soome
448a1bf3f78SToomas Soome FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 1, 1);
449a1bf3f78SToomas Soome
450a1bf3f78SToomas Soome fd = ficlStackPopInteger(ficlVmGetDataStack(pVM));
451a1bf3f78SToomas Soome flag = FICL_FALSE;
452a1bf3f78SToomas Soome do {
453a1bf3f78SToomas Soome if (fd < 0)
454a1bf3f78SToomas Soome break;
455a1bf3f78SToomas Soome if (fstat(fd, &sb) < 0)
456a1bf3f78SToomas Soome break;
457a1bf3f78SToomas Soome if (!S_ISDIR(sb.st_mode))
458a1bf3f78SToomas Soome break;
459a1bf3f78SToomas Soome flag = FICL_TRUE;
460a1bf3f78SToomas Soome } while (0);
461a1bf3f78SToomas Soome ficlStackPushInteger(ficlVmGetDataStack(pVM), flag);
462a1bf3f78SToomas Soome }
463a1bf3f78SToomas Soome
464a1bf3f78SToomas Soome /*
465a1bf3f78SToomas Soome * fopen - open a file and return new fd on stack.
466a1bf3f78SToomas Soome *
467a1bf3f78SToomas Soome * fopen ( ptr count mode -- fd )
468a1bf3f78SToomas Soome */
469a1bf3f78SToomas Soome extern char *get_dev(const char *);
470a1bf3f78SToomas Soome
471a1bf3f78SToomas Soome static void
pfopen(ficlVm * pVM)472a1bf3f78SToomas Soome pfopen(ficlVm *pVM)
473a1bf3f78SToomas Soome {
474a1bf3f78SToomas Soome int mode, fd, count;
475a1bf3f78SToomas Soome char *ptr, *name;
476*e09118e4SToomas Soome #ifndef _STANDALONE
477a1bf3f78SToomas Soome char *tmp;
478a1bf3f78SToomas Soome #endif
479a1bf3f78SToomas Soome
480a1bf3f78SToomas Soome FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 3, 1);
481a1bf3f78SToomas Soome
482a1bf3f78SToomas Soome mode = ficlStackPopInteger(ficlVmGetDataStack(pVM)); /* get mode */
483a1bf3f78SToomas Soome count = ficlStackPopInteger(ficlVmGetDataStack(pVM)); /* get count */
484a1bf3f78SToomas Soome ptr = ficlStackPopPointer(ficlVmGetDataStack(pVM)); /* get ptr */
485a1bf3f78SToomas Soome
486a1bf3f78SToomas Soome if ((count < 0) || (ptr == NULL)) {
487a1bf3f78SToomas Soome ficlStackPushInteger(ficlVmGetDataStack(pVM), -1);
488a1bf3f78SToomas Soome return;
489a1bf3f78SToomas Soome }
490a1bf3f78SToomas Soome
491a1bf3f78SToomas Soome /* ensure that the string is null terminated */
492a1bf3f78SToomas Soome name = (char *)malloc(count+1);
493a1bf3f78SToomas Soome bcopy(ptr, name, count);
494a1bf3f78SToomas Soome name[count] = 0;
495*e09118e4SToomas Soome #ifndef _STANDALONE
496a1bf3f78SToomas Soome tmp = get_dev(name);
497a1bf3f78SToomas Soome free(name);
498a1bf3f78SToomas Soome name = tmp;
499a1bf3f78SToomas Soome #endif
500a1bf3f78SToomas Soome
501a1bf3f78SToomas Soome /* open the file */
502a1bf3f78SToomas Soome fd = open(name, mode);
503a1bf3f78SToomas Soome free(name);
504a1bf3f78SToomas Soome ficlStackPushInteger(ficlVmGetDataStack(pVM), fd);
505a1bf3f78SToomas Soome }
506a1bf3f78SToomas Soome
507a1bf3f78SToomas Soome /*
508a1bf3f78SToomas Soome * fclose - close a file who's fd is on stack.
509a1bf3f78SToomas Soome * fclose ( fd -- )
510a1bf3f78SToomas Soome */
511a1bf3f78SToomas Soome static void
pfclose(ficlVm * pVM)512a1bf3f78SToomas Soome pfclose(ficlVm *pVM)
513a1bf3f78SToomas Soome {
514a1bf3f78SToomas Soome int fd;
515a1bf3f78SToomas Soome
516a1bf3f78SToomas Soome FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 1, 0);
517a1bf3f78SToomas Soome
518a1bf3f78SToomas Soome fd = ficlStackPopInteger(ficlVmGetDataStack(pVM)); /* get fd */
519a1bf3f78SToomas Soome if (fd != -1)
520a1bf3f78SToomas Soome close(fd);
521a1bf3f78SToomas Soome }
522a1bf3f78SToomas Soome
523a1bf3f78SToomas Soome /*
524a1bf3f78SToomas Soome * fread - read file contents
525a1bf3f78SToomas Soome * fread ( fd buf nbytes -- nread )
526a1bf3f78SToomas Soome */
527a1bf3f78SToomas Soome static void
pfread(ficlVm * pVM)528a1bf3f78SToomas Soome pfread(ficlVm *pVM)
529a1bf3f78SToomas Soome {
530a1bf3f78SToomas Soome int fd, len;
531a1bf3f78SToomas Soome char *buf;
532a1bf3f78SToomas Soome
533a1bf3f78SToomas Soome FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 3, 1);
534a1bf3f78SToomas Soome
535a1bf3f78SToomas Soome len = ficlStackPopInteger(ficlVmGetDataStack(pVM));
536a1bf3f78SToomas Soome buf = ficlStackPopPointer(ficlVmGetDataStack(pVM)); /* get buffer */
537a1bf3f78SToomas Soome fd = ficlStackPopInteger(ficlVmGetDataStack(pVM)); /* get fd */
538a1bf3f78SToomas Soome if (len > 0 && buf && fd != -1)
539a1bf3f78SToomas Soome ficlStackPushInteger(ficlVmGetDataStack(pVM),
540a1bf3f78SToomas Soome read(fd, buf, len));
541a1bf3f78SToomas Soome else
542a1bf3f78SToomas Soome ficlStackPushInteger(ficlVmGetDataStack(pVM), -1);
543a1bf3f78SToomas Soome }
544a1bf3f78SToomas Soome
545a1bf3f78SToomas Soome /*
546a1bf3f78SToomas Soome * fopendir - open directory
547a1bf3f78SToomas Soome *
548a1bf3f78SToomas Soome * fopendir ( addr len -- ptr TRUE | FALSE )
549a1bf3f78SToomas Soome */
pfopendir(ficlVm * pVM)550a1bf3f78SToomas Soome static void pfopendir(ficlVm *pVM)
551a1bf3f78SToomas Soome {
552*e09118e4SToomas Soome #ifndef _STANDALONE
553a1bf3f78SToomas Soome DIR *dir;
554a1bf3f78SToomas Soome char *tmp;
555a1bf3f78SToomas Soome #else
556a1bf3f78SToomas Soome struct stat sb;
557a1bf3f78SToomas Soome int fd;
558a1bf3f78SToomas Soome #endif
559a1bf3f78SToomas Soome int count;
560a1bf3f78SToomas Soome char *ptr, *name;
561a1bf3f78SToomas Soome ficlInteger flag = FICL_FALSE;
562a1bf3f78SToomas Soome
563a1bf3f78SToomas Soome FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 2, 1);
564a1bf3f78SToomas Soome
565a1bf3f78SToomas Soome count = ficlStackPopInteger(ficlVmGetDataStack(pVM));
566a1bf3f78SToomas Soome ptr = ficlStackPopPointer(ficlVmGetDataStack(pVM)); /* get ptr */
567a1bf3f78SToomas Soome
568a1bf3f78SToomas Soome if ((count < 0) || (ptr == NULL)) {
569a1bf3f78SToomas Soome ficlStackPushInteger(ficlVmGetDataStack(pVM), -1);
570a1bf3f78SToomas Soome return;
571a1bf3f78SToomas Soome }
572a1bf3f78SToomas Soome /* ensure that the string is null terminated */
573a1bf3f78SToomas Soome name = (char *)malloc(count+1);
574a1bf3f78SToomas Soome bcopy(ptr, name, count);
575a1bf3f78SToomas Soome name[count] = 0;
576*e09118e4SToomas Soome #ifndef _STANDALONE
577a1bf3f78SToomas Soome tmp = get_dev(name);
578a1bf3f78SToomas Soome free(name);
579a1bf3f78SToomas Soome name = tmp;
580a1bf3f78SToomas Soome #else
581a1bf3f78SToomas Soome fd = open(name, O_RDONLY);
582a1bf3f78SToomas Soome free(name);
583a1bf3f78SToomas Soome do {
584a1bf3f78SToomas Soome if (fd < 0)
585a1bf3f78SToomas Soome break;
586a1bf3f78SToomas Soome if (fstat(fd, &sb) < 0)
587a1bf3f78SToomas Soome break;
588a1bf3f78SToomas Soome if (!S_ISDIR(sb.st_mode))
589a1bf3f78SToomas Soome break;
590a1bf3f78SToomas Soome flag = FICL_TRUE;
591a1bf3f78SToomas Soome ficlStackPushInteger(ficlVmGetDataStack(pVM), fd);
592a1bf3f78SToomas Soome ficlStackPushInteger(ficlVmGetDataStack(pVM), flag);
593a1bf3f78SToomas Soome return;
594a1bf3f78SToomas Soome } while (0);
595a1bf3f78SToomas Soome
596a1bf3f78SToomas Soome if (fd >= 0)
597a1bf3f78SToomas Soome close(fd);
598a1bf3f78SToomas Soome
599a1bf3f78SToomas Soome ficlStackPushInteger(ficlVmGetDataStack(pVM), flag);
600a1bf3f78SToomas Soome return;
601a1bf3f78SToomas Soome #endif
602*e09118e4SToomas Soome #ifndef _STANDALONE
603a1bf3f78SToomas Soome dir = opendir(name);
604a1bf3f78SToomas Soome if (dir == NULL) {
605a1bf3f78SToomas Soome ficlStackPushInteger(ficlVmGetDataStack(pVM), flag);
606a1bf3f78SToomas Soome return;
607a1bf3f78SToomas Soome } else
608a1bf3f78SToomas Soome flag = FICL_TRUE;
609a1bf3f78SToomas Soome
610a1bf3f78SToomas Soome ficlStackPushPointer(ficlVmGetDataStack(pVM), dir);
611a1bf3f78SToomas Soome ficlStackPushInteger(ficlVmGetDataStack(pVM), flag);
612a1bf3f78SToomas Soome #endif
613a1bf3f78SToomas Soome }
614a1bf3f78SToomas Soome
615a1bf3f78SToomas Soome /*
616a1bf3f78SToomas Soome * freaddir - read directory contents
617a1bf3f78SToomas Soome * freaddir ( fd -- ptr len TRUE | FALSE )
618a1bf3f78SToomas Soome */
619a1bf3f78SToomas Soome static void
pfreaddir(ficlVm * pVM)620a1bf3f78SToomas Soome pfreaddir(ficlVm *pVM)
621a1bf3f78SToomas Soome {
622*e09118e4SToomas Soome #ifndef _STANDALONE
623a1bf3f78SToomas Soome static DIR *dir = NULL;
624a1bf3f78SToomas Soome #else
625a1bf3f78SToomas Soome int fd;
626a1bf3f78SToomas Soome #endif
627a1bf3f78SToomas Soome struct dirent *d = NULL;
628a1bf3f78SToomas Soome
629a1bf3f78SToomas Soome FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 1, 3);
630a1bf3f78SToomas Soome /*
631a1bf3f78SToomas Soome * libstand readdir does not always return . nor .. so filter
632a1bf3f78SToomas Soome * them out to have consistent behaviour.
633a1bf3f78SToomas Soome */
634*e09118e4SToomas Soome #ifndef _STANDALONE
635a1bf3f78SToomas Soome dir = ficlStackPopPointer(ficlVmGetDataStack(pVM));
636a1bf3f78SToomas Soome if (dir != NULL)
637a1bf3f78SToomas Soome do {
638a1bf3f78SToomas Soome d = readdir(dir);
639a1bf3f78SToomas Soome if (d != NULL && strcmp(d->d_name, ".") == 0)
640a1bf3f78SToomas Soome continue;
641a1bf3f78SToomas Soome if (d != NULL && strcmp(d->d_name, "..") == 0)
642a1bf3f78SToomas Soome continue;
643a1bf3f78SToomas Soome break;
644a1bf3f78SToomas Soome } while (d != NULL);
645a1bf3f78SToomas Soome #else
646a1bf3f78SToomas Soome fd = ficlStackPopInteger(ficlVmGetDataStack(pVM));
647a1bf3f78SToomas Soome if (fd != -1)
648a1bf3f78SToomas Soome do {
649a1bf3f78SToomas Soome d = readdirfd(fd);
650a1bf3f78SToomas Soome if (d != NULL && strcmp(d->d_name, ".") == 0)
651a1bf3f78SToomas Soome continue;
652a1bf3f78SToomas Soome if (d != NULL && strcmp(d->d_name, "..") == 0)
653a1bf3f78SToomas Soome continue;
654a1bf3f78SToomas Soome break;
655a1bf3f78SToomas Soome } while (d != NULL);
656a1bf3f78SToomas Soome #endif
657a1bf3f78SToomas Soome if (d != NULL) {
658a1bf3f78SToomas Soome ficlStackPushPointer(ficlVmGetDataStack(pVM), d->d_name);
659a1bf3f78SToomas Soome ficlStackPushInteger(ficlVmGetDataStack(pVM),
660a1bf3f78SToomas Soome strlen(d->d_name));
661a1bf3f78SToomas Soome ficlStackPushInteger(ficlVmGetDataStack(pVM), FICL_TRUE);
662a1bf3f78SToomas Soome } else {
663a1bf3f78SToomas Soome ficlStackPushInteger(ficlVmGetDataStack(pVM), FICL_FALSE);
664a1bf3f78SToomas Soome }
665a1bf3f78SToomas Soome }
666a1bf3f78SToomas Soome
667a1bf3f78SToomas Soome /*
668a1bf3f78SToomas Soome * fclosedir - close a dir on stack.
669a1bf3f78SToomas Soome *
670a1bf3f78SToomas Soome * fclosedir ( fd -- )
671a1bf3f78SToomas Soome */
672a1bf3f78SToomas Soome static void
pfclosedir(ficlVm * pVM)673a1bf3f78SToomas Soome pfclosedir(ficlVm *pVM)
674a1bf3f78SToomas Soome {
675*e09118e4SToomas Soome #ifndef _STANDALONE
676a1bf3f78SToomas Soome DIR *dir;
677a1bf3f78SToomas Soome #else
678a1bf3f78SToomas Soome int fd;
679a1bf3f78SToomas Soome #endif
680a1bf3f78SToomas Soome
681a1bf3f78SToomas Soome FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 1, 0);
682a1bf3f78SToomas Soome
683*e09118e4SToomas Soome #ifndef _STANDALONE
684a1bf3f78SToomas Soome dir = ficlStackPopPointer(ficlVmGetDataStack(pVM)); /* get dir */
685a1bf3f78SToomas Soome if (dir != NULL)
686a1bf3f78SToomas Soome closedir(dir);
687a1bf3f78SToomas Soome #else
688a1bf3f78SToomas Soome fd = ficlStackPopInteger(ficlVmGetDataStack(pVM)); /* get fd */
689a1bf3f78SToomas Soome if (fd != -1)
690a1bf3f78SToomas Soome close(fd);
691a1bf3f78SToomas Soome #endif
692a1bf3f78SToomas Soome }
693a1bf3f78SToomas Soome
694a1bf3f78SToomas Soome /*
695a1bf3f78SToomas Soome * fload - interpret file contents
696a1bf3f78SToomas Soome *
697a1bf3f78SToomas Soome * fload ( fd -- )
698a1bf3f78SToomas Soome */
pfload(ficlVm * pVM)699a1bf3f78SToomas Soome static void pfload(ficlVm *pVM)
700a1bf3f78SToomas Soome {
701a1bf3f78SToomas Soome int fd;
702a1bf3f78SToomas Soome
703a1bf3f78SToomas Soome FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 1, 0);
704a1bf3f78SToomas Soome
705a1bf3f78SToomas Soome fd = ficlStackPopInteger(ficlVmGetDataStack(pVM)); /* get fd */
706a1bf3f78SToomas Soome if (fd != -1)
707a1bf3f78SToomas Soome ficlExecFD(pVM, fd);
708a1bf3f78SToomas Soome }
709a1bf3f78SToomas Soome
710a1bf3f78SToomas Soome /*
711a1bf3f78SToomas Soome * fwrite - write file contents
712a1bf3f78SToomas Soome *
713a1bf3f78SToomas Soome * fwrite ( fd buf nbytes -- nwritten )
714a1bf3f78SToomas Soome */
715a1bf3f78SToomas Soome static void
pfwrite(ficlVm * pVM)716a1bf3f78SToomas Soome pfwrite(ficlVm *pVM)
717a1bf3f78SToomas Soome {
718a1bf3f78SToomas Soome int fd, len;
719a1bf3f78SToomas Soome char *buf;
720a1bf3f78SToomas Soome
721a1bf3f78SToomas Soome FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 3, 1);
722a1bf3f78SToomas Soome
723a1bf3f78SToomas Soome len = ficlStackPopInteger(ficlVmGetDataStack(pVM)); /* bytes to read */
724a1bf3f78SToomas Soome buf = ficlStackPopPointer(ficlVmGetDataStack(pVM)); /* get buffer */
725a1bf3f78SToomas Soome fd = ficlStackPopInteger(ficlVmGetDataStack(pVM)); /* get fd */
726a1bf3f78SToomas Soome if (len > 0 && buf && fd != -1)
727a1bf3f78SToomas Soome ficlStackPushInteger(ficlVmGetDataStack(pVM),
728a1bf3f78SToomas Soome write(fd, buf, len));
729a1bf3f78SToomas Soome else
730a1bf3f78SToomas Soome ficlStackPushInteger(ficlVmGetDataStack(pVM), -1);
731a1bf3f78SToomas Soome }
732a1bf3f78SToomas Soome
733a1bf3f78SToomas Soome /*
734a1bf3f78SToomas Soome * fseek - seek to a new position in a file
735a1bf3f78SToomas Soome *
736a1bf3f78SToomas Soome * fseek ( fd ofs whence -- pos )
737a1bf3f78SToomas Soome */
738a1bf3f78SToomas Soome static void
pfseek(ficlVm * pVM)739a1bf3f78SToomas Soome pfseek(ficlVm *pVM)
740a1bf3f78SToomas Soome {
741a1bf3f78SToomas Soome int fd, pos, whence;
742a1bf3f78SToomas Soome
743a1bf3f78SToomas Soome FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 3, 1);
744a1bf3f78SToomas Soome
745a1bf3f78SToomas Soome whence = ficlStackPopInteger(ficlVmGetDataStack(pVM));
746a1bf3f78SToomas Soome pos = ficlStackPopInteger(ficlVmGetDataStack(pVM));
747a1bf3f78SToomas Soome fd = ficlStackPopInteger(ficlVmGetDataStack(pVM));
748a1bf3f78SToomas Soome ficlStackPushInteger(ficlVmGetDataStack(pVM), lseek(fd, pos, whence));
749a1bf3f78SToomas Soome }
750a1bf3f78SToomas Soome
751a1bf3f78SToomas Soome /*
752a1bf3f78SToomas Soome * key - get a character from stdin
753a1bf3f78SToomas Soome *
754a1bf3f78SToomas Soome * key ( -- char )
755a1bf3f78SToomas Soome */
756a1bf3f78SToomas Soome static void
key(ficlVm * pVM)757a1bf3f78SToomas Soome key(ficlVm *pVM)
758a1bf3f78SToomas Soome {
759a1bf3f78SToomas Soome FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 0, 1);
760a1bf3f78SToomas Soome
761a1bf3f78SToomas Soome ficlStackPushInteger(ficlVmGetDataStack(pVM), getchar());
762a1bf3f78SToomas Soome }
763a1bf3f78SToomas Soome
764a1bf3f78SToomas Soome /*
765a1bf3f78SToomas Soome * key? - check for a character from stdin (FACILITY)
766a1bf3f78SToomas Soome * key? ( -- flag )
767a1bf3f78SToomas Soome */
768a1bf3f78SToomas Soome static void
keyQuestion(ficlVm * pVM)769a1bf3f78SToomas Soome keyQuestion(ficlVm *pVM)
770a1bf3f78SToomas Soome {
771*e09118e4SToomas Soome #ifndef _STANDALONE
772a1bf3f78SToomas Soome char ch = -1;
773a1bf3f78SToomas Soome struct termios oldt;
774a1bf3f78SToomas Soome struct termios newt;
775a1bf3f78SToomas Soome #endif
776a1bf3f78SToomas Soome
777a1bf3f78SToomas Soome FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 0, 1);
778a1bf3f78SToomas Soome
779*e09118e4SToomas Soome #ifndef _STANDALONE
780a1bf3f78SToomas Soome tcgetattr(STDIN_FILENO, &oldt);
781a1bf3f78SToomas Soome newt = oldt;
782a1bf3f78SToomas Soome newt.c_lflag &= ~(ICANON | ECHO);
783a1bf3f78SToomas Soome newt.c_cc[VMIN] = 0;
784a1bf3f78SToomas Soome newt.c_cc[VTIME] = 0;
785a1bf3f78SToomas Soome tcsetattr(STDIN_FILENO, TCSANOW, &newt);
786a1bf3f78SToomas Soome ch = getchar();
787a1bf3f78SToomas Soome tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
788a1bf3f78SToomas Soome
789a1bf3f78SToomas Soome if (ch != -1)
790a1bf3f78SToomas Soome (void) ungetc(ch, stdin);
791a1bf3f78SToomas Soome
792a1bf3f78SToomas Soome ficlStackPushInteger(ficlVmGetDataStack(pVM),
793a1bf3f78SToomas Soome ch != -1? FICL_TRUE : FICL_FALSE);
794a1bf3f78SToomas Soome #else
795a1bf3f78SToomas Soome ficlStackPushInteger(ficlVmGetDataStack(pVM),
796a1bf3f78SToomas Soome ischar()? FICL_TRUE : FICL_FALSE);
797a1bf3f78SToomas Soome #endif
798a1bf3f78SToomas Soome }
799a1bf3f78SToomas Soome
800a1bf3f78SToomas Soome /*
801a1bf3f78SToomas Soome * seconds - gives number of seconds since beginning of time
802a1bf3f78SToomas Soome *
803a1bf3f78SToomas Soome * beginning of time is defined as:
804a1bf3f78SToomas Soome *
805a1bf3f78SToomas Soome * BTX - number of seconds since midnight
806a1bf3f78SToomas Soome * FreeBSD - number of seconds since Jan 1 1970
807a1bf3f78SToomas Soome *
808a1bf3f78SToomas Soome * seconds ( -- u )
809a1bf3f78SToomas Soome */
810a1bf3f78SToomas Soome static void
pseconds(ficlVm * pVM)811a1bf3f78SToomas Soome pseconds(ficlVm *pVM)
812a1bf3f78SToomas Soome {
813a1bf3f78SToomas Soome FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 0, 1);
814a1bf3f78SToomas Soome
815a1bf3f78SToomas Soome ficlStackPushUnsigned(ficlVmGetDataStack(pVM),
816a1bf3f78SToomas Soome (ficlUnsigned) time(NULL));
817a1bf3f78SToomas Soome }
818a1bf3f78SToomas Soome
819a1bf3f78SToomas Soome /*
820a1bf3f78SToomas Soome * ms - wait at least that many milliseconds (FACILITY)
821a1bf3f78SToomas Soome * ms ( u -- )
822a1bf3f78SToomas Soome */
823a1bf3f78SToomas Soome static void
ms(ficlVm * pVM)824a1bf3f78SToomas Soome ms(ficlVm *pVM)
825a1bf3f78SToomas Soome {
826a1bf3f78SToomas Soome FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 1, 0);
827a1bf3f78SToomas Soome
828*e09118e4SToomas Soome #ifndef _STANDALONE
829a1bf3f78SToomas Soome usleep(ficlStackPopUnsigned(ficlVmGetDataStack(pVM)) * 1000);
830a1bf3f78SToomas Soome #else
831a1bf3f78SToomas Soome delay(ficlStackPopUnsigned(ficlVmGetDataStack(pVM)) * 1000);
832a1bf3f78SToomas Soome #endif
833a1bf3f78SToomas Soome }
834a1bf3f78SToomas Soome
835a1bf3f78SToomas Soome /*
836a1bf3f78SToomas Soome * fkey - get a character from a file
837a1bf3f78SToomas Soome * fkey ( file -- char )
838a1bf3f78SToomas Soome */
839a1bf3f78SToomas Soome static void
fkey(ficlVm * pVM)840a1bf3f78SToomas Soome fkey(ficlVm *pVM)
841a1bf3f78SToomas Soome {
842a1bf3f78SToomas Soome int i, fd;
843a1bf3f78SToomas Soome char ch;
844a1bf3f78SToomas Soome
845a1bf3f78SToomas Soome FICL_STACK_CHECK(ficlVmGetDataStack(pVM), 1, 1);
846a1bf3f78SToomas Soome
847a1bf3f78SToomas Soome fd = ficlStackPopInteger(ficlVmGetDataStack(pVM));
848a1bf3f78SToomas Soome i = read(fd, &ch, 1);
849a1bf3f78SToomas Soome ficlStackPushInteger(ficlVmGetDataStack(pVM), i > 0 ? ch : -1);
850a1bf3f78SToomas Soome }
851a1bf3f78SToomas Soome
852a1bf3f78SToomas Soome /*
853a1bf3f78SToomas Soome * Retrieves free space remaining on the dictionary
854a1bf3f78SToomas Soome */
855a1bf3f78SToomas Soome static void
freeHeap(ficlVm * pVM)856a1bf3f78SToomas Soome freeHeap(ficlVm *pVM)
857a1bf3f78SToomas Soome {
858a1bf3f78SToomas Soome ficlStackPushInteger(ficlVmGetDataStack(pVM),
859a1bf3f78SToomas Soome ficlDictionaryCellsAvailable(ficlVmGetDictionary(pVM)));
860a1bf3f78SToomas Soome }
861a1bf3f78SToomas Soome
862a1bf3f78SToomas Soome /*
863a1bf3f78SToomas Soome * f i c l C o m p i l e P l a t f o r m
864a1bf3f78SToomas Soome * Build FreeBSD platform extensions into the system dictionary
865a1bf3f78SToomas Soome */
866a1bf3f78SToomas Soome void
ficlSystemCompilePlatform(ficlSystem * pSys)867a1bf3f78SToomas Soome ficlSystemCompilePlatform(ficlSystem *pSys)
868a1bf3f78SToomas Soome {
869a1bf3f78SToomas Soome ficlDictionary *dp = ficlSystemGetDictionary(pSys);
870a1bf3f78SToomas Soome ficlDictionary *env = ficlSystemGetEnvironment(pSys);
871*e09118e4SToomas Soome #ifdef _STANDALONE
872d5a0772bSToomas Soome ficlCompileFcn **fnpp;
873d5a0772bSToomas Soome #endif
874a1bf3f78SToomas Soome
875a1bf3f78SToomas Soome FICL_SYSTEM_ASSERT(pSys, dp);
876a1bf3f78SToomas Soome FICL_SYSTEM_ASSERT(pSys, env);
877a1bf3f78SToomas Soome
878a1bf3f78SToomas Soome ficlDictionarySetPrimitive(dp, ".#", displayCellNoPad,
879a1bf3f78SToomas Soome FICL_WORD_DEFAULT);
880a1bf3f78SToomas Soome ficlDictionarySetPrimitive(dp, "isdir?", isdirQuestion,
881a1bf3f78SToomas Soome FICL_WORD_DEFAULT);
882a1bf3f78SToomas Soome ficlDictionarySetPrimitive(dp, "fopen", pfopen, FICL_WORD_DEFAULT);
883a1bf3f78SToomas Soome ficlDictionarySetPrimitive(dp, "fclose", pfclose, FICL_WORD_DEFAULT);
884a1bf3f78SToomas Soome ficlDictionarySetPrimitive(dp, "fread", pfread, FICL_WORD_DEFAULT);
885a1bf3f78SToomas Soome ficlDictionarySetPrimitive(dp, "fopendir", pfopendir,
886a1bf3f78SToomas Soome FICL_WORD_DEFAULT);
887a1bf3f78SToomas Soome ficlDictionarySetPrimitive(dp, "freaddir", pfreaddir,
888a1bf3f78SToomas Soome FICL_WORD_DEFAULT);
889a1bf3f78SToomas Soome ficlDictionarySetPrimitive(dp, "fclosedir", pfclosedir,
890a1bf3f78SToomas Soome FICL_WORD_DEFAULT);
891a1bf3f78SToomas Soome ficlDictionarySetPrimitive(dp, "fload", pfload, FICL_WORD_DEFAULT);
892a1bf3f78SToomas Soome ficlDictionarySetPrimitive(dp, "fkey", fkey, FICL_WORD_DEFAULT);
893a1bf3f78SToomas Soome ficlDictionarySetPrimitive(dp, "fseek", pfseek, FICL_WORD_DEFAULT);
894a1bf3f78SToomas Soome ficlDictionarySetPrimitive(dp, "fwrite", pfwrite, FICL_WORD_DEFAULT);
895a1bf3f78SToomas Soome ficlDictionarySetPrimitive(dp, "key", key, FICL_WORD_DEFAULT);
896a1bf3f78SToomas Soome ficlDictionarySetPrimitive(dp, "key?", keyQuestion, FICL_WORD_DEFAULT);
897a1bf3f78SToomas Soome ficlDictionarySetPrimitive(dp, "ms", ms, FICL_WORD_DEFAULT);
898a1bf3f78SToomas Soome ficlDictionarySetPrimitive(dp, "seconds", pseconds, FICL_WORD_DEFAULT);
899a1bf3f78SToomas Soome ficlDictionarySetPrimitive(dp, "heap?", freeHeap, FICL_WORD_DEFAULT);
900a1bf3f78SToomas Soome
901a1bf3f78SToomas Soome ficlDictionarySetPrimitive(dp, "setenv", ficlSetenv, FICL_WORD_DEFAULT);
902a1bf3f78SToomas Soome ficlDictionarySetPrimitive(dp, "setenv?", ficlSetenvq,
903a1bf3f78SToomas Soome FICL_WORD_DEFAULT);
904a1bf3f78SToomas Soome ficlDictionarySetPrimitive(dp, "getenv", ficlGetenv, FICL_WORD_DEFAULT);
905a1bf3f78SToomas Soome ficlDictionarySetPrimitive(dp, "unsetenv", ficlUnsetenv,
906a1bf3f78SToomas Soome FICL_WORD_DEFAULT);
907a1bf3f78SToomas Soome ficlDictionarySetPrimitive(dp, "copyin", ficlCopyin, FICL_WORD_DEFAULT);
908a1bf3f78SToomas Soome ficlDictionarySetPrimitive(dp, "copyout", ficlCopyout,
909a1bf3f78SToomas Soome FICL_WORD_DEFAULT);
910a1bf3f78SToomas Soome ficlDictionarySetPrimitive(dp, "findfile", ficlFindfile,
911a1bf3f78SToomas Soome FICL_WORD_DEFAULT);
912a1bf3f78SToomas Soome ficlDictionarySetPrimitive(dp, "ccall", ficlCcall, FICL_WORD_DEFAULT);
913065446baSToomas Soome ficlDictionarySetPrimitive(dp, "uuid-from-string", ficlUuidFromString,
914065446baSToomas Soome FICL_WORD_DEFAULT);
915065446baSToomas Soome ficlDictionarySetPrimitive(dp, "uuid-to-string", ficlUuidToString,
916065446baSToomas Soome FICL_WORD_DEFAULT);
917*e09118e4SToomas Soome #ifdef _STANDALONE
918d5a0772bSToomas Soome /* Register words from linker set. */
919d5a0772bSToomas Soome SET_FOREACH(fnpp, Xficl_compile_set)
920d5a0772bSToomas Soome (*fnpp)(pSys);
921a1bf3f78SToomas Soome #endif
922a1bf3f78SToomas Soome
923a1bf3f78SToomas Soome #if defined(__i386__) || defined(__amd64__)
924a1bf3f78SToomas Soome ficlDictionarySetConstant(env, "arch-i386", FICL_TRUE);
925a1bf3f78SToomas Soome ficlDictionarySetConstant(env, "arch-sparc", FICL_FALSE);
926a1bf3f78SToomas Soome #endif
927a1bf3f78SToomas Soome #ifdef __sparc
928a1bf3f78SToomas Soome ficlDictionarySetConstant(env, "arch-i386", FICL_FALSE);
929a1bf3f78SToomas Soome ficlDictionarySetConstant(env, "arch-sparc", FICL_TRUE);
930a1bf3f78SToomas Soome #endif
931a1bf3f78SToomas Soome }
932