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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 */ 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 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 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 */ 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 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 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 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 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 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 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 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 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 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