Diff
Not logged in

Differences From Artifact [4a08a53f73]:

To Artifact [82f43fedb1]:


1
2
3
4
5
6
7
8
9
10
11
12

13
14
15
16
17
18
19
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.12.8.2 2002/06/10 05:33:18 wolfsuit Exp $
 * RCS: @(#) $Id: tclUnixFile.c,v 1.12.8.3 2002/08/20 20:25:30 das Exp $
 */

#include "tclInt.h"
#include "tclPort.h"

static int NativeMatchType(CONST char* nativeName, Tcl_GlobTypeData *types);

114
115
116
117
118
119
120
121
122


123
124
125
126
127
128
129
114
115
116
117
118
119
120


121
122
123
124
125
126
127
128
129







-
-
+
+








	/*
	 * 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. */
	if ((access(name, X_OK) == 0)			/* INTL: Native. */
		&& (TclOSstat(name, &statBuf) == 0)	/* INTL: Native. */
		&& S_ISREG(statBuf.st_mode)) {
	    goto gotName;
	}
	if (*p == '\0') {
	    break;
	} else if (*(p+1) == 0) {
	    p = "./";
269
270
271
272
273
274
275
276

277
278
279
280
281
282
283
269
270
271
272
273
274
275

276
277
278
279
280
281
282
283







-
+








	/*
	 * 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. */
	if ((TclOSstat(native, &statBuf) != 0)		/* INTL: Native. */
		|| !S_ISDIR(statBuf.st_mode)) {
	    Tcl_DStringFree(&dsOrig);
	    Tcl_DStringFree(&ds);
	    return TCL_OK;
	}

	d = opendir(native);				/* INTL: Native. */
309
310
311
312
313
314
315
316

317
318
319
320
321
322
323
309
310
311
312
313
314
315

316
317
318
319
320
321
322
323







-
+







	nativeDirLen = Tcl_DStringLength(&ds);

	while (1) {
	    Tcl_DString utfDs;
	    CONST char *utf;
	    Tcl_DirEntry *entryPtr;
	    
	    entryPtr = Tcl_PlatformReaddir(d);		/* INTL: Native. */
	    entryPtr = TclOSreaddir(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.
374
375
376
377
378
379
380
381

382
383
384
385
386

387
388
389
390
391
392
393
374
375
376
377
378
379
380

381
382
383
384
385

386
387
388
389
390
391
392
393







-
+




-
+







    if (types == NULL) {
	/* 
	 * Simply check for the file's existence, but do it
	 * with lstat, in case it is a link to a file which
	 * doesn't exist (since that case would not show up
	 * if we used 'access' or 'stat')
	 */
	if (Tcl_PlatformLStat(nativeEntry, &buf) != 0) {
	if (TclOSlstat(nativeEntry, &buf) != 0) {
	    return 0;
	}
    } else {
	if (types->perm != 0) {
	    if (Tcl_PlatformStat(nativeEntry, &buf) != 0) {
	    if (TclOSstat(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
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
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







-
+


















-
+


-
+



-
+

-
+





-
+







		) {
		return 0;
	    }
	}
	if (types->type != 0) {
	    if (types->perm == 0) {
		/* We haven't yet done a stat on the file */
		if (Tcl_PlatformStat(nativeEntry, &buf) != 0) {
		if (TclOSstat(nativeEntry, &buf) != 0) {
		    /* Posix error occurred */
		    return 0;
		}
	    }
	    /*
	     * In order bcdpfls as in 'find -t'
	     */
	    if (
		((types->type & TCL_GLOB_TYPE_BLOCK) &&
			S_ISBLK(buf.st_mode)) ||
		((types->type & TCL_GLOB_TYPE_CHAR) &&
			S_ISCHR(buf.st_mode)) ||
		((types->type & TCL_GLOB_TYPE_DIR) &&
			S_ISDIR(buf.st_mode)) ||
		((types->type & TCL_GLOB_TYPE_PIPE) &&
			S_ISFIFO(buf.st_mode)) ||
		((types->type & TCL_GLOB_TYPE_FILE) &&
			S_ISREG(buf.st_mode))
    #ifdef S_ISSOCK
#ifdef S_ISSOCK
		|| ((types->type & TCL_GLOB_TYPE_SOCK) &&
			S_ISSOCK(buf.st_mode))
    #endif
#endif /* S_ISSOCK */
		) {
		/* Do nothing -- this file is ok */
	    } else {
    #ifdef S_ISLNK
#ifdef S_ISLNK
		if (types->type & TCL_GLOB_TYPE_LINK) {
		    if (Tcl_PlatformLStat(nativeEntry, &buf) == 0) {
		    if (TclOSlstat(nativeEntry, &buf) == 0) {
			if (S_ISLNK(buf.st_mode)) {
			    return 1;
			}
		    }
		}
    #endif
#endif /* S_ISLNK */
		return 0;
	    }
	}
    }
    return 1;
}

577
578
579
580
581
582
583
584

585
586
587
588
589
590
591
577
578
579
580
581
582
583

584
585
586
587
588
589
590
591







-
+







 */

int 
TclpObjLstat(pathPtr, bufPtr)
    Tcl_Obj *pathPtr;		/* Path of file to stat */
    Tcl_StatBuf *bufPtr;	/* Filled with results of stat call. */
{
    return Tcl_PlatformLStat(Tcl_FSGetNativePath(pathPtr), bufPtr);
    return TclOSlstat(Tcl_FSGetNativePath(pathPtr), bufPtr);
}

/*
 *---------------------------------------------------------------------------
 *
 * TclpObjGetCwd --
 *
683
684
685
686
687
688
689
690

691
692
693
694
695
696
697
683
684
685
686
687
688
689

690
691
692
693
694
695
696
697







-
+







    if (length < 0) {
	return NULL;
    }

    Tcl_ExternalToUtfDString(NULL, link, length, linkPtr);
    return Tcl_DStringValue(linkPtr);
#else
	return NULL;
    return NULL;
#endif
}

/*
 *----------------------------------------------------------------------
 *
 * TclpObjStat --
712
713
714
715
716
717
718
719

720
721
722
723
724
725
726
727

728
729

730



731
732
733
734
735






























736
737
738

739

740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755

756
757
758
759








760
761
762
763
764
765
766
712
713
714
715
716
717
718

719
720
721
722
723
724
725
726

727
728
729
730
731
732
733
734





735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768

769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786




787
788
789
790
791
792
793
794
795
796
797
798
799
800
801







-
+







-
+


+

+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+



+
-
+
















+
-
-
-
-
+
+
+
+
+
+
+
+







    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);
	return TclOSstat(path, bufPtr);
    }
}


#ifdef S_IFLNK

Tcl_Obj* 
TclpObjLink(pathPtr, toPtr)
TclpObjLink(pathPtr, toPtr, linkAction)
    Tcl_Obj *pathPtr;
    Tcl_Obj *toPtr;
    int linkAction;
{
    if (toPtr != NULL) {
	CONST char *src = Tcl_FSGetNativePath(pathPtr);
	CONST char *target = Tcl_FSGetNativePath(toPtr);
    Tcl_Obj* linkPtr = NULL;

    if (toPtr != NULL) {
        return NULL;
    } else {
	
	if (src == NULL || target == NULL) {
	    return NULL;
	}
	if (access(src, F_OK) != -1) {
	    /* src exists */
	    errno = EEXIST;
	    return NULL;
	}
	if (access(target, F_OK) == -1) {
	    /* target doesn't exist */
	    errno = ENOENT;
	    return NULL;
	}
	/* 
	 * Check symbolic link flag first, since we prefer to
	 * create these.
	 */
	if (linkAction & TCL_CREATE_SYMBOLIC_LINK) {
	    if (symlink(target, src) != 0) return NULL;
	} else if (linkAction & TCL_CREATE_HARD_LINK) {
	    if (link(target, src) != 0) return NULL;
	} else {
	    errno = ENODEV;
	    return NULL;
	}
	return toPtr;
    } else {
	Tcl_Obj* linkPtr = NULL;

	char link[MAXPATHLEN];
	int length;
	char *native;
	Tcl_DString ds;

	
	if (Tcl_FSGetTranslatedPath(NULL, pathPtr) == NULL) {
	    return NULL;
	}
	length = readlink(Tcl_FSGetNativePath(pathPtr), link, sizeof(link));
	if (length < 0) {
	    return NULL;
	}
	
	/* 
	 * Allocate and copy the name, taking care since the
	 * name need not be null terminated. 
	 */
	native = (char*)ckalloc((unsigned)(1+length));
	strncpy(native, link, (unsigned)length);
	native[length] = '\0';
	
	Tcl_ExternalToUtfDString(NULL, native, length, &ds);
	linkPtr = Tcl_FSNewNativePath(pathPtr, native);
	Tcl_IncrRefCount(linkPtr);
    }
    return linkPtr;
	linkPtr = Tcl_NewStringObj(Tcl_DStringValue(&ds), 
				   Tcl_DStringLength(&ds));
	Tcl_DStringFree(&ds);
	if (linkPtr != NULL) {
	    Tcl_IncrRefCount(linkPtr);
	}
	return linkPtr;
    }
}

#endif


/*
 *---------------------------------------------------------------------------