Tcl Source Code

Check-in [90c31690eb]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:[Bug 3508771] Wrong Tcl_StatBuf used on MinGW [Bug 2015723] duplicate inodes from file stat on windows
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | core-8-4-branch
Files: files | file ages | folders
SHA1: 90c31690ebec1c960be755fef74ea53772dc8fd7
User & Date: jan.nijtmans 2012-03-27 11:20:55
Context
2012-03-29
20:48
[Bug 3511806] Compiler checks too early This change allows to build the cygwin and mingw32 ports of ... check-in: 8b0d9cc5fc user: jan.nijtmans tags: core-8-4-branch
12:13
better solution for bug-510001 it fills a correctly working stub entry for Win64 Closed-Leaf check-in: 02368db2ae user: jan.nijtmans tags: bug-510001
2012-03-27
15:08
bug-3511806 implementation check-in: 86da646fff user: jan.nijtmans tags: bug-3511806
11:39
[Bug 3508771] Wrong Tcl_StatBuf used on MinGW [Bug 2015723] duplicate inodes from file stat on windo... check-in: f9900bca57 user: jan.nijtmans tags: core-8-5-branch
11:20
[Bug 3508771] Wrong Tcl_StatBuf used on MinGW [Bug 2015723] duplicate inodes from file stat on windo... check-in: 90c31690eb user: jan.nijtmans tags: core-8-4-branch
2012-03-26
21:01
enable cygwin build in /win directory (using mingw-w64 compiler) check-in: b5a4dfa5f1 user: jan.nijtmans tags: core-8-4-branch
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to ChangeLog.






1
2
3
4
5
6
7





2012-03-24  Jan Nijtmans  <[email protected]>

	* generic/tclInt.decls:      [Bug 3508771] load tclreg.dll in cygwin tclsh
	* generic/tclIntPlatDecls.h: Implement TclWinConvertError, TclWinConvertWSAError,
	* generic/tclStubInit.c:     and various more win32-specific internal functions for 
	* unix/Makefile.in:          Cygwin, so win32 extensions using those can be
	* unix/tcl.m4:               loaded in the cygwin version of tclsh.
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
2012-03-27  Jan Nijtmans  <[email protected]>

	* generic/tcl.h:             [Bug 3508771] Wrong Tcl_StatBuf used on MinGW
	* generic/tclFCmd.c:         [Bug 2015723] duplicate inodes from file stat on windows

2012-03-24  Jan Nijtmans  <[email protected]>

	* generic/tclInt.decls:      [Bug 3508771] load tclreg.dll in cygwin tclsh
	* generic/tclIntPlatDecls.h: Implement TclWinConvertError, TclWinConvertWSAError,
	* generic/tclStubInit.c:     and various more win32-specific internal functions for 
	* unix/Makefile.in:          Cygwin, so win32 extensions using those can be
	* unix/tcl.m4:               loaded in the cygwin version of tclsh.

Changes to generic/tcl.h.

372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
 * complex formats sometimes needed (e.g. in the format(n) command.)
 */

#if !defined(TCL_WIDE_INT_TYPE)&&!defined(TCL_WIDE_INT_IS_LONG)
#   if defined(__WIN32__)
#      define TCL_WIDE_INT_TYPE __int64
#      ifdef __BORLANDC__
typedef struct stati64 Tcl_StatBuf;
#         define TCL_LL_MODIFIER	"L"
#         define TCL_LL_MODIFIER_SIZE	1
#      else /* __BORLANDC__ */
#         if defined(_WIN64)
typedef struct __stat64 Tcl_StatBuf;
#         elif (defined(_MSC_VER) && (_MSC_VER < 1400)) || defined(_USE_32BIT_TIME_T)
typedef struct _stati64	Tcl_StatBuf;
#         else
typedef struct _stat32i64 Tcl_StatBuf;
#         endif /* _MSC_VER < 1400 */
#         define TCL_LL_MODIFIER	"I64"
#         define TCL_LL_MODIFIER_SIZE	3
#      endif /* __BORLANDC__ */
#   elif defined(__GNUC__)
#      define TCL_WIDE_INT_TYPE long long
#      define TCL_LL_MODIFIER	"ll"
#      define TCL_LL_MODIFIER_SIZE	2
#      if defined(__WIN32__)
typedef struct _stat32i64 Tcl_StatBuf;
#      else
typedef struct stat	Tcl_StatBuf;
#      endif
#   else /* ! __WIN32__ && ! __GNUC__ */
/*
 * Don't know what platform it is and configure hasn't discovered what
 * is going on for us.  Try to guess...
 */
#      ifdef NO_LIMITS_H
#	  error please define either TCL_WIDE_INT_TYPE or TCL_WIDE_INT_IS_LONG







<



<
<
<
<
<
<
<







<
<
<
<
<







372
373
374
375
376
377
378

379
380
381







382
383
384
385
386
387
388





389
390
391
392
393
394
395
 * complex formats sometimes needed (e.g. in the format(n) command.)
 */

#if !defined(TCL_WIDE_INT_TYPE)&&!defined(TCL_WIDE_INT_IS_LONG)
#   if defined(__WIN32__)
#      define TCL_WIDE_INT_TYPE __int64
#      ifdef __BORLANDC__

#         define TCL_LL_MODIFIER	"L"
#         define TCL_LL_MODIFIER_SIZE	1
#      else /* __BORLANDC__ */







#         define TCL_LL_MODIFIER	"I64"
#         define TCL_LL_MODIFIER_SIZE	3
#      endif /* __BORLANDC__ */
#   elif defined(__GNUC__)
#      define TCL_WIDE_INT_TYPE long long
#      define TCL_LL_MODIFIER	"ll"
#      define TCL_LL_MODIFIER_SIZE	2





#   else /* ! __WIN32__ && ! __GNUC__ */
/*
 * Don't know what platform it is and configure hasn't discovered what
 * is going on for us.  Try to guess...
 */
#      ifdef NO_LIMITS_H
#	  error please define either TCL_WIDE_INT_TYPE or TCL_WIDE_INT_IS_LONG
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
462
463
464
465
466
467
468
469

































470
471
472
473
474
475
476
#   define TCL_WIDE_INT_TYPE	long
#endif /* TCL_WIDE_INT_IS_LONG */

typedef TCL_WIDE_INT_TYPE		Tcl_WideInt;
typedef unsigned TCL_WIDE_INT_TYPE	Tcl_WideUInt;

#ifdef TCL_WIDE_INT_IS_LONG
typedef struct stat	Tcl_StatBuf;
#   define Tcl_WideAsLong(val)		((long)(val))
#   define Tcl_LongAsWide(val)		((long)(val))
#   define Tcl_WideAsDouble(val)	((double)((long)(val)))
#   define Tcl_DoubleAsWide(val)	((long)((double)(val)))
#   ifndef TCL_LL_MODIFIER
#      define TCL_LL_MODIFIER		"l"
#      define TCL_LL_MODIFIER_SIZE	1
#   endif /* !TCL_LL_MODIFIER */
#else /* TCL_WIDE_INT_IS_LONG */
/*
 * The next short section of defines are only done when not running on
 * Windows or some other strange platform.
 */
#   ifndef TCL_LL_MODIFIER
#      ifdef __CYGWIN__
typedef struct _stat32i64 {
    dev_t st_dev;
    ino_t st_ino;
    unsigned short st_mode;
    short st_nlink;
    short st_uid;
    short st_gid;
    dev_t st_rdev;
    long long st_size;
    struct {long tv_sec;} st_atim;
    struct {long tv_sec;} st_mtim;
    struct {long tv_sec;} st_ctim;
} Tcl_StatBuf;
#      elif defined(HAVE_STRUCT_STAT64)
typedef struct stat64	Tcl_StatBuf;
#      else
typedef struct stat	Tcl_StatBuf;
#      endif /* HAVE_STRUCT_STAT64 */
#      define TCL_LL_MODIFIER		"ll"
#      define TCL_LL_MODIFIER_SIZE	2
#   endif /* !TCL_LL_MODIFIER */
#   define Tcl_WideAsLong(val)		((long)((Tcl_WideInt)(val)))
#   define Tcl_LongAsWide(val)		((Tcl_WideInt)((long)(val)))
#   define Tcl_WideAsDouble(val)	((double)((Tcl_WideInt)(val)))
#   define Tcl_DoubleAsWide(val)	((Tcl_WideInt)((double)(val)))
#endif /* TCL_WIDE_INT_IS_LONG */



































/*
 * This flag controls whether binary compatability is maintained with
 * extensions built against a previous version of Tcl. This is true
 * by default.
 */







<














<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







408
409
410
411
412
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
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
#   define TCL_WIDE_INT_TYPE	long
#endif /* TCL_WIDE_INT_IS_LONG */

typedef TCL_WIDE_INT_TYPE		Tcl_WideInt;
typedef unsigned TCL_WIDE_INT_TYPE	Tcl_WideUInt;

#ifdef TCL_WIDE_INT_IS_LONG

#   define Tcl_WideAsLong(val)		((long)(val))
#   define Tcl_LongAsWide(val)		((long)(val))
#   define Tcl_WideAsDouble(val)	((double)((long)(val)))
#   define Tcl_DoubleAsWide(val)	((long)((double)(val)))
#   ifndef TCL_LL_MODIFIER
#      define TCL_LL_MODIFIER		"l"
#      define TCL_LL_MODIFIER_SIZE	1
#   endif /* !TCL_LL_MODIFIER */
#else /* TCL_WIDE_INT_IS_LONG */
/*
 * The next short section of defines are only done when not running on
 * Windows or some other strange platform.
 */
#   ifndef TCL_LL_MODIFIER



















#      define TCL_LL_MODIFIER		"ll"
#      define TCL_LL_MODIFIER_SIZE	2
#   endif /* !TCL_LL_MODIFIER */
#   define Tcl_WideAsLong(val)		((long)((Tcl_WideInt)(val)))
#   define Tcl_LongAsWide(val)		((Tcl_WideInt)((long)(val)))
#   define Tcl_WideAsDouble(val)	((double)((Tcl_WideInt)(val)))
#   define Tcl_DoubleAsWide(val)	((Tcl_WideInt)((double)(val)))
#endif /* TCL_WIDE_INT_IS_LONG */

#if defined(__WIN32__)
#   ifdef __BORLANDC__
	typedef struct stati64 Tcl_StatBuf;
#   elif defined(_WIN64)
	typedef struct __stat64 Tcl_StatBuf;
#   elif (defined(_MSC_VER) && (_MSC_VER < 1400)) || defined(_USE_32BIT_TIME_T)
	typedef struct _stati64	Tcl_StatBuf;
#   else
	typedef struct _stat32i64 Tcl_StatBuf;
#   endif /* _MSC_VER < 1400 */
#elif defined(__CYGWIN__)
    typedef struct _stat32i64 {
	dev_t st_dev;
	unsigned short st_ino;
	unsigned short st_mode;
	short st_nlink;
	short st_uid;
	short st_gid;
	/* Here is a 2-byte gap */
	dev_t st_rdev;
	/* Here is a 4-byte gap */
	long long st_size;
	struct {long tv_sec;} st_atim;
	struct {long tv_sec;} st_mtim;
	struct {long tv_sec;} st_ctim;
	/* Here is a 4-byte gap */
    } Tcl_StatBuf;
#elif defined(HAVE_STRUCT_STAT64)
    typedef struct stat64 Tcl_StatBuf;
#else
    typedef struct stat Tcl_StatBuf;
#endif


/*
 * This flag controls whether binary compatability is maintained with
 * extensions built against a previous version of Tcl. This is true
 * by default.
 */

Changes to generic/tclFCmd.c.

512
513
514
515
516
517
518
519
520
521
522
523
524
525

526
527
528
529
530
531
532


533
534
535
536
537
538
539
    } else {
	if (force == 0) {
	    errno = EEXIST;
	    errfile = target;
	    goto done;
	}

        /* 
         * Prevent copying or renaming a file onto itself.  Under Windows, 
         * stat always returns 0 for st_ino.  However, the Windows-specific 
         * code knows how to deal with copying or renaming a file on top of
         * itself.  It might be a good idea to write a stat that worked.
         */
     

        if ((sourceStatBuf.st_ino != 0) && (targetStatBuf.st_ino != 0)) {
            if ((sourceStatBuf.st_ino == targetStatBuf.st_ino) &&
            	    (sourceStatBuf.st_dev == targetStatBuf.st_dev)) {
            	result = TCL_OK;
            	goto done;
            }
        }



	/*
	 * Prevent copying/renaming a file onto a directory and
	 * vice-versa.  This is a policy decision based on the fact that
	 * existing implementations of copy and rename on all platforms
	 * also prevent this.
	 */







|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
>
>







512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
    } else {
	if (force == 0) {
	    errno = EEXIST;
	    errfile = target;
	    goto done;
	}

	/*
	 * Prevent copying or renaming a file onto itself. On Windows since
	 * 8.5 we do get an inode number, however the unsigned short field is
	 * insufficient to accept the Win32 API file id so it is truncated to
	 * 16 bits and we get collisions. See bug #2015723.
	 */

#if !defined(WIN32) && !defined(__CYGWIN__)
	if ((sourceStatBuf.st_ino != 0) && (targetStatBuf.st_ino != 0)) {
	    if ((sourceStatBuf.st_ino == targetStatBuf.st_ino) &&
		    (sourceStatBuf.st_dev == targetStatBuf.st_dev)) {
		result = TCL_OK;
		goto done;
	    }
	}
#endif


	/*
	 * Prevent copying/renaming a file onto a directory and
	 * vice-versa.  This is a policy decision based on the fact that
	 * existing implementations of copy and rename on all platforms
	 * also prevent this.
	 */