| ︙ | | |
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
|
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
|
-
+
|
&TclpObjRemoveDirectory,
&TclpObjDeleteFile,
&TclpObjCopyFile,
&TclpObjRenameFile,
&TclpObjCopyDirectory,
&TclpObjLstat,
&TclpDlopen,
/* Needs a cast since we're using version_2 */
/* Needs a cast since we're using version_2. */
(Tcl_FSGetCwdProc *) &TclpGetNativeCwd,
&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 to modify the
|
| ︙ | | |
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
|
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
|
-
-
+
+
-
+
|
* Note that ino_t/ino64_t is unsigned...
*
* Workaround gcc warning of "comparison is always false due to
* limited range of data type" by assigning to tmp var of type
* Tcl_WideInt.
*/
tmp1 = (Tcl_WideInt) buf.st_ino;
tmp2 = (Tcl_WideInt) buf.st_size;
tmp1 = (Tcl_WideInt) buf.st_ino;
tmp2 = (Tcl_WideInt) buf.st_size;
#ifdef HAVE_ST_BLOCKS
tmp3 = (Tcl_WideInt) buf.st_blocks;
tmp3 = (Tcl_WideInt) buf.st_blocks;
#endif
if (OUT_OF_URANGE(tmp1) || OUT_OF_RANGE(tmp2)
#ifdef HAVE_ST_BLOCKS
|| OUT_OF_RANGE(tmp3)
#endif
) {
|
| ︙ | | |
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
|
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
|
-
+
|
Tcl_IncrRefCount(pathPtr);
ret = Tcl_FSEvalFile(interp, pathPtr);
Tcl_DecrRefCount(pathPtr);
return ret;
}
/*
* Now move on to the basic filesystem implementation
* Now move on to the basic filesystem implementation.
*/
static void
FsThrExitProc(
ClientData cd)
{
ThreadSpecificData *tsdPtr = cd;
|
| ︙ | | |
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
|
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
|
-
+
|
if (cwdClientData != NULL) {
NativeFreeInternalRep(cwdClientData);
cwdClientData = NULL;
}
/*
* Remove all filesystems, freeing any allocated memory that is no longer
* needed
* needed.
*/
fsRecPtr = filesystemList;
while (fsRecPtr != NULL) {
FilesystemRecord *tmpFsRecPtr = fsRecPtr->nextPtr;
if (fsRecPtr->fileRefCount <= 0) {
|
| ︙ | | |
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
|
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
|
-
+
|
* Memory allocated and modifies the link list for filesystems.
*
*----------------------------------------------------------------------
*/
int
Tcl_FSRegister(
ClientData clientData, /* Client specific data for this fs */
ClientData clientData, /* Client specific data for this fs. */
const Tcl_Filesystem *fsPtr)/* The filesystem record for the new fs. */
{
FilesystemRecord *newFilesystemPtr;
if (fsPtr == NULL) {
return TCL_ERROR;
}
|
| ︙ | | |
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
|
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
|
-
+
|
*
*----------------------------------------------------------------------
*/
int
Tcl_FSMatchInDirectory(
Tcl_Interp *interp, /* Interpreter to receive error messages, but
* may be NULL. */
* may be NULL. */
Tcl_Obj *resultPtr, /* List object to receive results. */
Tcl_Obj *pathPtr, /* Contains path to directory to search. */
const char *pattern, /* Pattern to match against. */
Tcl_GlobTypeData *types) /* Object containing list of acceptable types.
* May be NULL. In particular the directory
* flag is very important. */
{
|
| ︙ | | |
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
|
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
|
-
+
|
FsAddMountsToGlobResult(resultPtr, pathPtr, pattern, types);
}
return ret;
}
/*
* If the path isn't empty, we have no idea how to match files in a
* directory which belongs to no known filesystem
* directory which belongs to no known filesystem.
*/
if (pathPtr != NULL && TclGetString(pathPtr)[0] != '\0') {
Tcl_SetErrno(ENOENT);
return -1;
}
|
| ︙ | | |
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
|
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
|
-
+
|
*----------------------------------------------------------------------
*/
static void
FsAddMountsToGlobResult(
Tcl_Obj *resultPtr, /* The current list of matching paths; must
* not be shared! */
Tcl_Obj *pathPtr, /* The directory in question */
Tcl_Obj *pathPtr, /* The directory in question. */
const char *pattern, /* Pattern to match against. */
Tcl_GlobTypeData *types) /* Object containing list of acceptable types.
* May be NULL. In particular the directory
* flag is very important. */
{
int mLength, gLength, i;
int dir = (types == NULL || (types->type & TCL_GLOB_TYPE_DIR));
|
| ︙ | | |
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
|
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
|
-
+
|
/*
* We don't want to list this.
*/
Tcl_ListObjReplace(NULL, resultPtr, j, 1, 0, NULL);
gLength--;
}
break; /* Break out of for loop */
break; /* Break out of for loop. */
}
}
if (!found && dir) {
Tcl_Obj *norm;
int len, mlen;
/*
|
| ︙ | | |
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
|
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
|
-
-
+
+
|
*
*---------------------------------------------------------------------------
*/
int
TclFSNormalizeToUniquePath(
Tcl_Interp *interp, /* Used for error messages. */
Tcl_Obj *pathPtr, /* The path to normalize in place */
int startAt, /* Start at this char-offset */
Tcl_Obj *pathPtr, /* The path to normalize in place. */
int startAt, /* Start at this char-offset. */
ClientData *clientDataPtr) /* If we generated a complete normalized path
* for a given filesystem, we can optionally
* return an fs-specific clientdata here. */
{
FilesystemRecord *fsRecPtr, *firstFsRecPtr;
/* Ignore this variable */
(void) clientDataPtr;
|
| ︙ | | |
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
|
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
|
-
+
|
Tcl_Interp *interp, /* Interpreter to use for error reporting -
* may be NULL. */
const char *modeString, /* Mode string, e.g. "r+" or "RDONLY CREAT" */
int *seekFlagPtr, /* Set this to 1 if the caller should seek to
* EOF during the opening of the file. */
int *binaryPtr) /* Set this to 1 if the caller should
* configure the opened channel for binary
* operations */
* operations. */
{
int mode, modeArgc, c, i, gotRW;
const char **modeArgv, *flag;
#define RW_MODES (O_RDONLY|O_WRONLY|O_RDWR)
/*
* Check for the simpler fopen-like access modes (e.g. "r"). They are
|
| ︙ | | |
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
|
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
|
-
+
|
result = TclUpdateReturnInfo(iPtr);
} else if (result == TCL_ERROR) {
/*
* Record information telling where the error occurred.
*/
const char *pathString = Tcl_GetStringFromObj(pathPtr, &length);
int limit = 150;
const int limit = 150;
int overflow = (length > limit);
Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
"\n (file \"%.*s%s\" line %d)",
(overflow ? limit : length), pathString,
(overflow ? "..." : ""), Tcl_GetErrorLine(interp)));
}
|
| ︙ | | |
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
|
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
|
-
+
+
|
* See utime documentation.
*
*----------------------------------------------------------------------
*/
int
Tcl_FSUtime(
Tcl_Obj *pathPtr, /* File to change access/modification times */
Tcl_Obj *pathPtr, /* File to change access/modification
* times. */
struct utimbuf *tval) /* Structure containing access/modification
* times to use. Should not be modified. */
{
const Tcl_Filesystem *fsPtr = Tcl_FSGetFileSystemForPath(pathPtr);
if (fsPtr != NULL && fsPtr->utimeProc != NULL) {
return fsPtr->utimeProc(pathPtr, tval);
|
| ︙ | | |
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
|
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
|
+
-
+
+
+
|
}
proc2 = (TclFSGetCwdProc2 *) fsRecPtr->fsPtr->getCwdProc;
retCd = proc2(NULL);
if (retCd != NULL) {
Tcl_Obj *norm;
/*
/* Looks like a new current directory */
* Looks like a new current directory.
*/
retVal = fsRecPtr->fsPtr->internalToNormalizedProc(retCd);
Tcl_IncrRefCount(retVal);
norm = TclFSNormalizeAbsolutePath(interp,retVal,NULL);
if (norm != NULL) {
/*
* We found a cwd, which is now in our global storage. We
* must make a copy. Norm already has a refCount of 1.
|
| ︙ | | |
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
|
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
|
-
+
|
Tcl_StatBuf buf;
/*
* If the file can be stat'ed and is a directory and is readable,
* then we can chdir. If any of these actions fail, then
* 'Tcl_SetErrno()' should automatically have been called to set
* an appropriate error code
* an appropriate error code.
*/
if ((Tcl_FSStat(pathPtr, &buf) == 0) && (S_ISDIR(buf.st_mode))
&& (Tcl_FSAccess(pathPtr, R_OK) == 0)) {
/*
* We allow the chdir.
*/
|
| ︙ | | |
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
|
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
|
-
+
|
}
}
return TCL_OK;
}
/*
* This function used to be in the platform specific directories, but it has
* now been made to work cross-platform
* now been made to work cross-platform.
*/
int
TclpLoadFile(
Tcl_Interp *interp, /* Used for error reporting. */
Tcl_Obj *pathPtr, /* Name of the file containing the desired
* code (UTF-8). */
|
| ︙ | | |
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
|
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
|
-
-
-
+
+
+
|
* See readlink() documentation. A new filesystem link object may appear.
*
*---------------------------------------------------------------------------
*/
Tcl_Obj *
Tcl_FSLink(
Tcl_Obj *pathPtr, /* Path of file to readlink or link */
Tcl_Obj *toPtr, /* NULL or path to be linked to */
int linkAction) /* Action to perform */
Tcl_Obj *pathPtr, /* Path of file to readlink or link. */
Tcl_Obj *toPtr, /* NULL or path to be linked to. */
int linkAction) /* Action to perform. */
{
const Tcl_Filesystem *fsPtr = Tcl_FSGetFileSystemForPath(pathPtr);
if (fsPtr != NULL && fsPtr->linkProc != NULL) {
return fsPtr->linkProc(pathPtr, toPtr, linkAction);
}
|
| ︙ | | |
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
|
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
|
-
+
|
if (lenPtr != NULL) {
TclListObjLength(NULL, result, lenPtr);
}
return result;
}
/* Simple helper function */
/* Simple helper function. */
Tcl_Obj *
TclFSInternalToNormalized(
const Tcl_Filesystem *fromFilesystem,
ClientData clientData,
FilesystemRecord **fsRecPtrPtr)
{
FilesystemRecord *fsRecPtr = FsGetFirstFilesystem();
|
| ︙ | | |
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
|
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
|
-
+
|
* None.
*
*----------------------------------------------------------------------
*/
Tcl_PathType
TclGetPathType(
Tcl_Obj *pathPtr, /* Path to determine type for */
Tcl_Obj *pathPtr, /* Path to determine type for. */
const Tcl_Filesystem **filesystemPtrPtr,
/* If absolute path and this is not NULL, then
* set to the filesystem which claims this
* path. */
int *driveNameLengthPtr, /* If the path is absolute, and this is
* non-NULL, then set to the length of the
* driveName. */
|
| ︙ | | |
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
|
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
|
-
-
+
+
|
* None.
*
*----------------------------------------------------------------------
*/
Tcl_PathType
TclFSNonnativePathType(
const char *path, /* Path to determine type for */
int pathLen, /* Length of the path */
const char *path, /* Path to determine type for. */
int pathLen, /* Length of the path. */
const Tcl_Filesystem **filesystemPtrPtr,
/* If absolute path and this is not NULL, then
* set to the filesystem which claims this
* path. */
int *driveNameLengthPtr, /* If the path is absolute, and this is
* non-NULL, then set to the length of the
* driveName. */
|
| ︙ | | |
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
|
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
|
-
+
|
* A file may be created.
*
*---------------------------------------------------------------------------
*/
int
TclCrossFilesystemCopy(
Tcl_Interp *interp, /* For error messages */
Tcl_Interp *interp, /* For error messages. */
Tcl_Obj *source, /* Pathname of file to be copied (UTF-8). */
Tcl_Obj *target) /* Pathname of file to copy to (UTF-8). */
{
int result = TCL_ERROR;
int prot = 0666;
Tcl_Channel in, out;
Tcl_StatBuf sourceStatBuf;
|
| ︙ | | |