| ︙ | | |
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
-
+
-
+
|
*
* 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.47 2002/06/10 17:41:52 vincentdarley Exp $
* RCS: @(#) $Id: tclIOUtil.c,v 1.48 2002/06/12 09:28:58 vincentdarley Exp $
*/
#include "tclInt.h"
#include "tclPort.h"
#ifdef MAC_TCL
#include "tclMacInt.h"
#endif
#ifdef __WIN32__
/* For 'file link' */
/* for tclWinProcs->useWide */
#include "tclWinInt.h"
#endif
/*
* Prototypes for procedures defined later in this file.
*/
|
| ︙ | | |
314
315
316
317
318
319
320
321
322
323
324
325
326
327
|
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
|
+
+
+
|
int fileRefCount; /* How many Tcl_Obj's use this
* filesystem. */
struct FilesystemRecord *nextPtr;
/* The next filesystem registered
* to Tcl, or NULL if no more. */
} FilesystemRecord;
static FilesystemRecord* GetFilesystemRecord
_ANSI_ARGS_((Tcl_Filesystem *fromFilesystem, int *epoch));
/*
* Declare the native filesystem support. These functions should
* be considered private to Tcl, and should really not be called
* directly by any code other than this file (i.e. neither by
* Tcl's core nor by extensions). Similarly, the old string-based
* Tclp... native filesystem functions should not be called.
*
|
| ︙ | | |
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
|
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
|
-
+
|
Tcl_FSCopyDirectoryProc TclpObjCopyDirectory;
Tcl_FSRemoveDirectoryProc TclpObjRemoveDirectory;
Tcl_FSUnloadFileProc TclpUnloadFile;
Tcl_FSLinkProc TclpObjLink;
Tcl_FSListVolumesProc TclpObjListVolumes;
/* Define the native filesystem dispatch table */
static Tcl_Filesystem nativeFilesystem = {
Tcl_Filesystem nativeFilesystem = {
"native",
sizeof(Tcl_Filesystem),
TCL_FILESYSTEM_VERSION_1,
&NativePathInFilesystem,
&NativeDupInternalRep,
&NativeFreeInternalRep,
&TclpNativeToNormalized,
|
| ︙ | | |
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
|
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
|
-
+
-
+
+
+
+
-
-
+
+
+
-
-
-
+
|
* New memory may be allocated.
*
*---------------------------------------------------------------------------
*/
Tcl_Obj *
Tcl_FSNewNativePath(fromFilesystem, clientData)
Tcl_Obj* fromFilesystem;
Tcl_Filesystem* fromFilesystem;
ClientData clientData;
{
Tcl_Obj *objPtr;
FsPath *fsPathPtr, *fsFromPtr;
FsPath *fsPathPtr;
FilesystemRecord *fsFromPtr;
Tcl_FSInternalToNormalizedProc *proc;
int epoch;
fsFromPtr = GetFilesystemRecord(fromFilesystem, &epoch);
if (Tcl_FSConvertToPathType(NULL, fromFilesystem) != TCL_OK) {
return NULL;
if (fsFromPtr == NULL) {
return NULL;
}
fsFromPtr = (FsPath*) fromFilesystem->internalRep.otherValuePtr;
proc = fsFromPtr->fsRecPtr->fsPtr->internalToNormalizedProc;
proc = fsFromPtr->fsPtr->internalToNormalizedProc;
if (proc == NULL) {
return NULL;
}
objPtr = (*proc)(clientData);
if (objPtr == NULL) {
|
| ︙ | | |
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
|
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
|
-
+
-
+
|
fsPathPtr = (FsPath*)ckalloc((unsigned)sizeof(FsPath));
fsPathPtr->translatedPathPtr = NULL;
/* Circular reference, by design */
fsPathPtr->normPathPtr = objPtr;
fsPathPtr->cwdPtr = NULL;
fsPathPtr->nativePathPtr = clientData;
fsPathPtr->fsRecPtr = fsFromPtr->fsRecPtr;
fsPathPtr->fsRecPtr = fsFromPtr;
/* We must increase the refCount for this filesystem. */
fsPathPtr->fsRecPtr->fileRefCount++;
fsPathPtr->filesystemEpoch = fsFromPtr->filesystemEpoch;
fsPathPtr->filesystemEpoch = epoch;
objPtr->internalRep.otherValuePtr = (VOID *) fsPathPtr;
objPtr->typePtr = &tclFsPathType;
return objPtr;
}
static void
|
| ︙ | | |
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
|
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
|
+
+
+
+
+
-
-
-
+
+
+
+
-
+
-
+
|
/* Make sure the normalized path is set */
normPtr = Tcl_FSGetNormalizedPath(NULL, pathObjPtr);
str = Tcl_GetStringFromObj(normPtr,&len);
#ifdef __WIN32__
Tcl_WinUtfToTChar(str, len, &ds);
if (tclWinProcs->useWide) {
nativePathPtr = ckalloc((unsigned)(sizeof(WCHAR)+Tcl_DStringLength(&ds)));
memcpy((VOID*)nativePathPtr, (VOID*)Tcl_DStringValue(&ds),
(size_t) (sizeof(WCHAR)+Tcl_DStringLength(&ds)));
} else {
nativePathPtr = ckalloc((unsigned)(2+Tcl_DStringLength(&ds)));
memcpy((VOID*)nativePathPtr, (VOID*)Tcl_DStringValue(&ds),
(size_t) (2+Tcl_DStringLength(&ds)));
nativePathPtr = ckalloc((unsigned)(sizeof(char)+Tcl_DStringLength(&ds)));
memcpy((VOID*)nativePathPtr, (VOID*)Tcl_DStringValue(&ds),
(size_t) (sizeof(char)+Tcl_DStringLength(&ds)));
}
#else
Tcl_UtfToExternalDString(NULL, str, len, &ds);
nativePathPtr = ckalloc((unsigned)(1+Tcl_DStringLength(&ds)));
nativePathPtr = ckalloc((unsigned)(sizeof(char)+Tcl_DStringLength(&ds)));
memcpy((VOID*)nativePathPtr, (VOID*)Tcl_DStringValue(&ds),
(size_t) (1+Tcl_DStringLength(&ds)));
(size_t) (sizeof(char)+Tcl_DStringLength(&ds)));
#endif
Tcl_DStringFree(&ds);
return (ClientData)nativePathPtr;
}
/*
|
| ︙ | | |
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
|
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
|
+
-
-
-
+
+
+
+
+
+
+
|
#ifdef __WIN32__
/*
* Certain native path representations on Windows have this special
* prefix to indicate that they are to be treated specially. For
* example extremely long paths, or symlinks
*/
if (*copy == '\\') {
if (0 == strncmp(copy,"\\??\\",4)) {
copy += 4;
len -= 4;
if (0 == strncmp(copy,"\\??\\",4)) {
copy += 4;
len -= 4;
} else if (0 == strncmp(copy,"\\\\?\\",4)) {
copy += 4;
len -= 4;
}
}
#endif
objPtr = Tcl_NewStringObj(copy,len);
Tcl_DStringFree(&ds);
return objPtr;
|
| ︙ | | |
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
|
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
|
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
|
fsRecPtr = fsRecPtr->nextPtr;
}
done:
FsReleaseIterator();
return retVal;
}
/* Simple helper function */
static FilesystemRecord*
GetFilesystemRecord(fromFilesystem, epoch)
Tcl_Filesystem *fromFilesystem;
int *epoch;
{
FilesystemRecord *fsRecPtr = FsGetIterator();
while (fsRecPtr != NULL) {
if (fsRecPtr->fsPtr == fromFilesystem) {
*epoch = theFilesystemEpoch;
break;
}
}
FsReleaseIterator();
return fsRecPtr;
}
/*
*---------------------------------------------------------------------------
*
* Tcl_FSEqualPaths --
*
* This function tests whether the two paths given are equal path
|
| ︙ | | |