| ︙ | | | ︙ | |
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
*
* Copyright (c) 1991-1994 The Regents of the University of California.
* Copyright (c) 1994-1997 Sun Microsystems, Inc.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* RCS: @(#) $Id: tclIOUtil.c,v 1.62 2002/07/21 17:03:00 dgp Exp $
*/
#include "tclInt.h"
#include "tclPort.h"
#ifdef MAC_TCL
#include "tclMacInt.h"
#endif
|
|
|
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
*
* Copyright (c) 1991-1994 The Regents of the University of California.
* Copyright (c) 1994-1997 Sun Microsystems, Inc.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* RCS: @(#) $Id: tclIOUtil.c,v 1.63 2002/07/22 16:51:48 vincentdarley Exp $
*/
#include "tclInt.h"
#include "tclPort.h"
#ifdef MAC_TCL
#include "tclMacInt.h"
#endif
|
| ︙ | | | ︙ | |
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
|
Tcl_FSCreateDirectoryProc TclpObjCreateDirectory;
Tcl_FSCopyDirectoryProc TclpObjCopyDirectory;
Tcl_FSRemoveDirectoryProc TclpObjRemoveDirectory;
Tcl_FSUnloadFileProc TclpUnloadFile;
Tcl_FSLinkProc TclpObjLink;
Tcl_FSListVolumesProc TclpObjListVolumes;
/* Define the native filesystem dispatch table */
Tcl_Filesystem tclNativeFilesystem = {
"native",
sizeof(Tcl_Filesystem),
TCL_FILESYSTEM_VERSION_1,
&NativePathInFilesystem,
&NativeDupInternalRep,
&NativeFreeInternalRep,
&TclpNativeToNormalized,
|
>
|
>
>
>
>
>
>
|
|
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
|
Tcl_FSCreateDirectoryProc TclpObjCreateDirectory;
Tcl_FSCopyDirectoryProc TclpObjCopyDirectory;
Tcl_FSRemoveDirectoryProc TclpObjRemoveDirectory;
Tcl_FSUnloadFileProc TclpUnloadFile;
Tcl_FSLinkProc TclpObjLink;
Tcl_FSListVolumesProc TclpObjListVolumes;
/*
* Define the native filesystem dispatch table. If necessary, it
* is ok to make this non-static, but it should only be accessed
* by the functions actually listed within it (or perhaps other
* helper functions of them). Anything which is not part of this
* 'native filesystem implementation' should not be delving inside
* here!
*/
static Tcl_Filesystem tclNativeFilesystem = {
"native",
sizeof(Tcl_Filesystem),
TCL_FILESYSTEM_VERSION_1,
&NativePathInFilesystem,
&NativeDupInternalRep,
&NativeFreeInternalRep,
&TclpNativeToNormalized,
|
| ︙ | | | ︙ | |
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
|
&TclpObjCreateDirectory,
&TclpObjRemoveDirectory,
&TclpObjDeleteFile,
&TclpObjCopyFile,
&TclpObjRenameFile,
&TclpObjCopyDirectory,
&TclpObjLstat,
&TclpLoadFile,
&TclpObjGetCwd,
&TclpObjChdir
};
/*
* Define the tail of the linked list. Note that for unconventional
* uses of Tcl without a native filesystem, we may in the future wish
|
|
|
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
|
&TclpObjCreateDirectory,
&TclpObjRemoveDirectory,
&TclpObjDeleteFile,
&TclpObjCopyFile,
&TclpObjRenameFile,
&TclpObjCopyDirectory,
&TclpObjLstat,
&TclpDlopen,
&TclpObjGetCwd,
&TclpObjChdir
};
/*
* Define the tail of the linked list. Note that for unconventional
* uses of Tcl without a native filesystem, we may in the future wish
|
| ︙ | | | ︙ | |
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
|
*----------------------------------------------------------------------
*
* TclFinalizeFilesystem --
*
* Clean up the filesystem. After this, calls to all Tcl_FS...
* functions will fail.
*
* Note that, since 'TclFinalizedLoad' may unload extensions
* which implement other filesystems, and which may therefore
* contain a 'freeProc' for those filesystems, at this stage
* we _must_ have freed all objects of "path" type, or we may
* end up with segfaults if we try to free them later.
*
* Results:
* None.
|
|
|
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
|
*----------------------------------------------------------------------
*
* TclFinalizeFilesystem --
*
* Clean up the filesystem. After this, calls to all Tcl_FS...
* functions will fail.
*
* Note that, since 'TclFinalizeLoad' may unload extensions
* which implement other filesystems, and which may therefore
* contain a 'freeProc' for those filesystems, at this stage
* we _must_ have freed all objects of "path" type, or we may
* end up with segfaults if we try to free them later.
*
* Results:
* None.
|
| ︙ | | | ︙ | |
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
|
* unloaded by passing the clientData to the unloadProc.
*
*----------------------------------------------------------------------
*/
int
Tcl_FSLoadFile(interp, pathPtr, sym1, sym2, proc1Ptr, proc2Ptr,
clientDataPtr, unloadProcPtr)
Tcl_Interp *interp; /* Used for error reporting. */
Tcl_Obj *pathPtr; /* Name of the file containing the desired
* code. */
CONST char *sym1, *sym2; /* Names of two procedures to look up in
* the file's symbol table. */
Tcl_PackageInitProc **proc1Ptr, **proc2Ptr;
/* Where to return the addresses corresponding
* to sym1 and sym2. */
ClientData *clientDataPtr; /* Filled with token for dynamically loaded
* file which will be passed back to
* (*unloadProcPtr)() to unload the file. */
Tcl_FSUnloadFileProc **unloadProcPtr;
/* Filled with address of Tcl_FSUnloadFileProc
* function which should be used for
* this file. */
{
Tcl_Filesystem *fsPtr = Tcl_FSGetFileSystemForPath(pathPtr);
if (fsPtr != NULL) {
Tcl_FSLoadFileProc *proc = fsPtr->loadFileProc;
if (proc != NULL) {
int retVal = (*proc)(interp, pathPtr, sym1, sym2,
proc1Ptr, proc2Ptr, clientDataPtr,
unloadProcPtr);
return retVal;
} else {
Tcl_Filesystem *copyFsPtr;
Tcl_Obj *copyToPtr;
/* First check if it is readable -- and exists! */
if (Tcl_FSAccess(pathPtr, R_OK) != 0) {
|
|
|
|
|
>
>
|
>
>
>
>
|
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
|
* unloaded by passing the clientData to the unloadProc.
*
*----------------------------------------------------------------------
*/
int
Tcl_FSLoadFile(interp, pathPtr, sym1, sym2, proc1Ptr, proc2Ptr,
handlePtr, unloadProcPtr)
Tcl_Interp *interp; /* Used for error reporting. */
Tcl_Obj *pathPtr; /* Name of the file containing the desired
* code. */
CONST char *sym1, *sym2; /* Names of two procedures to look up in
* the file's symbol table. */
Tcl_PackageInitProc **proc1Ptr, **proc2Ptr;
/* Where to return the addresses corresponding
* to sym1 and sym2. */
Tcl_LoadHandle *handlePtr; /* Filled with token for dynamically loaded
* file which will be passed back to
* (*unloadProcPtr)() to unload the file. */
Tcl_FSUnloadFileProc **unloadProcPtr;
/* Filled with address of Tcl_FSUnloadFileProc
* function which should be used for
* this file. */
{
Tcl_Filesystem *fsPtr = Tcl_FSGetFileSystemForPath(pathPtr);
if (fsPtr != NULL) {
Tcl_FSLoadFileProc *proc = fsPtr->loadFileProc;
if (proc != NULL) {
int retVal = (*proc)(interp, pathPtr, handlePtr, unloadProcPtr);
if (retVal != TCL_OK) {
return retVal;
}
if (*handlePtr == NULL) {
return TCL_ERROR;
}
*proc1Ptr = TclpFindSymbol(interp, *handlePtr, sym1);
*proc2Ptr = TclpFindSymbol(interp, *handlePtr, sym2);
return retVal;
} else {
Tcl_Filesystem *copyFsPtr;
Tcl_Obj *copyToPtr;
/* First check if it is readable -- and exists! */
if (Tcl_FSAccess(pathPtr, R_OK) != 0) {
|
| ︙ | | | ︙ | |
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
|
Tcl_LoadHandle newLoadHandle = NULL;
Tcl_FSUnloadFileProc *newUnloadProcPtr = NULL;
FsDivertLoad *tvdlPtr;
int retVal;
retVal = Tcl_FSLoadFile(interp, copyToPtr, sym1, sym2,
proc1Ptr, proc2Ptr,
(ClientData*)&newLoadHandle,
&newUnloadProcPtr);
if (retVal != TCL_OK) {
/* The file didn't load successfully */
Tcl_FSDeleteFile(copyToPtr);
Tcl_DecrRefCount(copyToPtr);
return retVal;
}
/*
* Try to delete the file immediately -- this is
* possible in some OSes, and avoids any worries
* about leaving the copy laying around on exit.
*/
if (Tcl_FSDeleteFile(copyToPtr) == TCL_OK) {
Tcl_DecrRefCount(copyToPtr);
(*clientDataPtr) = NULL;
(*unloadProcPtr) = NULL;
return TCL_OK;
}
/*
* When we unload this file, we need to divert the
* unloading so we can unload and cleanup the
* temporary file correctly.
|
|
|
|
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
|
Tcl_LoadHandle newLoadHandle = NULL;
Tcl_FSUnloadFileProc *newUnloadProcPtr = NULL;
FsDivertLoad *tvdlPtr;
int retVal;
retVal = Tcl_FSLoadFile(interp, copyToPtr, sym1, sym2,
proc1Ptr, proc2Ptr,
&newLoadHandle,
&newUnloadProcPtr);
if (retVal != TCL_OK) {
/* The file didn't load successfully */
Tcl_FSDeleteFile(copyToPtr);
Tcl_DecrRefCount(copyToPtr);
return retVal;
}
/*
* Try to delete the file immediately -- this is
* possible in some OSes, and avoids any worries
* about leaving the copy laying around on exit.
*/
if (Tcl_FSDeleteFile(copyToPtr) == TCL_OK) {
Tcl_DecrRefCount(copyToPtr);
(*handlePtr) = NULL;
(*unloadProcPtr) = NULL;
return TCL_OK;
}
/*
* When we unload this file, we need to divert the
* unloading so we can unload and cleanup the
* temporary file correctly.
|
| ︙ | | | ︙ | |
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
|
* disappearing on us.
*/
tvdlPtr->divertedFilesystem = copyFsPtr;
/* Get the native representation of the file path */
tvdlPtr->divertedFileNativeRep = Tcl_FSGetInternalRep(copyToPtr,
copyFsPtr);
copyToPtr = NULL;
(*clientDataPtr) = (ClientData) tvdlPtr;
(*unloadProcPtr) = &FSUnloadTempFile;
return retVal;
} else {
/* Cross-platform copy failed */
Tcl_FSDeleteFile(copyToPtr);
Tcl_DecrRefCount(copyToPtr);
|
|
|
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
|
* disappearing on us.
*/
tvdlPtr->divertedFilesystem = copyFsPtr;
/* Get the native representation of the file path */
tvdlPtr->divertedFileNativeRep = Tcl_FSGetInternalRep(copyToPtr,
copyFsPtr);
copyToPtr = NULL;
(*handlePtr) = (Tcl_LoadHandle) tvdlPtr;
(*unloadProcPtr) = &FSUnloadTempFile;
return retVal;
} else {
/* Cross-platform copy failed */
Tcl_FSDeleteFile(copyToPtr);
Tcl_DecrRefCount(copyToPtr);
|
| ︙ | | | ︙ | |