Overview
Comment: | Added matchInDir support |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
5583d77f1ced231e004b80898a3c47f3 |
User & Date: | rkeene on 2019-09-14 03:59:53 |
Other Links: | manifest | tags |
Context
2019-09-14
| ||
04:56 | Added support for accessProc and mapped X_OK to directories check-in: 12ff77016f user: rkeene tags: trunk | |
03:59 | Added matchInDir support check-in: 5583d77f1c user: rkeene tags: trunk | |
00:54 | Updated to keep track of whether or not there were events queued before closing and freeing a structure check-in: aa08a4a749 user: rkeene tags: trunk | |
Changes
Modified Makefile from [5600193367] to [de04821f8d].
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | CPPFLAGS := -I. -DUSE_TCL_STUBS=1 -DXVFS_MODE_FLEXIBLE CFLAGS := -fPIC -g3 -ggdb3 -Wall LDFLAGS := LIBS := -ltclstub8.6 all: example.so example.c: $(shell find example -type f) $(shell find lib -type f) xvfs.c.rvt xvfs-create Makefile ./xvfs-create --directory example --name example > example.c.new mv example.c.new example.c example.o: example.c xvfs-core.h xvfs-core.c Makefile $(CC) $(CPPFLAGS) $(CFLAGS) -o example.o -c example.c example.so: example.o Makefile $(CC) $(CFLAGS) $(LDFLAGS) -shared -o example.so example.o $(LIBS) test: example.so | > > | > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | CPPFLAGS := -I. -DUSE_TCL_STUBS=1 -DXVFS_MODE_FLEXIBLE CFLAGS := -fPIC -g3 -ggdb3 -Wall LDFLAGS := LIBS := -ltclstub8.6 TCLSH := tclsh all: example.so example.c: $(shell find example -type f) $(shell find lib -type f) xvfs.c.rvt xvfs-create Makefile ./xvfs-create --directory example --name example > example.c.new mv example.c.new example.c example.o: example.c xvfs-core.h xvfs-core.c Makefile $(CC) $(CPPFLAGS) $(CFLAGS) -o example.o -c example.c example.so: example.o Makefile $(CC) $(CFLAGS) $(LDFLAGS) -shared -o example.so example.o $(LIBS) test: example.so rm -f __test__.tcl echo 'if {[catch { load ./example.so Xvfs_example; source //xvfs:/example/main.tcl }]} { puts stderr $$::errorInfo; exit 1 }; exit 0' > __test__.tcl $(GDB) $(TCLSH) __test__.tcl rm -f __test__.tcl clean: rm -f example.c example.c.new rm -f example.so example.o rm -f __test__.tcl distclean: clean .PHONY: all clean distclean test |
Modified example/main.tcl from [6323624de5] to [575385fd45].
|
| | > > | 1 2 3 4 5 6 7 8 9 10 | set dir "//xvfs:/example" set dirNative [file join [pwd] example] set file "${dir}/foo" set fd [open $file] seek $fd 0 end seek $fd -1 current set check [read $fd 1] if {$check != "\n"} { error "EXPECTED: (new line); GOT: [binary encode hex $check]" |
︙ | ︙ | |||
44 45 46 47 48 49 50 51 | } if {[lsort -integer $output] != $output} { error "EXPECTED [lsort -integer $output], GOT $output" } close $fd update idle puts "ALL TESTS PASSED" | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | } if {[lsort -integer $output] != $output} { error "EXPECTED [lsort -integer $output], GOT $output" } close $fd update idle proc glob_verify {args} { set rv [glob -nocomplain -directory $::dir {*}$args] set verify [glob -nocomplain -directory $::dirNative {*}$args] if {[llength $rv] != [llength $verify]} { error "VERIFY FAILED: glob ... $args ($rv versus $verify)" } return $rv } set check [glob_verify *] if {[llength $check] < 2} { error "EXPECTED >=2, GOT [llength $check] ($check)" } set check [glob_verify f*] if {[llength $check] != 1} { error "EXPECTED 1, GOT [llength $check] ($check)" } set check [glob_verify ./f*] if {[llength $check] != 1} { error "EXPECTED 1, GOT [llength $check] ($check)" } set check [glob_verify -type f ./f*] if {[llength $check] != 1} { error "EXPECTED 1, GOT [llength $check] ($check)" } set check [glob_verify -type d ./f*] if {[llength $check] != 0} { error "EXPECTED 0, GOT [llength $check] ($check)" } set check [glob_verify x*] if {[llength $check] != 0} { error "EXPECTED 0, GOT [llength $check] ($check)" } set check [glob_verify lib/*] if {[llength $check] != 1} { error "EXPECTED 1, GOT [llength $check] ($check)" } set check [lindex $check 0] if {![string match $dir/* $check]} { error "EXPECTED \"$dir/*\", GOT $check" } set check [glob_verify -type d *] if {[llength $check] != 1} { error "EXPECTED 1, GOT [llength $check] ($check)" } puts "ALL TESTS PASSED" |
Modified xvfs-core.c from [7b136bd4a6] to [46e5437872].
︙ | ︙ | |||
24 25 26 27 28 29 30 31 32 33 34 35 36 37 | }; /* * Internal Core Utilities */ static const char *xvfs_relativePath(Tcl_Obj *path, struct xvfs_tclfs_instance_info *info) { const char *pathStr, *rootStr; int pathLen, rootLen; pathStr = Tcl_GetStringFromObj(path, &pathLen); rootStr = Tcl_GetStringFromObj(info->mountpoint, &rootLen); if (pathLen < rootLen) { return(NULL); | > | 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | }; /* * Internal Core Utilities */ static const char *xvfs_relativePath(Tcl_Obj *path, struct xvfs_tclfs_instance_info *info) { const char *pathStr, *rootStr; const char *pathFinal; int pathLen, rootLen; pathStr = Tcl_GetStringFromObj(path, &pathLen); rootStr = Tcl_GetStringFromObj(info->mountpoint, &rootLen); if (pathLen < rootLen) { return(NULL); |
︙ | ︙ | |||
46 47 48 49 50 51 52 | } /* XXX:TODO: Should this use the native OS path separator ? */ if (pathStr[rootLen] != '/') { return(NULL); } | | > | > > | | > > > > | | > | > > < > > | 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | } /* XXX:TODO: Should this use the native OS path separator ? */ if (pathStr[rootLen] != '/') { return(NULL); } pathFinal = pathStr + rootLen + 1; pathLen -= rootLen + 1; if (pathLen == 1 && memcmp(pathFinal, ".", 1) == 0) { return(""); } while (pathLen >= 2 && memcmp(pathFinal, "./", 2) == 0) { pathFinal += 2; pathLen -= 2; } return(pathFinal); } static const char *xvfs_perror(int xvfs_error) { if (xvfs_error >= 0) { return("Not an error"); } switch (xvfs_error) { case XVFS_RV_ERR_ENOENT: return("No such file or directory"); case XVFS_RV_ERR_EINVAL: return("Invalid argument"); case XVFS_RV_ERR_EISDIR: return("Is a directory"); case XVFS_RV_ERR_ENOTDIR: return("Not a directory"); case XVFS_RV_ERR_EFAULT: return("Bad address"); case XVFS_RV_ERR_INTERNAL: return("Internal error"); default: return("Unknown error"); } } static int xvfs_errorToErrno(int xvfs_error) { if (xvfs_error >= 0) { return(0); } switch (xvfs_error) { case XVFS_RV_ERR_ENOENT: return(ENOENT); case XVFS_RV_ERR_EINVAL: return(EINVAL); case XVFS_RV_ERR_EISDIR: return(EISDIR); case XVFS_RV_ERR_ENOTDIR: return(ENOTDIR); case XVFS_RV_ERR_EFAULT: return(EFAULT); case XVFS_RV_ERR_INTERNAL: return(EINVAL); default: return(ERANGE); } } /* * Xvfs Memory Channel |
︙ | ︙ | |||
397 398 399 400 401 402 403 404 405 406 407 408 409 410 | if (mode & O_WRONLY) { return(NULL); } return(xvfs_tclfs_openChannel(Tcl_NewStringObj(pathStr, -1), instanceInfo)); } #endif /* XVFS_MODE_SERVER || XVFS_MODE_STANDALONE || XVFS_MODE_FLEIXBLE */ #if defined(XVFS_MODE_STANDALONE) || defined(XVFS_MODE_FLEXIBLE) /* * Tcl_Filesystem handlers for the standalone implementation */ static struct xvfs_tclfs_instance_info xvfs_tclfs_standalone_info; | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 | if (mode & O_WRONLY) { return(NULL); } return(xvfs_tclfs_openChannel(Tcl_NewStringObj(pathStr, -1), instanceInfo)); } static int xvfs_tclfs_verifyType(Tcl_Obj *path, Tcl_GlobTypeData *types, struct xvfs_tclfs_instance_info *instanceInfo) { const char *pathStr; Tcl_StatBuf fileInfo; int statRetVal; statRetVal = xvfs_tclfs_stat(path, &fileInfo, instanceInfo); if (statRetVal != 0) { return(0); } if (!types) { return(1); } if (types->perm != TCL_GLOB_PERM_RONLY) { if (types->perm & (TCL_GLOB_PERM_W | TCL_GLOB_PERM_X | TCL_GLOB_PERM_HIDDEN)) { return(0); } } if (types->type & (TCL_GLOB_TYPE_BLOCK | TCL_GLOB_TYPE_CHAR | TCL_GLOB_TYPE_PIPE | TCL_GLOB_TYPE_SOCK | TCL_GLOB_TYPE_LINK)) { return(0); } if ((types->type & TCL_GLOB_TYPE_DIR) == TCL_GLOB_TYPE_DIR) { if (!(fileInfo.st_mode & 040000)) { return(0); } } if ((types->type & TCL_GLOB_TYPE_FILE) == TCL_GLOB_TYPE_FILE) { if (!(fileInfo.st_mode & 0100000)) { return(0); } } if ((types->type & TCL_GLOB_TYPE_MOUNT) == TCL_GLOB_TYPE_MOUNT) { pathStr = xvfs_relativePath(path, instanceInfo); if (!pathStr) { return(0); } if (strlen(pathStr) != 0) { return(0); } } return(1); } static int xvfs_tclfs_matchInDir(Tcl_Interp *interp, Tcl_Obj *resultPtr, Tcl_Obj *path, const char *pattern, Tcl_GlobTypeData *types, struct xvfs_tclfs_instance_info *instanceInfo) { const char *pathStr; const char **children, *child; Tcl_WideInt childrenCount, idx; Tcl_Obj *childObj; int tclRetVal; if (pattern == NULL) { if (xvfs_tclfs_verifyType(path, types, instanceInfo)) { return(TCL_OK); } return(TCL_ERROR); } pathStr = xvfs_relativePath(path, instanceInfo); if (!pathStr) { if (interp) { Tcl_SetResult(interp, (char *) xvfs_perror(XVFS_RV_ERR_ENOENT), NULL); } return(TCL_ERROR); } childrenCount = 0; children = instanceInfo->fsInfo->getChildrenProc(pathStr, &childrenCount); if (childrenCount < 0) { if (interp) { Tcl_SetResult(interp, (char *) xvfs_perror(childrenCount), NULL); } return(TCL_ERROR); } for (idx = 0; idx < childrenCount; idx++) { child = children[idx]; if (!Tcl_StringMatch(child, pattern)) { continue; } childObj = Tcl_DuplicateObj(path); Tcl_AppendStringsToObj(childObj, "/", child, NULL); Tcl_IncrRefCount(childObj); if (!xvfs_tclfs_verifyType(childObj, types, instanceInfo)) { Tcl_DecrRefCount(childObj); continue; } tclRetVal = Tcl_ListObjAppendElement(interp, resultPtr, childObj); Tcl_DecrRefCount(childObj); if (tclRetVal != TCL_OK) { return(tclRetVal); } } return(TCL_OK); } #endif /* XVFS_MODE_SERVER || XVFS_MODE_STANDALONE || XVFS_MODE_FLEIXBLE */ #if defined(XVFS_MODE_STANDALONE) || defined(XVFS_MODE_FLEXIBLE) /* * Tcl_Filesystem handlers for the standalone implementation */ static struct xvfs_tclfs_instance_info xvfs_tclfs_standalone_info; |
︙ | ︙ | |||
419 420 421 422 423 424 425 426 427 428 429 430 431 432 | static Tcl_Obj *xvfs_tclfs_standalone_listVolumes(void) { return(xvfs_tclfs_listVolumes(&xvfs_tclfs_standalone_info)); } static Tcl_Channel xvfs_tclfs_standalone_openFileChannel(Tcl_Interp *interp, Tcl_Obj *path, int mode, int permissions) { return(xvfs_tclfs_openFileChannel(interp, path, mode, permissions, &xvfs_tclfs_standalone_info)); } /* * There are three (3) modes of operation for Xvfs_Register: * 1. standalone -- We register our own Tcl_Filesystem * and handle requests under `//xvfs:/<fsName>` * 2. client -- A single Tcl_Filesystem is registered for the * interp to handle requests under `//xvfs:/` which | > > > > | 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 | static Tcl_Obj *xvfs_tclfs_standalone_listVolumes(void) { return(xvfs_tclfs_listVolumes(&xvfs_tclfs_standalone_info)); } static Tcl_Channel xvfs_tclfs_standalone_openFileChannel(Tcl_Interp *interp, Tcl_Obj *path, int mode, int permissions) { return(xvfs_tclfs_openFileChannel(interp, path, mode, permissions, &xvfs_tclfs_standalone_info)); } static int xvfs_tclfs_standalone_matchInDir(Tcl_Interp *interp, Tcl_Obj *resultPtr, Tcl_Obj *pathPtr, const char *pattern, Tcl_GlobTypeData *types) { return(xvfs_tclfs_matchInDir(interp, resultPtr, pathPtr, pattern, types, &xvfs_tclfs_standalone_info)); } /* * There are three (3) modes of operation for Xvfs_Register: * 1. standalone -- We register our own Tcl_Filesystem * and handle requests under `//xvfs:/<fsName>` * 2. client -- A single Tcl_Filesystem is registered for the * interp to handle requests under `//xvfs:/` which |
︙ | ︙ | |||
471 472 473 474 475 476 477 | xvfs_tclfs_standalone_fs.createInternalRepProc = NULL; xvfs_tclfs_standalone_fs.normalizePathProc = NULL; xvfs_tclfs_standalone_fs.filesystemPathTypeProc = NULL; xvfs_tclfs_standalone_fs.filesystemSeparatorProc = NULL; xvfs_tclfs_standalone_fs.statProc = xvfs_tclfs_standalone_stat; xvfs_tclfs_standalone_fs.accessProc = NULL; xvfs_tclfs_standalone_fs.openFileChannelProc = xvfs_tclfs_standalone_openFileChannel; | | | 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 | xvfs_tclfs_standalone_fs.createInternalRepProc = NULL; xvfs_tclfs_standalone_fs.normalizePathProc = NULL; xvfs_tclfs_standalone_fs.filesystemPathTypeProc = NULL; xvfs_tclfs_standalone_fs.filesystemSeparatorProc = NULL; xvfs_tclfs_standalone_fs.statProc = xvfs_tclfs_standalone_stat; xvfs_tclfs_standalone_fs.accessProc = NULL; xvfs_tclfs_standalone_fs.openFileChannelProc = xvfs_tclfs_standalone_openFileChannel; xvfs_tclfs_standalone_fs.matchInDirectoryProc = xvfs_tclfs_standalone_matchInDir; xvfs_tclfs_standalone_fs.utimeProc = NULL; xvfs_tclfs_standalone_fs.linkProc = NULL; xvfs_tclfs_standalone_fs.listVolumesProc = xvfs_tclfs_standalone_listVolumes; xvfs_tclfs_standalone_fs.fileAttrStringsProc = NULL; xvfs_tclfs_standalone_fs.fileAttrsGetProc = NULL; xvfs_tclfs_standalone_fs.fileAttrsSetProc = NULL; xvfs_tclfs_standalone_fs.createDirectoryProc = NULL; |
︙ | ︙ |
Modified xvfs-core.h from [f98af2d91c] to [38b72c1f15].
︙ | ︙ | |||
27 28 29 30 31 32 33 34 35 36 37 38 39 40 | * not be changed. */ #define XVFS_RV_ERR_ENOENT (-8192) #define XVFS_RV_ERR_EINVAL (-8193) #define XVFS_RV_ERR_EISDIR (-8194) #define XVFS_RV_ERR_ENOTDIR (-8195) #define XVFS_RV_ERR_EFAULT (-8196) #define XVFS_REGISTER_INTERFACE(name) int name(Tcl_Interp *interp, struct Xvfs_FSInfo *fsInfo); #if defined(XVFS_MODE_STANDALONE) /* * In standalone mode, we just redefine calls to * Xvfs_Register() to go to the xvfs_standalone_register() | > | 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | * not be changed. */ #define XVFS_RV_ERR_ENOENT (-8192) #define XVFS_RV_ERR_EINVAL (-8193) #define XVFS_RV_ERR_EISDIR (-8194) #define XVFS_RV_ERR_ENOTDIR (-8195) #define XVFS_RV_ERR_EFAULT (-8196) #define XVFS_RV_ERR_INTERNAL (-16383) #define XVFS_REGISTER_INTERFACE(name) int name(Tcl_Interp *interp, struct Xvfs_FSInfo *fsInfo); #if defined(XVFS_MODE_STANDALONE) /* * In standalone mode, we just redefine calls to * Xvfs_Register() to go to the xvfs_standalone_register() |
︙ | ︙ |
Modified xvfs.c.rvt from [b727267b99] to [f6fac50f2f].
︙ | ︙ | |||
190 191 192 193 194 195 196 | statBuf->st_gid = -1; statBuf->st_atime = 0; statBuf->st_ctime = 0; statBuf->st_mtime = 0; statBuf->st_blksize = XVFS_FILE_BLOCKSIZE; if (fileInfo->type == XVFS_FILE_TYPE_REG) { | | | | 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 | statBuf->st_gid = -1; statBuf->st_atime = 0; statBuf->st_ctime = 0; statBuf->st_mtime = 0; statBuf->st_blksize = XVFS_FILE_BLOCKSIZE; if (fileInfo->type == XVFS_FILE_TYPE_REG) { statBuf->st_mode = 0100400; statBuf->st_nlink = 1; statBuf->st_size = fileInfo->size; statBuf->st_blocks = (fileInfo->size + statBuf->st_blksize - 1) / statBuf->st_blksize; } else if (fileInfo->type == XVFS_FILE_TYPE_DIR) { statBuf->st_mode = 040500; statBuf->st_nlink = fileInfo->size; statBuf->st_size = fileInfo->size; statBuf->st_blocks = 1; } return(0); } |
︙ | ︙ |