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