1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
/*
* tclUnixFile.c --
*
* This file contains wrappers around UNIX file handling functions.
* These wrappers mask differences between Windows and UNIX.
*
* Copyright (c) 1995-1998 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: tclUnixFile.c,v 1.17 2002/02/12 14:26:05 davygrvy Exp $
*/
#include "tclInt.h"
#include "tclPort.h"
/*
|
|
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
/*
* tclUnixFile.c --
*
* This file contains wrappers around UNIX file handling functions.
* These wrappers mask differences between Windows and UNIX.
*
* Copyright (c) 1995-1998 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: tclUnixFile.c,v 1.18 2002/02/15 14:28:50 dkf Exp $
*/
#include "tclInt.h"
#include "tclPort.h"
/*
|
| ︙ | | | ︙ | |
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
|
char *
TclpFindExecutable(argv0)
CONST char *argv0; /* The value of the application's argv[0]
* (native). */
{
CONST char *name, *p;
struct stat statBuf;
int length;
Tcl_DString buffer, nameString;
if (argv0 == NULL) {
return NULL;
}
if (tclNativeExecutableName != NULL) {
|
<
|
|
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
char *
TclpFindExecutable(argv0)
CONST char *argv0; /* The value of the application's argv[0]
* (native). */
{
CONST char *name, *p;
Tcl_StatBuf statBuf;
int length;
Tcl_DString buffer, nameString;
if (argv0 == NULL) {
return NULL;
}
if (tclNativeExecutableName != NULL) {
|
| ︙ | | | ︙ | |
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
/*
* INTL: The following calls to access() and stat() should not be
* converted to Tclp routines because they need to operate on native
* strings directly.
*/
if ((access(name, X_OK) == 0) /* INTL: Native. */
&& (stat(name, &statBuf) == 0) /* INTL: Native. */
&& S_ISREG(statBuf.st_mode)) {
goto gotName;
}
if (*p == '\0') {
break;
} else if (*(p+1) == 0) {
p = "./";
|
|
|
|
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
/*
* INTL: The following calls to access() and stat() should not be
* converted to Tclp routines because they need to operate on native
* strings directly.
*/
if ((access(name, X_OK) == 0) /* INTL: Native. */
&& (Tcl_PlatformStat(name, &statBuf) == 0) /* INTL: Native. */
&& S_ISREG(statBuf.st_mode)) {
goto gotName;
}
if (*p == '\0') {
break;
} else if (*(p+1) == 0) {
p = "./";
|
| ︙ | | | ︙ | |
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
|
Tcl_GlobTypeData *types; /* Object containing list of acceptable types.
* May be NULL. In particular the directory
* flag is very important. */
{
CONST char *native, *fname, *dirName;
DIR *d;
Tcl_DString ds;
struct stat statBuf;
int matchHidden;
int nativeDirLen;
int result = TCL_OK;
Tcl_DString dsOrig;
Tcl_Obj *fileNamePtr;
int baseLength;
|
|
|
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
|
Tcl_GlobTypeData *types; /* Object containing list of acceptable types.
* May be NULL. In particular the directory
* flag is very important. */
{
CONST char *native, *fname, *dirName;
DIR *d;
Tcl_DString ds;
Tcl_StatBuf statBuf;
int matchHidden;
int nativeDirLen;
int result = TCL_OK;
Tcl_DString dsOrig;
Tcl_Obj *fileNamePtr;
int baseLength;
|
| ︙ | | | ︙ | |
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
|
/*
* Now open the directory for reading and iterate over the contents.
*/
native = Tcl_UtfToExternalDString(NULL, dirName, -1, &ds);
if ((stat(native, &statBuf) != 0) /* INTL: UTF-8. */
|| !S_ISDIR(statBuf.st_mode)) {
Tcl_DStringFree(&dsOrig);
Tcl_DStringFree(&ds);
return TCL_OK;
}
d = opendir(native); /* INTL: Native. */
|
|
|
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
|
/*
* Now open the directory for reading and iterate over the contents.
*/
native = Tcl_UtfToExternalDString(NULL, dirName, -1, &ds);
if ((Tcl_PlatformStat(native, &statBuf) != 0) /* INTL: UTF-8. */
|| !S_ISDIR(statBuf.st_mode)) {
Tcl_DStringFree(&dsOrig);
Tcl_DStringFree(&ds);
return TCL_OK;
}
d = opendir(native); /* INTL: Native. */
|
| ︙ | | | ︙ | |
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
|
}
nativeDirLen = Tcl_DStringLength(&ds);
while (1) {
Tcl_DString utfDs;
CONST char *utf;
struct dirent *entryPtr;
entryPtr = readdir(d); /* INTL: Native. */
if (entryPtr == NULL) {
break;
}
if (types != NULL && (types->perm & TCL_GLOB_PERM_HIDDEN)) {
/*
* We explicitly asked for hidden files, so turn around
* and ignore any file which isn't hidden.
|
|
|
|
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
|
}
nativeDirLen = Tcl_DStringLength(&ds);
while (1) {
Tcl_DString utfDs;
CONST char *utf;
Tcl_DirEntry *entryPtr;
entryPtr = Tcl_PlatformReaddir(d); /* INTL: Native. */
if (entryPtr == NULL) {
break;
}
if (types != NULL && (types->perm & TCL_GLOB_PERM_HIDDEN)) {
/*
* We explicitly asked for hidden files, so turn around
* and ignore any file which isn't hidden.
|
| ︙ | | | ︙ | |
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
|
if (Tcl_StringMatch(utf, pattern) != 0) {
int typeOk = 1;
Tcl_DStringSetLength(&dsOrig, baseLength);
Tcl_DStringAppend(&dsOrig, utf, -1);
fname = Tcl_DStringValue(&dsOrig);
if (types != NULL) {
struct stat buf;
char *nativeEntry;
Tcl_DStringSetLength(&ds, nativeDirLen);
nativeEntry = Tcl_DStringAppend(&ds, entryPtr->d_name, -1);
/*
* The native name of the file is in entryPtr->d_name.
* We can use this below.
*/
if (types->perm != 0) {
if (stat(nativeEntry, &buf) != 0) {
/*
* Either the file has disappeared between the
* 'readdir' call and the 'stat' call, or
* the file is a link to a file which doesn't
* exist (which we could ascertain with
* lstat), or there is some other strange
* problem. In all these cases, we define this
|
|
|
|
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
|
if (Tcl_StringMatch(utf, pattern) != 0) {
int typeOk = 1;
Tcl_DStringSetLength(&dsOrig, baseLength);
Tcl_DStringAppend(&dsOrig, utf, -1);
fname = Tcl_DStringValue(&dsOrig);
if (types != NULL) {
Tcl_StatBuf buf;
char *nativeEntry;
Tcl_DStringSetLength(&ds, nativeDirLen);
nativeEntry = Tcl_DStringAppend(&ds, entryPtr->d_name, -1);
/*
* The native name of the file is in entryPtr->d_name.
* We can use this below.
*/
if (types->perm != 0) {
if (Tcl_PlatformStat(nativeEntry, &buf) != 0) {
/*
* Either the file has disappeared between the
* 'readdir' call and the 'stat' call, or
* the file is a link to a file which doesn't
* exist (which we could ascertain with
* lstat), or there is some other strange
* problem. In all these cases, we define this
|
| ︙ | | | ︙ | |
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
|
)) {
typeOk = 0;
}
}
if (typeOk && (types->type != 0)) {
if (types->perm == 0) {
/* We haven't yet done a stat on the file */
if (stat(nativeEntry, &buf) != 0) {
/* Posix error occurred */
typeOk = 0;
}
}
if (typeOk) {
/*
* In order bcdpfls as in 'find -t'
|
|
|
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
|
)) {
typeOk = 0;
}
}
if (typeOk && (types->type != 0)) {
if (types->perm == 0) {
/* We haven't yet done a stat on the file */
if (Tcl_PlatformStat(nativeEntry, &buf) != 0) {
/* Posix error occurred */
typeOk = 0;
}
}
if (typeOk) {
/*
* In order bcdpfls as in 'find -t'
|
| ︙ | | | ︙ | |
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
|
S_ISSOCK(buf.st_mode))
#endif
) {
/* Do nothing -- this file is ok */
} else {
typeOk = 0;
#ifdef S_ISLNK
if (types->type & TCL_GLOB_TYPE_LINK) {
if (lstat(nativeEntry, &buf) == 0) {
if (S_ISLNK(buf.st_mode)) {
typeOk = 1;
}
}
}
#endif
}
}
}
}
if (typeOk) {
|
|
|
|
|
<
<
|
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
|
S_ISSOCK(buf.st_mode))
#endif
) {
/* Do nothing -- this file is ok */
} else {
typeOk = 0;
#ifdef S_ISLNK
if ((types->type & TCL_GLOB_TYPE_LINK)
&& Tcl_PlatformLStat(nativeEntry, &buf)==0
&& S_ISLNK(buf.st_mode)) {
typeOk = 1;
}
#endif
}
}
}
}
if (typeOk) {
|
| ︙ | | | ︙ | |
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
|
*
*----------------------------------------------------------------------
*/
int
TclpObjLstat(pathPtr, bufPtr)
Tcl_Obj *pathPtr; /* Path of file to stat */
struct stat *bufPtr; /* Filled with results of stat call. */
{
CONST char *path = Tcl_FSGetNativePath(pathPtr);
if (path == NULL) {
return -1;
} else {
return lstat(path, bufPtr);
}
}
/*
*---------------------------------------------------------------------------
*
* TclpObjGetCwd --
|
|
|
|
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
|
*
*----------------------------------------------------------------------
*/
int
TclpObjLstat(pathPtr, bufPtr)
Tcl_Obj *pathPtr; /* Path of file to stat */
Tcl_StatBuf *bufPtr; /* Filled with results of stat call. */
{
CONST char *path = Tcl_FSGetNativePath(pathPtr);
if (path == NULL) {
return -1;
} else {
return Tcl_PlatformLStat(path, bufPtr);
}
}
/*
*---------------------------------------------------------------------------
*
* TclpObjGetCwd --
|
| ︙ | | | ︙ | |
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
|
*
*----------------------------------------------------------------------
*/
int
TclpObjStat(pathPtr, bufPtr)
Tcl_Obj *pathPtr; /* Path of file to stat */
struct stat *bufPtr; /* Filled with results of stat call. */
{
CONST char *path = Tcl_FSGetNativePath(pathPtr);
if (path == NULL) {
return -1;
} else {
return stat(path, bufPtr);
}
}
#ifdef S_IFLNK
Tcl_Obj*
|
|
|
|
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
|
*
*----------------------------------------------------------------------
*/
int
TclpObjStat(pathPtr, bufPtr)
Tcl_Obj *pathPtr; /* Path of file to stat */
Tcl_StatBuf *bufPtr; /* Filled with results of stat call. */
{
CONST char *path = Tcl_FSGetNativePath(pathPtr);
if (path == NULL) {
return -1;
} else {
return Tcl_PlatformStat(path, bufPtr);
}
}
#ifdef S_IFLNK
Tcl_Obj*
|
| ︙ | | | ︙ | |
736
737
738
739
740
741
742
743
744
745
|
linkPtr = Tcl_FSNewNativePath(pathPtr, native);
Tcl_IncrRefCount(linkPtr);
}
return linkPtr;
}
#endif
|
<
<
<
|
733
734
735
736
737
738
739
|
linkPtr = Tcl_FSNewNativePath(pathPtr, native);
Tcl_IncrRefCount(linkPtr);
}
return linkPtr;
}
#endif
|