161374Sdcs/*- 261374Sdcs * Copyright (c) 2000 Daniel Capo Sobral 361374Sdcs * All rights reserved. 461374Sdcs * 561374Sdcs * Redistribution and use in source and binary forms, with or without 661374Sdcs * modification, are permitted provided that the following conditions 761374Sdcs * are met: 861374Sdcs * 1. Redistributions of source code must retain the above copyright 961374Sdcs * notice, this list of conditions and the following disclaimer. 1061374Sdcs * 2. Redistributions in binary form must reproduce the above copyright 1161374Sdcs * notice, this list of conditions and the following disclaimer in the 1261374Sdcs * documentation and/or other materials provided with the distribution. 1361374Sdcs * 1461374Sdcs * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1561374Sdcs * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1661374Sdcs * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1761374Sdcs * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1861374Sdcs * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1961374Sdcs * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2061374Sdcs * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2161374Sdcs * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2261374Sdcs * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2361374Sdcs * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2461374Sdcs * SUCH DAMAGE. 2561374Sdcs * 2661374Sdcs * $FreeBSD: releng/10.3/sys/boot/ficl/loader.c 254155 2013-08-09 19:10:56Z marcel $ 2761374Sdcs */ 2861374Sdcs 2961374Sdcs/******************************************************************* 3061374Sdcs** l o a d e r . c 3161374Sdcs** Additional FICL words designed for FreeBSD's loader 3261374Sdcs** 3361374Sdcs*******************************************************************/ 3461374Sdcs 35102215Sscottl#ifdef TESTMAIN 36253862Smarcel#include <sys/types.h> 37253862Smarcel#include <sys/stat.h> 38253862Smarcel#include <dirent.h> 39253862Smarcel#include <fcntl.h> 40253862Smarcel#include <stdio.h> 41102215Sscottl#include <stdlib.h> 42253862Smarcel#include <unistd.h> 43102215Sscottl#else 4461374Sdcs#include <stand.h> 45102215Sscottl#endif 4661374Sdcs#include "bootstrap.h" 4761374Sdcs#include <string.h> 4861374Sdcs#include "ficl.h" 4961374Sdcs 5076116Sdcs/* FreeBSD's loader interaction words and extras 5161374Sdcs * 5261374Sdcs * setenv ( value n name n' -- ) 5361374Sdcs * setenv? ( value n name n' flag -- ) 5461374Sdcs * getenv ( addr n -- addr' n' | -1 ) 5561374Sdcs * unsetenv ( addr n -- ) 5661374Sdcs * copyin ( addr addr' len -- ) 5761374Sdcs * copyout ( addr addr' len -- ) 5865617Sdcs * findfile ( name len type len' -- addr ) 5965617Sdcs * pnpdevices ( -- addr ) 6065617Sdcs * pnphandlers ( -- addr ) 6165617Sdcs * ccall ( [[...[p10] p9] ... p1] n addr -- result ) 6276116Sdcs * .# ( value -- ) 6361374Sdcs */ 6461374Sdcs 6561374Sdcsvoid 6661374SdcsficlSetenv(FICL_VM *pVM) 6761374Sdcs{ 68138223Sscottl#ifndef TESTMAIN 69138223Sscottl char *name, *value; 70138223Sscottl#endif 71138223Sscottl char *namep, *valuep; 7261374Sdcs int names, values; 7361374Sdcs 7461374Sdcs#if FICL_ROBUST > 1 7561374Sdcs vmCheckStack(pVM, 4, 0); 7661374Sdcs#endif 7761374Sdcs names = stackPopINT(pVM->pStack); 7861374Sdcs namep = (char*) stackPopPtr(pVM->pStack); 7961374Sdcs values = stackPopINT(pVM->pStack); 8061374Sdcs valuep = (char*) stackPopPtr(pVM->pStack); 8161374Sdcs 82138223Sscottl#ifndef TESTMAIN 8361374Sdcs name = (char*) ficlMalloc(names+1); 8461374Sdcs if (!name) 8561374Sdcs vmThrowErr(pVM, "Error: out of memory"); 8661374Sdcs strncpy(name, namep, names); 8761374Sdcs name[names] = '\0'; 8861374Sdcs value = (char*) ficlMalloc(values+1); 8961374Sdcs if (!value) 9061374Sdcs vmThrowErr(pVM, "Error: out of memory"); 9161374Sdcs strncpy(value, valuep, values); 9261374Sdcs value[values] = '\0'; 9361374Sdcs 9461374Sdcs setenv(name, value, 1); 9561374Sdcs ficlFree(name); 9661374Sdcs ficlFree(value); 97138223Sscottl#endif 9861374Sdcs 9961374Sdcs return; 10061374Sdcs} 10161374Sdcs 10261374Sdcsvoid 10361374SdcsficlSetenvq(FICL_VM *pVM) 10461374Sdcs{ 105138223Sscottl#ifndef TESTMAIN 106138223Sscottl char *name, *value; 107138223Sscottl#endif 108138223Sscottl char *namep, *valuep; 10961374Sdcs int names, values, overwrite; 11061374Sdcs 11161374Sdcs#if FICL_ROBUST > 1 11261374Sdcs vmCheckStack(pVM, 5, 0); 11361374Sdcs#endif 11461374Sdcs overwrite = stackPopINT(pVM->pStack); 11561374Sdcs names = stackPopINT(pVM->pStack); 11661374Sdcs namep = (char*) stackPopPtr(pVM->pStack); 11761374Sdcs values = stackPopINT(pVM->pStack); 11861374Sdcs valuep = (char*) stackPopPtr(pVM->pStack); 11961374Sdcs 120138223Sscottl#ifndef TESTMAIN 12161374Sdcs name = (char*) ficlMalloc(names+1); 12261374Sdcs if (!name) 12361374Sdcs vmThrowErr(pVM, "Error: out of memory"); 12461374Sdcs strncpy(name, namep, names); 12561374Sdcs name[names] = '\0'; 12661374Sdcs value = (char*) ficlMalloc(values+1); 12761374Sdcs if (!value) 12861374Sdcs vmThrowErr(pVM, "Error: out of memory"); 12961374Sdcs strncpy(value, valuep, values); 13061374Sdcs value[values] = '\0'; 13161374Sdcs 13261374Sdcs setenv(name, value, overwrite); 13361374Sdcs ficlFree(name); 13461374Sdcs ficlFree(value); 135138223Sscottl#endif 13661374Sdcs 13761374Sdcs return; 13861374Sdcs} 13961374Sdcs 14061374Sdcsvoid 14161374SdcsficlGetenv(FICL_VM *pVM) 14261374Sdcs{ 143138223Sscottl#ifndef TESTMAIN 144253862Smarcel char *name, *value; 145138223Sscottl#endif 146253862Smarcel char *namep; 14761374Sdcs int names; 14861374Sdcs 14961374Sdcs#if FICL_ROBUST > 1 15061374Sdcs vmCheckStack(pVM, 2, 2); 15161374Sdcs#endif 15261374Sdcs names = stackPopINT(pVM->pStack); 15361374Sdcs namep = (char*) stackPopPtr(pVM->pStack); 15461374Sdcs 155138223Sscottl#ifndef TESTMAIN 15661374Sdcs name = (char*) ficlMalloc(names+1); 15761374Sdcs if (!name) 15861374Sdcs vmThrowErr(pVM, "Error: out of memory"); 15961374Sdcs strncpy(name, namep, names); 16061374Sdcs name[names] = '\0'; 16161374Sdcs 16261374Sdcs value = getenv(name); 16361374Sdcs ficlFree(name); 16461374Sdcs 16561374Sdcs if(value != NULL) { 16661374Sdcs stackPushPtr(pVM->pStack, value); 16761374Sdcs stackPushINT(pVM->pStack, strlen(value)); 16861374Sdcs } else 169138223Sscottl#endif 17061374Sdcs stackPushINT(pVM->pStack, -1); 17161374Sdcs 17261374Sdcs return; 17361374Sdcs} 17461374Sdcs 17561374Sdcsvoid 17661374SdcsficlUnsetenv(FICL_VM *pVM) 17761374Sdcs{ 178138223Sscottl#ifndef TESTMAIN 179138223Sscottl char *name; 180138223Sscottl#endif 181138223Sscottl char *namep; 18261374Sdcs int names; 18361374Sdcs 18461374Sdcs#if FICL_ROBUST > 1 18561374Sdcs vmCheckStack(pVM, 2, 0); 18661374Sdcs#endif 18761374Sdcs names = stackPopINT(pVM->pStack); 18861374Sdcs namep = (char*) stackPopPtr(pVM->pStack); 18961374Sdcs 190138223Sscottl#ifndef TESTMAIN 19161374Sdcs name = (char*) ficlMalloc(names+1); 19261374Sdcs if (!name) 19361374Sdcs vmThrowErr(pVM, "Error: out of memory"); 19461374Sdcs strncpy(name, namep, names); 19561374Sdcs name[names] = '\0'; 19661374Sdcs 19761374Sdcs unsetenv(name); 19861374Sdcs ficlFree(name); 199138223Sscottl#endif 20061374Sdcs 20161374Sdcs return; 20261374Sdcs} 20361374Sdcs 20461374Sdcsvoid 20561374SdcsficlCopyin(FICL_VM *pVM) 20661374Sdcs{ 20761374Sdcs void* src; 20861374Sdcs vm_offset_t dest; 20961374Sdcs size_t len; 21061374Sdcs 21161374Sdcs#if FICL_ROBUST > 1 21261374Sdcs vmCheckStack(pVM, 3, 0); 21361374Sdcs#endif 21461374Sdcs 21561374Sdcs len = stackPopINT(pVM->pStack); 21661374Sdcs dest = stackPopINT(pVM->pStack); 21761374Sdcs src = stackPopPtr(pVM->pStack); 21861374Sdcs 219138223Sscottl#ifndef TESTMAIN 22061374Sdcs archsw.arch_copyin(src, dest, len); 221138223Sscottl#endif 22261374Sdcs 22361374Sdcs return; 22461374Sdcs} 22561374Sdcs 22661374Sdcsvoid 22761374SdcsficlCopyout(FICL_VM *pVM) 22861374Sdcs{ 22961374Sdcs void* dest; 23061374Sdcs vm_offset_t src; 23161374Sdcs size_t len; 23261374Sdcs 23361374Sdcs#if FICL_ROBUST > 1 23461374Sdcs vmCheckStack(pVM, 3, 0); 23561374Sdcs#endif 23661374Sdcs 23761374Sdcs len = stackPopINT(pVM->pStack); 23861374Sdcs dest = stackPopPtr(pVM->pStack); 23961374Sdcs src = stackPopINT(pVM->pStack); 24061374Sdcs 241138223Sscottl#ifndef TESTMAIN 24261374Sdcs archsw.arch_copyout(src, dest, len); 243138223Sscottl#endif 24461374Sdcs 24561374Sdcs return; 24661374Sdcs} 24761374Sdcs 24865617Sdcsvoid 24965617SdcsficlFindfile(FICL_VM *pVM) 25065617Sdcs{ 251138223Sscottl#ifndef TESTMAIN 252253862Smarcel char *name, *type; 253138223Sscottl#endif 254253862Smarcel char *namep, *typep; 25565617Sdcs struct preloaded_file* fp; 25665617Sdcs int names, types; 25765617Sdcs 25865617Sdcs#if FICL_ROBUST > 1 25965617Sdcs vmCheckStack(pVM, 4, 1); 26065617Sdcs#endif 26165617Sdcs 26265617Sdcs types = stackPopINT(pVM->pStack); 26365617Sdcs typep = (char*) stackPopPtr(pVM->pStack); 26465617Sdcs names = stackPopINT(pVM->pStack); 26565617Sdcs namep = (char*) stackPopPtr(pVM->pStack); 266138223Sscottl#ifndef TESTMAIN 26765617Sdcs name = (char*) ficlMalloc(names+1); 26865617Sdcs if (!name) 26965617Sdcs vmThrowErr(pVM, "Error: out of memory"); 27065617Sdcs strncpy(name, namep, names); 27165617Sdcs name[names] = '\0'; 27265617Sdcs type = (char*) ficlMalloc(types+1); 27365617Sdcs if (!type) 27465617Sdcs vmThrowErr(pVM, "Error: out of memory"); 27565617Sdcs strncpy(type, typep, types); 27665617Sdcs type[types] = '\0'; 27765617Sdcs 27865617Sdcs fp = file_findfile(name, type); 279138223Sscottl#else 280138223Sscottl fp = NULL; 281138223Sscottl#endif 28265617Sdcs stackPushPtr(pVM->pStack, fp); 28365617Sdcs 28465617Sdcs return; 28565617Sdcs} 28665617Sdcs 287138223Sscottl#ifndef TESTMAIN 28865677Sdfr#ifdef HAVE_PNP 28965677Sdfr 29065617Sdcsvoid 29165617SdcsficlPnpdevices(FICL_VM *pVM) 29265617Sdcs{ 29365617Sdcs static int pnp_devices_initted = 0; 29465617Sdcs#if FICL_ROBUST > 1 29565617Sdcs vmCheckStack(pVM, 0, 1); 29665617Sdcs#endif 29765617Sdcs 29865617Sdcs if(!pnp_devices_initted) { 29965617Sdcs STAILQ_INIT(&pnp_devices); 30065617Sdcs pnp_devices_initted = 1; 30165617Sdcs } 30265617Sdcs 30365617Sdcs stackPushPtr(pVM->pStack, &pnp_devices); 30465617Sdcs 30565617Sdcs return; 30665617Sdcs} 30765617Sdcs 30865617Sdcsvoid 30965617SdcsficlPnphandlers(FICL_VM *pVM) 31065617Sdcs{ 31165617Sdcs#if FICL_ROBUST > 1 31265617Sdcs vmCheckStack(pVM, 0, 1); 31365617Sdcs#endif 31465617Sdcs 31565617Sdcs stackPushPtr(pVM->pStack, pnphandlers); 31665617Sdcs 31765617Sdcs return; 31865617Sdcs} 31965617Sdcs 32065677Sdfr#endif 32165677Sdfr 32276116Sdcs#endif /* ndef TESTMAIN */ 32376116Sdcs 32465617Sdcsvoid 32565617SdcsficlCcall(FICL_VM *pVM) 32665617Sdcs{ 32765617Sdcs int (*func)(int, ...); 32865617Sdcs int result, p[10]; 32965617Sdcs int nparam, i; 33065617Sdcs 33165617Sdcs#if FICL_ROBUST > 1 33265617Sdcs vmCheckStack(pVM, 2, 0); 33365617Sdcs#endif 33465617Sdcs 33565617Sdcs func = stackPopPtr(pVM->pStack); 33665617Sdcs nparam = stackPopINT(pVM->pStack); 33765617Sdcs 33865617Sdcs#if FICL_ROBUST > 1 33965617Sdcs vmCheckStack(pVM, nparam, 1); 34065617Sdcs#endif 34165617Sdcs 34265617Sdcs for (i = 0; i < nparam; i++) 34365617Sdcs p[i] = stackPopINT(pVM->pStack); 34465617Sdcs 34565617Sdcs result = func(p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], 34665617Sdcs p[9]); 34765617Sdcs 34865617Sdcs stackPushINT(pVM->pStack, result); 34965617Sdcs 35065617Sdcs return; 35165617Sdcs} 35265617Sdcs 35376116Sdcs/************************************************************************** 35476116Sdcs f i c l E x e c F D 35576116Sdcs** reads in text from file fd and passes it to ficlExec() 35676116Sdcs * returns VM_OUTOFTEXT on success or the ficlExec() error code on 35776116Sdcs * failure. 35876116Sdcs */ 35976116Sdcs#define nLINEBUF 256 36076116Sdcsint ficlExecFD(FICL_VM *pVM, int fd) 36176116Sdcs{ 36276116Sdcs char cp[nLINEBUF]; 36376116Sdcs int nLine = 0, rval = VM_OUTOFTEXT; 36476116Sdcs char ch; 36576116Sdcs CELL id; 36676116Sdcs 36776116Sdcs id = pVM->sourceID; 36876116Sdcs pVM->sourceID.i = fd; 36976116Sdcs 37076116Sdcs /* feed each line to ficlExec */ 37176116Sdcs while (1) { 37276116Sdcs int status, i; 37376116Sdcs 37476116Sdcs i = 0; 37576116Sdcs while ((status = read(fd, &ch, 1)) > 0 && ch != '\n') 37676116Sdcs cp[i++] = ch; 37776116Sdcs nLine++; 37876116Sdcs if (!i) { 37976116Sdcs if (status < 1) 38076116Sdcs break; 38176116Sdcs continue; 38276116Sdcs } 38376116Sdcs rval = ficlExecC(pVM, cp, i); 38476116Sdcs if(rval != VM_QUIT && rval != VM_USEREXIT && rval != VM_OUTOFTEXT) 38576116Sdcs { 38676116Sdcs pVM->sourceID = id; 38776116Sdcs return rval; 38876116Sdcs } 38976116Sdcs } 39076116Sdcs /* 39176116Sdcs ** Pass an empty line with SOURCE-ID == -1 to flush 39276116Sdcs ** any pending REFILLs (as required by FILE wordset) 39376116Sdcs */ 39476116Sdcs pVM->sourceID.i = -1; 39576116Sdcs ficlExec(pVM, ""); 39676116Sdcs 39776116Sdcs pVM->sourceID = id; 39876116Sdcs return rval; 39976116Sdcs} 40076116Sdcs 40176116Sdcsstatic void displayCellNoPad(FICL_VM *pVM) 40276116Sdcs{ 40376116Sdcs CELL c; 40476116Sdcs#if FICL_ROBUST > 1 40576116Sdcs vmCheckStack(pVM, 1, 0); 40676116Sdcs#endif 40776116Sdcs c = stackPop(pVM->pStack); 40876116Sdcs ltoa((c).i, pVM->pad, pVM->base); 40976116Sdcs vmTextOut(pVM, pVM->pad, 0); 41076116Sdcs return; 41176116Sdcs} 41276116Sdcs 413253172Smarcel/* isdir? - Return whether an fd corresponds to a directory. 414253172Smarcel * 415253172Smarcel * isdir? ( fd -- bool ) 416253172Smarcel */ 417253172Smarcelstatic void isdirQuestion(FICL_VM *pVM) 418253172Smarcel{ 419253172Smarcel struct stat sb; 420253172Smarcel FICL_INT flag; 421253172Smarcel int fd; 422253172Smarcel 423253172Smarcel#if FICL_ROBUST > 1 424253172Smarcel vmCheckStack(pVM, 1, 1); 425253172Smarcel#endif 426253172Smarcel 427253172Smarcel fd = stackPopINT(pVM->pStack); 428253172Smarcel flag = FICL_FALSE; 429253172Smarcel do { 430253172Smarcel if (fd < 0) 431253172Smarcel break; 432253172Smarcel if (fstat(fd, &sb) < 0) 433253172Smarcel break; 434253172Smarcel if (!S_ISDIR(sb.st_mode)) 435253172Smarcel break; 436253172Smarcel flag = FICL_TRUE; 437253172Smarcel } while (0); 438253172Smarcel stackPushINT(pVM->pStack, flag); 439253172Smarcel} 440253172Smarcel 44176116Sdcs/* fopen - open a file and return new fd on stack. 44276116Sdcs * 44387636Sjhb * fopen ( ptr count mode -- fd ) 44476116Sdcs */ 44576116Sdcsstatic void pfopen(FICL_VM *pVM) 44676116Sdcs{ 44787636Sjhb int mode, fd, count; 44887636Sjhb char *ptr, *name; 44976116Sdcs 45076116Sdcs#if FICL_ROBUST > 1 45187636Sjhb vmCheckStack(pVM, 3, 1); 45276116Sdcs#endif 45387636Sjhb 45487636Sjhb mode = stackPopINT(pVM->pStack); /* get mode */ 45587636Sjhb count = stackPopINT(pVM->pStack); /* get count */ 45687636Sjhb ptr = stackPopPtr(pVM->pStack); /* get ptr */ 45787636Sjhb 45887636Sjhb if ((count < 0) || (ptr == NULL)) { 45987636Sjhb stackPushINT(pVM->pStack, -1); 46087636Sjhb return; 46187636Sjhb } 46287636Sjhb 46387636Sjhb /* ensure that the string is null terminated */ 46487636Sjhb name = (char *)malloc(count+1); 46587636Sjhb bcopy(ptr,name,count); 46687636Sjhb name[count] = 0; 46787636Sjhb 46887636Sjhb /* open the file */ 46987636Sjhb fd = open(name, mode); 47087636Sjhb free(name); 47176116Sdcs stackPushINT(pVM->pStack, fd); 47276116Sdcs return; 47387636Sjhb} 47476116Sdcs 47576116Sdcs/* fclose - close a file who's fd is on stack. 47676116Sdcs * 47776116Sdcs * fclose ( fd -- ) 47876116Sdcs */ 47976116Sdcsstatic void pfclose(FICL_VM *pVM) 48076116Sdcs{ 48176116Sdcs int fd; 48276116Sdcs 48376116Sdcs#if FICL_ROBUST > 1 48476116Sdcs vmCheckStack(pVM, 1, 0); 48576116Sdcs#endif 48676116Sdcs fd = stackPopINT(pVM->pStack); /* get fd */ 48776116Sdcs if (fd != -1) 48876116Sdcs close(fd); 48976116Sdcs return; 49076116Sdcs} 49176116Sdcs 49276116Sdcs/* fread - read file contents 49376116Sdcs * 49476116Sdcs * fread ( fd buf nbytes -- nread ) 49576116Sdcs */ 49676116Sdcsstatic void pfread(FICL_VM *pVM) 49776116Sdcs{ 49876116Sdcs int fd, len; 49976116Sdcs char *buf; 50076116Sdcs 50176116Sdcs#if FICL_ROBUST > 1 50276116Sdcs vmCheckStack(pVM, 3, 1); 50376116Sdcs#endif 50476116Sdcs len = stackPopINT(pVM->pStack); /* get number of bytes to read */ 50576116Sdcs buf = stackPopPtr(pVM->pStack); /* get buffer */ 50676116Sdcs fd = stackPopINT(pVM->pStack); /* get fd */ 50776116Sdcs if (len > 0 && buf && fd != -1) 50876116Sdcs stackPushINT(pVM->pStack, read(fd, buf, len)); 50976116Sdcs else 51076116Sdcs stackPushINT(pVM->pStack, -1); 51176116Sdcs return; 51276116Sdcs} 51376116Sdcs 514253172Smarcel/* freaddir - read directory contents 515253172Smarcel * 516253172Smarcel * freaddir ( fd -- ptr len TRUE | FALSE ) 517253172Smarcel */ 518253172Smarcelstatic void pfreaddir(FICL_VM *pVM) 519253172Smarcel{ 520253862Smarcel#ifdef TESTMAIN 521254155Smarcel static struct dirent dirent; 522254155Smarcel struct stat sb; 523254155Smarcel char *buf; 524254155Smarcel off_t off, ptr; 525254155Smarcel u_int blksz; 526254155Smarcel int bufsz; 527253862Smarcel#endif 528253172Smarcel struct dirent *d; 529253172Smarcel int fd; 530253172Smarcel 531253172Smarcel#if FICL_ROBUST > 1 532253172Smarcel vmCheckStack(pVM, 1, 3); 533253172Smarcel#endif 534253172Smarcel 535253172Smarcel fd = stackPopINT(pVM->pStack); 536253862Smarcel#if TESTMAIN 537253862Smarcel /* 538253862Smarcel * The readdirfd() function is specific to the loader environment. 539253862Smarcel * We do the best we can to make freaddir work, but it's not at 540253862Smarcel * all guaranteed. 541253862Smarcel */ 542254155Smarcel d = NULL; 543254155Smarcel buf = NULL; 544254155Smarcel do { 545254155Smarcel if (fd == -1) 546254155Smarcel break; 547254155Smarcel if (fstat(fd, &sb) == -1) 548254155Smarcel break; 549254155Smarcel blksz = (sb.st_blksize) ? sb.st_blksize : getpagesize(); 550254155Smarcel if ((blksz & (blksz - 1)) != 0) 551254155Smarcel break; 552254155Smarcel buf = malloc(blksz); 553254155Smarcel if (buf == NULL) 554254155Smarcel break; 555254155Smarcel off = lseek(fd, 0LL, SEEK_CUR); 556254155Smarcel if (off == -1) 557254155Smarcel break; 558254155Smarcel ptr = off; 559254155Smarcel if (lseek(fd, 0, SEEK_SET) == -1) 560254155Smarcel break; 561254155Smarcel bufsz = getdents(fd, buf, blksz); 562254155Smarcel while (bufsz > 0 && bufsz <= ptr) { 563254155Smarcel ptr -= bufsz; 564254155Smarcel bufsz = getdents(fd, buf, blksz); 565254155Smarcel } 566254155Smarcel if (bufsz <= 0) 567254155Smarcel break; 568254155Smarcel d = (void *)(buf + ptr); 569254155Smarcel dirent = *d; 570254155Smarcel off += d->d_reclen; 571254155Smarcel d = (lseek(fd, off, SEEK_SET) != off) ? NULL : &dirent; 572254155Smarcel } while (0); 573254155Smarcel if (buf != NULL) 574254155Smarcel free(buf); 575253862Smarcel#else 576253172Smarcel d = readdirfd(fd); 577253862Smarcel#endif 578253172Smarcel if (d != NULL) { 579253172Smarcel stackPushPtr(pVM->pStack, d->d_name); 580253172Smarcel stackPushINT(pVM->pStack, strlen(d->d_name)); 581253172Smarcel stackPushINT(pVM->pStack, FICL_TRUE); 582253172Smarcel } else { 583253172Smarcel stackPushINT(pVM->pStack, FICL_FALSE); 584253172Smarcel } 585253172Smarcel} 586253172Smarcel 58776116Sdcs/* fload - interpret file contents 58876116Sdcs * 58976116Sdcs * fload ( fd -- ) 59076116Sdcs */ 59176116Sdcsstatic void pfload(FICL_VM *pVM) 59276116Sdcs{ 59376116Sdcs int fd; 59476116Sdcs 59576116Sdcs#if FICL_ROBUST > 1 59676116Sdcs vmCheckStack(pVM, 1, 0); 59776116Sdcs#endif 59876116Sdcs fd = stackPopINT(pVM->pStack); /* get fd */ 59976116Sdcs if (fd != -1) 60076116Sdcs ficlExecFD(pVM, fd); 60176116Sdcs return; 60276116Sdcs} 60376116Sdcs 60487636Sjhb/* fwrite - write file contents 60587636Sjhb * 60687636Sjhb * fwrite ( fd buf nbytes -- nwritten ) 60787636Sjhb */ 60887636Sjhbstatic void pfwrite(FICL_VM *pVM) 60987636Sjhb{ 61087636Sjhb int fd, len; 61187636Sjhb char *buf; 61287636Sjhb 61387636Sjhb#if FICL_ROBUST > 1 61487636Sjhb vmCheckStack(pVM, 3, 1); 61587636Sjhb#endif 61687636Sjhb len = stackPopINT(pVM->pStack); /* get number of bytes to read */ 61787636Sjhb buf = stackPopPtr(pVM->pStack); /* get buffer */ 61887636Sjhb fd = stackPopINT(pVM->pStack); /* get fd */ 61987636Sjhb if (len > 0 && buf && fd != -1) 62087636Sjhb stackPushINT(pVM->pStack, write(fd, buf, len)); 62187636Sjhb else 62287636Sjhb stackPushINT(pVM->pStack, -1); 62387636Sjhb return; 62487636Sjhb} 62587636Sjhb 62687636Sjhb/* fseek - seek to a new position in a file 62787636Sjhb * 62887636Sjhb * fseek ( fd ofs whence -- pos ) 62987636Sjhb */ 63087636Sjhbstatic void pfseek(FICL_VM *pVM) 63187636Sjhb{ 63287636Sjhb int fd, pos, whence; 63387636Sjhb 63487636Sjhb#if FICL_ROBUST > 1 63587636Sjhb vmCheckStack(pVM, 3, 1); 63687636Sjhb#endif 63787636Sjhb whence = stackPopINT(pVM->pStack); 63887636Sjhb pos = stackPopINT(pVM->pStack); 63987636Sjhb fd = stackPopINT(pVM->pStack); 64087636Sjhb stackPushINT(pVM->pStack, lseek(fd, pos, whence)); 64187636Sjhb return; 64287636Sjhb} 64387636Sjhb 64476116Sdcs/* key - get a character from stdin 64576116Sdcs * 64676116Sdcs * key ( -- char ) 64776116Sdcs */ 64876116Sdcsstatic void key(FICL_VM *pVM) 64976116Sdcs{ 65076116Sdcs#if FICL_ROBUST > 1 65176116Sdcs vmCheckStack(pVM, 0, 1); 65276116Sdcs#endif 65376116Sdcs stackPushINT(pVM->pStack, getchar()); 65476116Sdcs return; 65576116Sdcs} 65676116Sdcs 65776116Sdcs/* key? - check for a character from stdin (FACILITY) 65876116Sdcs * 65976116Sdcs * key? ( -- flag ) 66076116Sdcs */ 66176116Sdcsstatic void keyQuestion(FICL_VM *pVM) 66276116Sdcs{ 66376116Sdcs#if FICL_ROBUST > 1 66476116Sdcs vmCheckStack(pVM, 0, 1); 66576116Sdcs#endif 66676116Sdcs#ifdef TESTMAIN 66776116Sdcs /* XXX Since we don't fiddle with termios, let it always succeed... */ 66876116Sdcs stackPushINT(pVM->pStack, FICL_TRUE); 66976116Sdcs#else 67076116Sdcs /* But here do the right thing. */ 67176116Sdcs stackPushINT(pVM->pStack, ischar()? FICL_TRUE : FICL_FALSE); 67276116Sdcs#endif 67376116Sdcs return; 67476116Sdcs} 67576116Sdcs 67676116Sdcs/* seconds - gives number of seconds since beginning of time 67776116Sdcs * 67876116Sdcs * beginning of time is defined as: 67976116Sdcs * 68076116Sdcs * BTX - number of seconds since midnight 68176116Sdcs * FreeBSD - number of seconds since Jan 1 1970 68276116Sdcs * 68376116Sdcs * seconds ( -- u ) 68476116Sdcs */ 68576116Sdcsstatic void pseconds(FICL_VM *pVM) 68676116Sdcs{ 68776116Sdcs#if FICL_ROBUST > 1 68876116Sdcs vmCheckStack(pVM,0,1); 68976116Sdcs#endif 69076116Sdcs stackPushUNS(pVM->pStack, (FICL_UNS) time(NULL)); 69176116Sdcs return; 69276116Sdcs} 69376116Sdcs 69476116Sdcs/* ms - wait at least that many milliseconds (FACILITY) 69576116Sdcs * 69676116Sdcs * ms ( u -- ) 69776116Sdcs * 69876116Sdcs */ 69976116Sdcsstatic void ms(FICL_VM *pVM) 70076116Sdcs{ 70176116Sdcs#if FICL_ROBUST > 1 70276116Sdcs vmCheckStack(pVM,1,0); 70376116Sdcs#endif 70476116Sdcs#ifdef TESTMAIN 70576116Sdcs usleep(stackPopUNS(pVM->pStack)*1000); 70676116Sdcs#else 70776116Sdcs delay(stackPopUNS(pVM->pStack)*1000); 70876116Sdcs#endif 70976116Sdcs return; 71076116Sdcs} 71176116Sdcs 71276116Sdcs/* fkey - get a character from a file 71376116Sdcs * 71476116Sdcs * fkey ( file -- char ) 71576116Sdcs */ 71676116Sdcsstatic void fkey(FICL_VM *pVM) 71776116Sdcs{ 71876116Sdcs int i, fd; 71976116Sdcs char ch; 72076116Sdcs 72176116Sdcs#if FICL_ROBUST > 1 72276116Sdcs vmCheckStack(pVM, 1, 1); 72376116Sdcs#endif 72476116Sdcs fd = stackPopINT(pVM->pStack); 72576116Sdcs i = read(fd, &ch, 1); 72676116Sdcs stackPushINT(pVM->pStack, i > 0 ? ch : -1); 72776116Sdcs return; 72876116Sdcs} 72976116Sdcs 73076116Sdcs/* 73176116Sdcs** Retrieves free space remaining on the dictionary 73276116Sdcs*/ 73376116Sdcs 73476116Sdcsstatic void freeHeap(FICL_VM *pVM) 73576116Sdcs{ 73694290Sdcs stackPushINT(pVM->pStack, dictCellsAvail(ficlGetDict(pVM->pSys))); 73776116Sdcs} 73876116Sdcs 73976116Sdcs 74076116Sdcs/******************* Increase dictionary size on-demand ******************/ 74176116Sdcs 74276116Sdcsstatic void ficlDictThreshold(FICL_VM *pVM) 74376116Sdcs{ 74476116Sdcs stackPushPtr(pVM->pStack, &dictThreshold); 74576116Sdcs} 74676116Sdcs 74776116Sdcsstatic void ficlDictIncrease(FICL_VM *pVM) 74876116Sdcs{ 74976116Sdcs stackPushPtr(pVM->pStack, &dictIncrease); 75076116Sdcs} 75176116Sdcs 75276116Sdcs 75376116Sdcs/************************************************************************** 75476116Sdcs f i c l C o m p i l e P l a t f o r m 75576116Sdcs** Build FreeBSD platform extensions into the system dictionary 75676116Sdcs**************************************************************************/ 75776116Sdcsvoid ficlCompilePlatform(FICL_SYSTEM *pSys) 75876116Sdcs{ 75976116Sdcs FICL_DICT *dp = pSys->dp; 76076116Sdcs assert (dp); 76176116Sdcs 76276116Sdcs dictAppendWord(dp, ".#", displayCellNoPad, FW_DEFAULT); 763253172Smarcel dictAppendWord(dp, "isdir?", isdirQuestion, FW_DEFAULT); 76476116Sdcs dictAppendWord(dp, "fopen", pfopen, FW_DEFAULT); 76576116Sdcs dictAppendWord(dp, "fclose", pfclose, FW_DEFAULT); 76676116Sdcs dictAppendWord(dp, "fread", pfread, FW_DEFAULT); 767253172Smarcel dictAppendWord(dp, "freaddir", pfreaddir, FW_DEFAULT); 76876116Sdcs dictAppendWord(dp, "fload", pfload, FW_DEFAULT); 76976116Sdcs dictAppendWord(dp, "fkey", fkey, FW_DEFAULT); 77087636Sjhb dictAppendWord(dp, "fseek", pfseek, FW_DEFAULT); 77187636Sjhb dictAppendWord(dp, "fwrite", pfwrite, FW_DEFAULT); 77276116Sdcs dictAppendWord(dp, "key", key, FW_DEFAULT); 77376116Sdcs dictAppendWord(dp, "key?", keyQuestion, FW_DEFAULT); 77476116Sdcs dictAppendWord(dp, "ms", ms, FW_DEFAULT); 77576116Sdcs dictAppendWord(dp, "seconds", pseconds, FW_DEFAULT); 77676116Sdcs dictAppendWord(dp, "heap?", freeHeap, FW_DEFAULT); 77776116Sdcs dictAppendWord(dp, "dictthreshold", ficlDictThreshold, FW_DEFAULT); 77876116Sdcs dictAppendWord(dp, "dictincrease", ficlDictIncrease, FW_DEFAULT); 77976116Sdcs 78076116Sdcs dictAppendWord(dp, "setenv", ficlSetenv, FW_DEFAULT); 78176116Sdcs dictAppendWord(dp, "setenv?", ficlSetenvq, FW_DEFAULT); 78276116Sdcs dictAppendWord(dp, "getenv", ficlGetenv, FW_DEFAULT); 78376116Sdcs dictAppendWord(dp, "unsetenv", ficlUnsetenv, FW_DEFAULT); 78476116Sdcs dictAppendWord(dp, "copyin", ficlCopyin, FW_DEFAULT); 78576116Sdcs dictAppendWord(dp, "copyout", ficlCopyout, FW_DEFAULT); 78676116Sdcs dictAppendWord(dp, "findfile", ficlFindfile, FW_DEFAULT); 787138223Sscottl dictAppendWord(dp, "ccall", ficlCcall, FW_DEFAULT); 788138223Sscottl#ifndef TESTMAIN 789138223Sscottl#ifdef __i386__ 790138223Sscottl dictAppendWord(dp, "outb", ficlOutb, FW_DEFAULT); 791138223Sscottl dictAppendWord(dp, "inb", ficlInb, FW_DEFAULT); 792138223Sscottl#endif 79376116Sdcs#ifdef HAVE_PNP 79476116Sdcs dictAppendWord(dp, "pnpdevices",ficlPnpdevices, FW_DEFAULT); 79576116Sdcs dictAppendWord(dp, "pnphandlers",ficlPnphandlers, FW_DEFAULT); 79676116Sdcs#endif 79776116Sdcs#endif 79876116Sdcs 799116000Snyan#if defined(PC98) 800116000Snyan ficlSetEnv(pSys, "arch-pc98", FICL_TRUE); 801116000Snyan#elif defined(__i386__) 80294290Sdcs ficlSetEnv(pSys, "arch-i386", FICL_TRUE); 80394290Sdcs ficlSetEnv(pSys, "arch-ia64", FICL_FALSE); 804123373Sgrehan ficlSetEnv(pSys, "arch-powerpc", FICL_FALSE); 80582941Sdfr#elif defined(__ia64__) 80694290Sdcs ficlSetEnv(pSys, "arch-i386", FICL_FALSE); 80794290Sdcs ficlSetEnv(pSys, "arch-ia64", FICL_TRUE); 808123373Sgrehan ficlSetEnv(pSys, "arch-powerpc", FICL_FALSE); 809123373Sgrehan#elif defined(__powerpc__) 810123373Sgrehan ficlSetEnv(pSys, "arch-i386", FICL_FALSE); 811123373Sgrehan ficlSetEnv(pSys, "arch-ia64", FICL_FALSE); 812123373Sgrehan ficlSetEnv(pSys, "arch-powerpc", FICL_TRUE); 81376116Sdcs#endif 81476116Sdcs 81576116Sdcs return; 81676116Sdcs} 81776116Sdcs 818