From 7b4a3a11e94026797dfda140a1044ecf9d2871c5 Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 11 Jun 2012 22:25:57 +0000 Subject: First draft patch to fix Bug 3024359. No reliable test yet. --- generic/tclFileSystem.h | 1 + generic/tclIOUtil.c | 100 +++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 91 insertions(+), 10 deletions(-) diff --git a/generic/tclFileSystem.h b/generic/tclFileSystem.h index 2d6f046..97e73fe 100644 --- a/generic/tclFileSystem.h +++ b/generic/tclFileSystem.h @@ -52,6 +52,7 @@ typedef struct ThreadSpecificData { Tcl_Obj *cwdPathPtr; ClientData cwdClientData; FilesystemRecord *filesystemList; + int claims; } ThreadSpecificData; /* diff --git a/generic/tclIOUtil.c b/generic/tclIOUtil.c index 09877a3..d9cd66f 100644 --- a/generic/tclIOUtil.c +++ b/generic/tclIOUtil.c @@ -38,6 +38,8 @@ static void FsAddMountsToGlobResult(Tcl_Obj *resultPtr, Tcl_Obj *pathPtr, const char *pattern, Tcl_GlobTypeData *types); static void FsUpdateCwd(Tcl_Obj *cwdObj, ClientData clientData); +static void Claim(void); +static void Disclaim(void); #ifdef TCL_THREADS static void FsRecacheFilesystemList(void); @@ -594,15 +596,17 @@ FsRecacheFilesystemList(void) * Trash the current cache. */ - fsRecPtr = tsdPtr->filesystemList; - while (fsRecPtr != NULL) { + if (tsdPtr->claims <= 0) { + fsRecPtr = tsdPtr->filesystemList; + while (fsRecPtr != NULL) { tmpFsRecPtr = fsRecPtr->nextPtr; - if (--fsRecPtr->fileRefCount <= 0) { - ckfree((char *)fsRecPtr); + if (--fsRecPtr->fileRefCount <= 0) { + ckfree((char *)fsRecPtr); + } + fsRecPtr = tmpFsRecPtr; } - fsRecPtr = tmpFsRecPtr; + tsdPtr->filesystemList = NULL; } - tsdPtr->filesystemList = NULL; /* * Code below operates on shared data. We are already called under mutex @@ -627,9 +631,6 @@ FsRecacheFilesystemList(void) *tmpFsRecPtr = *fsRecPtr; tmpFsRecPtr->nextPtr = tsdPtr->filesystemList; tmpFsRecPtr->prevPtr = NULL; - if (tsdPtr->filesystemList) { - tsdPtr->filesystemList->prevPtr = tmpFsRecPtr; - } tsdPtr->filesystemList = tmpFsRecPtr; fsRecPtr = fsRecPtr->prevPtr; } @@ -679,6 +680,47 @@ TclFSEpochOk( (void) FsGetFirstFilesystem(); return (filesystemEpoch == tsdPtr->filesystemEpoch); } + +static void +Claim() +{ +#ifdef TCL_THREADS + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey); + + tsdPtr->claims++; +#endif +} + +static void +Disclaim() +{ +#ifdef TCL_THREADS + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey); + FilesystemRecord *toRelease, *fsRecPtr = tsdPtr->filesystemList; + + if (--tsdPtr->claims > 0) { + return; + } + /* + * No claims held, Release all out of date FilesystemRecords from the + * tsdPtr->filesystemList. First skip the current list. + */ + while (fsRecPtr->fsPtr != &tclNativeFilesystem) { + fsRecPtr = fsRecPtr->nextPtr; + } + + /* Then release everything that comes after. */ + toRelease = fsRecPtr->nextPtr; + while (toRelease != NULL) { + fsRecPtr = toRelease->nextPtr; + + if (--toRelease->fileRefCount <= 0) { + ckfree((char *)toRelease); + } + toRelease = fsRecPtr; + } +#endif +} /* * If non-NULL, clientData is owned by us and must be freed later. @@ -1369,6 +1411,9 @@ Tcl_FSData( if (fsRecPtr->fsPtr == fsPtr) { retVal = fsRecPtr->clientData; } + if (fsRecPtr->fsPtr == &tclNativeFilesystem) { + break; + } fsRecPtr = fsRecPtr->nextPtr; } @@ -1427,6 +1472,7 @@ TclFSNormalizeToUniquePath( firstFsRecPtr = FsGetFirstFilesystem(); + Claim(); fsRecPtr = firstFsRecPtr; while (fsRecPtr != NULL) { if (fsRecPtr->fsPtr == &tclNativeFilesystem) { @@ -1445,7 +1491,9 @@ TclFSNormalizeToUniquePath( * Skip the native system next time through. */ - if (fsRecPtr->fsPtr != &tclNativeFilesystem) { + if (fsRecPtr->fsPtr == &tclNativeFilesystem) { + break; + } else { Tcl_FSNormalizePathProc *proc = fsRecPtr->fsPtr->normalizePathProc; if (proc != NULL) { startAt = (*proc)(interp, pathPtr, startAt); @@ -1459,6 +1507,7 @@ TclFSNormalizeToUniquePath( } fsRecPtr = fsRecPtr->nextPtr; } + Disclaim(); return startAt; } @@ -2653,6 +2702,7 @@ Tcl_FSGetCwd( */ fsRecPtr = FsGetFirstFilesystem(); + Claim(); while ((retVal == NULL) && (fsRecPtr != NULL)) { Tcl_FSGetCwdProc *proc = fsRecPtr->fsPtr->getCwdProc; if (proc != NULL) { @@ -2700,8 +2750,12 @@ Tcl_FSGetCwd( retVal = (*proc)(interp); } } + if (fsRecPtr->fsPtr == &tclNativeFilesystem) { + break; + } fsRecPtr = fsRecPtr->nextPtr; } + Disclaim(); /* * Now the 'cwd' may NOT be normalized, at least on some platforms. @@ -3648,6 +3702,7 @@ Tcl_FSListVolumes(void) */ fsRecPtr = FsGetFirstFilesystem(); + Claim(); while (fsRecPtr != NULL) { Tcl_FSListVolumesProc *proc = fsRecPtr->fsPtr->listVolumesProc; if (proc != NULL) { @@ -3657,8 +3712,12 @@ Tcl_FSListVolumes(void) Tcl_DecrRefCount(thisFsVolumes); } } + if (fsRecPtr->fsPtr == &tclNativeFilesystem) { + break; + } fsRecPtr = fsRecPtr->nextPtr; } + Disclaim(); return resultPtr; } @@ -3698,6 +3757,7 @@ FsListMounts( */ fsRecPtr = FsGetFirstFilesystem(); + Claim(); while (fsRecPtr != NULL) { if (fsRecPtr->fsPtr != &tclNativeFilesystem) { Tcl_FSMatchInDirectoryProc *proc = @@ -3709,8 +3769,12 @@ FsListMounts( (*proc)(NULL, resultPtr, pathPtr, pattern, &mountsOnly); } } + if (fsRecPtr->fsPtr == &tclNativeFilesystem) { + break; + } fsRecPtr = fsRecPtr->nextPtr; } + Disclaim(); return resultPtr; } @@ -3829,13 +3893,19 @@ TclFSInternalToNormalized( { FilesystemRecord *fsRecPtr = FsGetFirstFilesystem(); + Claim(); while (fsRecPtr != NULL) { if (fsRecPtr->fsPtr == fromFilesystem) { *fsRecPtrPtr = fsRecPtr; break; } + if (fsRecPtr->fsPtr == &tclNativeFilesystem) { + fsRecPtr = NULL; + break; + } fsRecPtr = fsRecPtr->nextPtr; } + Disclaim(); if ((fsRecPtr != NULL) && (fromFilesystem->internalToNormalizedProc != NULL)) { @@ -3948,6 +4018,7 @@ TclFSNonnativePathType( */ fsRecPtr = FsGetFirstFilesystem(); + Claim(); while (fsRecPtr != NULL) { Tcl_FSListVolumesProc *proc = fsRecPtr->fsPtr->listVolumesProc; @@ -4024,8 +4095,12 @@ TclFSNonnativePathType( } } } + if (fsRecPtr->fsPtr == &tclNativeFilesystem) { + break; + } fsRecPtr = fsRecPtr->nextPtr; } + Disclaim(); return type; } @@ -4420,6 +4495,7 @@ Tcl_FSGetFileSystemForPath( */ fsRecPtr = FsGetFirstFilesystem(); + Claim(); if (TclFSEnsureEpochOk(pathPtr, &retVal) != TCL_OK) { return NULL; @@ -4446,8 +4522,12 @@ Tcl_FSGetFileSystemForPath( retVal = fsRecPtr->fsPtr; } } + if (fsRecPtr->fsPtr == &tclNativeFilesystem) { + break; + } fsRecPtr = fsRecPtr->nextPtr; } + Disclaim(); return retVal; } -- cgit v0.12 From 8469cbab159b4bfe007ee77f47b58cccc583561f Mon Sep 17 00:00:00 2001 From: dgp Date: Tue, 12 Jun 2012 13:44:14 +0000 Subject: Convert function calls to macros. --- generic/tclIOUtil.c | 52 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/generic/tclIOUtil.c b/generic/tclIOUtil.c index d9cd66f..f8141ee 100644 --- a/generic/tclIOUtil.c +++ b/generic/tclIOUtil.c @@ -38,11 +38,16 @@ static void FsAddMountsToGlobResult(Tcl_Obj *resultPtr, Tcl_Obj *pathPtr, const char *pattern, Tcl_GlobTypeData *types); static void FsUpdateCwd(Tcl_Obj *cwdObj, ClientData clientData); -static void Claim(void); -static void Disclaim(void); #ifdef TCL_THREADS static void FsRecacheFilesystemList(void); +static void Purge(FilesystemRecord *fsRecPtr); + +#define Claim() (tsdPtr->claims++) +#define Disclaim() if (--tsdPtr->claims <= 0) Purge(tsdPtr->filesystemList); +#else +#define Claim() +#define Disclaim() #endif /* @@ -681,29 +686,16 @@ TclFSEpochOk( return (filesystemEpoch == tsdPtr->filesystemEpoch); } -static void -Claim() -{ #ifdef TCL_THREADS - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey); - - tsdPtr->claims++; -#endif -} - static void -Disclaim() +Purge( + FilesystemRecord *fsRecPtr) { -#ifdef TCL_THREADS - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey); - FilesystemRecord *toRelease, *fsRecPtr = tsdPtr->filesystemList; + FilesystemRecord *toRelease; - if (--tsdPtr->claims > 0) { - return; - } /* - * No claims held, Release all out of date FilesystemRecords from the - * tsdPtr->filesystemList. First skip the current list. + * Release all out of date FilesystemRecords. + * First skip the current list. */ while (fsRecPtr->fsPtr != &tclNativeFilesystem) { fsRecPtr = fsRecPtr->nextPtr; @@ -719,8 +711,8 @@ Disclaim() } toRelease = fsRecPtr; } -#endif } +#endif /* * If non-NULL, clientData is owned by us and must be freed later. @@ -1459,6 +1451,9 @@ TclFSNormalizeToUniquePath( * for a given filesystem, we can optionally * return an fs-specific clientdata here. */ { +#ifdef TCL_THREADS + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey); +#endif FilesystemRecord *fsRecPtr, *firstFsRecPtr; /* Ignore this variable */ (void) clientDataPtr; @@ -3691,6 +3686,9 @@ Tcl_FSLink( Tcl_Obj* Tcl_FSListVolumes(void) { +#ifdef TCL_THREADS + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey); +#endif FilesystemRecord *fsRecPtr; Tcl_Obj *resultPtr = Tcl_NewObj(); @@ -3745,6 +3743,9 @@ FsListMounts( Tcl_Obj *pathPtr, /* Contains path to directory to search. */ const char *pattern) /* Pattern to match against. */ { +#ifdef TCL_THREADS + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey); +#endif FilesystemRecord *fsRecPtr; Tcl_GlobTypeData mountsOnly = { TCL_GLOB_TYPE_MOUNT, 0, NULL, NULL }; Tcl_Obj *resultPtr = NULL; @@ -3891,6 +3892,9 @@ TclFSInternalToNormalized( ClientData clientData, FilesystemRecord **fsRecPtrPtr) { +#ifdef TCL_THREADS + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey); +#endif FilesystemRecord *fsRecPtr = FsGetFirstFilesystem(); Claim(); @@ -4008,6 +4012,9 @@ TclFSNonnativePathType( * path, already with a refCount for the * caller. */ { +#ifdef TCL_THREADS + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey); +#endif FilesystemRecord *fsRecPtr; Tcl_PathType type = TCL_PATH_RELATIVE; @@ -4468,6 +4475,9 @@ Tcl_Filesystem * Tcl_FSGetFileSystemForPath( Tcl_Obj* pathPtr) { +#ifdef TCL_THREADS + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey); +#endif FilesystemRecord *fsRecPtr; Tcl_Filesystem* retVal = NULL; -- cgit v0.12 From 4731d0ccca76a01ad1401b71b70c9e6f1e372050 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 13 Jun 2012 14:48:27 +0000 Subject: first attempt at Cygwin notifier adaptation --- unix/tclUnixNotfy.c | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) diff --git a/unix/tclUnixNotfy.c b/unix/tclUnixNotfy.c index 0af7207..aff51b1 100644 --- a/unix/tclUnixNotfy.c +++ b/unix/tclUnixNotfy.c @@ -98,6 +98,12 @@ typedef struct ThreadSpecificData { * from these pointers. You must hold the * notifierMutex lock before accessing these * fields. */ +#ifdef __CYGWIN__ + void *event; /* Any other thread alerts a notifier + * that an event is ready to be processed + * by sending this event. */ + void *hwnd; /* Messaging window. */ +#endif /* __CYGWIN__ */ Tcl_Condition waitCV; /* Any other thread alerts a notifier * that an event is ready to be processed * by signaling this condition variable. */ @@ -205,6 +211,48 @@ static int FileHandlerEventProc _ANSI_ARGS_((Tcl_Event *evPtr, *---------------------------------------------------------------------- */ +#if defined(TCL_THREADS) && defined(__CYGWIN__) + +typedef struct { + void *hwnd; + unsigned int *message; + int wParam; + int lParam; + int time; + int x; + int y; +} MSG; + +typedef struct { + unsigned int style; + void *lpfnWndProc; + int cbClsExtra; + int cbWndExtra; + void *hInstance; + void *hIcon; + void *hCursor; + void *hbrBackground; + void *lpszMenuName; + void *lpszClassName; +} WNDCLASS; + +extern unsigned char __stdcall PeekMessageW(MSG *, void *, int, int, int); +extern unsigned char __stdcall GetMessageW(MSG *, void *, int, int); +extern unsigned char __stdcall TranslateMessage(const MSG *); +extern int __stdcall DispatchMessageW(const MSG *); +extern void __stdcall PostQuitMessage(int); +extern void * __stdcall CreateWindowExW(void *, void *, void *, DWORD, int, int, int, int, void *, void *, void *, void *); +extern unsigned char __stdcall DestroyWindow(void *); +extern unsigned char __stdcall PostMessageW(void *, unsigned int, void *, void *); +extern void *__stdcall RegisterClassW(const WNDCLASS *); +extern DWORD __stdcall DefWindowProcW(void *, int, void *, void *); +extern void *__stdcall CreateEventW(void *, unsigned char, unsigned char, void *); +extern void __stdcall CloseHandle(void *); +extern void __stdcall MsgWaitForMultipleObjects(DWORD, void *, unsigned char, DWORD, DWORD); +extern unsigned char __stdcall ResetEvent(void *); + +#endif + ClientData Tcl_InitNotifier() { @@ -304,6 +352,9 @@ Tcl_FinalizeNotifier(clientData) * Clean up any synchronization objects in the thread local storage. */ +#ifdef __CYGWIN__ + CloseHandle(tsdPtr->event); +#endif /* __CYGWIN__ */ Tcl_ConditionFinalize(&(tsdPtr->waitCV)); Tcl_MutexUnlock(¬ifierMutex); @@ -635,6 +686,31 @@ FileHandlerEventProc(evPtr, flags) return 1; } +#if defined(TCL_THREADS) && defined(__CYGWIN__) + +static DWORD __stdcall +NotifierProc( + void *hwnd, + unsigned int message, + void *wParam, + void *lParam) +{ + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); + + if (message != 1024) { + return DefWindowProcW(hwnd, message, wParam, lParam); + } + + /* + * Process all of the runnable events. + */ + + tsdPtr->eventReady = 1; + Tcl_ServiceAll(); + return 0; +} +#endif /* __CYGWIN__ */ + /* *---------------------------------------------------------------------- * @@ -663,6 +739,9 @@ Tcl_WaitForEvent(timePtr) int mask; #ifdef TCL_THREADS int waitForFiles; +# ifdef __CYGWIN__ + MSG msg; +# endif #else /* Impl. notes: timeout & timeoutPtr are used if, and only if * threads are not enabled. They are the arguments for the regular @@ -738,6 +817,31 @@ Tcl_WaitForEvent(timePtr) tsdPtr->pollState = 0; } +#ifdef __CYGWIN__ + if (!tsdPtr->hwnd) { + WNDCLASS class; + + class.style = 0; + class.cbClsExtra = 0; + class.cbWndExtra = 0; + class.hInstance = TclWinGetTclInstance(); + class.hbrBackground = NULL; + class.lpszMenuName = NULL; + class.lpszClassName = L"TclNotifier"; + class.lpfnWndProc = NotifierProc; + class.hIcon = NULL; + class.hCursor = NULL; + + if (!RegisterClassW(&class)) { + Tcl_Panic("Unable to register TclNotifier window class"); + } + tsdPtr->hwnd = CreateWindowExW(NULL, class.lpszClassName, class.lpszClassName, + 0, 0, 0, 0, 0, NULL, NULL, TclWinGetTclInstance(), NULL); + tsdPtr->event = CreateEventW(NULL, 1 /* manual */, + 0 /* !signaled */, NULL); + } + +#endif if (waitForFiles) { /* * Add the ThreadSpecificData structure of this thread to the list @@ -766,6 +870,21 @@ Tcl_WaitForEvent(timePtr) } tsdPtr->eventReady = 0; + while (PeekMessageW(&msg, NULL, 0, 0, 0)) { + /* + * Retrieve and dispatch the message. + */ + DWORD result = GetMessageW(&msg, NULL, 0, 0); + if (result == 0) { + PostQuitMessage(msg.wParam); + /* What to do here? */ + } else if (result != (DWORD)-1) { + TranslateMessage(&msg); + DispatchMessageW(&msg); + } + } + ResetEvent(tsdPtr->event); + if (waitForFiles && tsdPtr->onList) { /* * Remove the ThreadSpecificData structure of this thread from the -- cgit v0.12 From d175d3a8425c48ce4739f167b9a6eb80d3678685 Mon Sep 17 00:00:00 2001 From: dgp Date: Wed, 13 Jun 2012 17:26:41 +0000 Subject: More work in progress. The problem with release of the elements of a fileSystemList by one routine while some other (caller) routine is still traversing that list is not dependent on threaded operations. An unthreaded build can still encounter the problem. Revised so that threaded/unthreaded operations are much closer to the same (no direct TCL_THREADS dependency). Also simplified the epoch checking which reduces locking to when it's needed. Still have the problem of returning as valid FilesystemRecords that are pulled from an outdated epoch. --- generic/tclIOUtil.c | 45 +++++++-------------------------------------- 1 file changed, 7 insertions(+), 38 deletions(-) diff --git a/generic/tclIOUtil.c b/generic/tclIOUtil.c index f8141ee..d98e760 100644 --- a/generic/tclIOUtil.c +++ b/generic/tclIOUtil.c @@ -39,16 +39,11 @@ static void FsAddMountsToGlobResult(Tcl_Obj *resultPtr, Tcl_GlobTypeData *types); static void FsUpdateCwd(Tcl_Obj *cwdObj, ClientData clientData); -#ifdef TCL_THREADS static void FsRecacheFilesystemList(void); static void Purge(FilesystemRecord *fsRecPtr); #define Claim() (tsdPtr->claims++) #define Disclaim() if (--tsdPtr->claims <= 0) Purge(tsdPtr->filesystemList); -#else -#define Claim() -#define Disclaim() -#endif /* * These form part of the native filesystem support. They are needed here @@ -590,7 +585,6 @@ TclFSCwdPointerEquals( } } -#ifdef TCL_THREADS static void FsRecacheFilesystemList(void) { @@ -614,12 +608,10 @@ FsRecacheFilesystemList(void) } /* - * Code below operates on shared data. We are already called under mutex - * lock so we can safely proceed. - * * Locate tail of the global filesystem list. */ + Tcl_MutexLock(&filesystemMutex); fsRecPtr = filesystemList; while (fsRecPtr != NULL) { tmpFsRecPtr = fsRecPtr; @@ -639,6 +631,8 @@ FsRecacheFilesystemList(void) tsdPtr->filesystemList = tmpFsRecPtr; fsRecPtr = fsRecPtr->prevPtr; } + tsdPtr->filesystemEpoch = theFilesystemEpoch; + Tcl_MutexUnlock(&filesystemMutex); /* * Make sure the above gets released on thread exit. @@ -649,27 +643,16 @@ FsRecacheFilesystemList(void) tsdPtr->initialized = 1; } } -#endif /* TCL_THREADS */ static FilesystemRecord * FsGetFirstFilesystem(void) { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey); - FilesystemRecord *fsRecPtr; -#ifndef TCL_THREADS - tsdPtr->filesystemEpoch = theFilesystemEpoch; - fsRecPtr = filesystemList; -#else - Tcl_MutexLock(&filesystemMutex); if (tsdPtr->filesystemList == NULL || (tsdPtr->filesystemEpoch != theFilesystemEpoch)) { FsRecacheFilesystemList(); - tsdPtr->filesystemEpoch = theFilesystemEpoch; } - Tcl_MutexUnlock(&filesystemMutex); - fsRecPtr = tsdPtr->filesystemList; -#endif - return fsRecPtr; + return tsdPtr->filesystemList; } /* @@ -681,12 +664,9 @@ int TclFSEpochOk( int filesystemEpoch) { - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey); - (void) FsGetFirstFilesystem(); - return (filesystemEpoch == tsdPtr->filesystemEpoch); + return (filesystemEpoch == theFilesystemEpoch); } -#ifdef TCL_THREADS static void Purge( FilesystemRecord *fsRecPtr) @@ -712,7 +692,6 @@ Purge( toRelease = fsRecPtr; } } -#endif /* * If non-NULL, clientData is owned by us and must be freed later. @@ -832,6 +811,7 @@ TclFinalizeFilesystem(void) } fsRecPtr = tmpFsRecPtr; } + theFilesystemEpoch++; filesystemList = NULL; /* @@ -869,6 +849,7 @@ void TclResetFilesystem(void) { filesystemList = &nativeFilesystemRecord; + theFilesystemEpoch++; /* * Note, at this point, I believe nativeFilesystemRecord -> fileRefCount @@ -1451,9 +1432,7 @@ TclFSNormalizeToUniquePath( * for a given filesystem, we can optionally * return an fs-specific clientdata here. */ { -#ifdef TCL_THREADS ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey); -#endif FilesystemRecord *fsRecPtr, *firstFsRecPtr; /* Ignore this variable */ (void) clientDataPtr; @@ -3686,9 +3665,7 @@ Tcl_FSLink( Tcl_Obj* Tcl_FSListVolumes(void) { -#ifdef TCL_THREADS ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey); -#endif FilesystemRecord *fsRecPtr; Tcl_Obj *resultPtr = Tcl_NewObj(); @@ -3743,9 +3720,7 @@ FsListMounts( Tcl_Obj *pathPtr, /* Contains path to directory to search. */ const char *pattern) /* Pattern to match against. */ { -#ifdef TCL_THREADS ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey); -#endif FilesystemRecord *fsRecPtr; Tcl_GlobTypeData mountsOnly = { TCL_GLOB_TYPE_MOUNT, 0, NULL, NULL }; Tcl_Obj *resultPtr = NULL; @@ -3892,9 +3867,7 @@ TclFSInternalToNormalized( ClientData clientData, FilesystemRecord **fsRecPtrPtr) { -#ifdef TCL_THREADS ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey); -#endif FilesystemRecord *fsRecPtr = FsGetFirstFilesystem(); Claim(); @@ -4012,9 +3985,7 @@ TclFSNonnativePathType( * path, already with a refCount for the * caller. */ { -#ifdef TCL_THREADS ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey); -#endif FilesystemRecord *fsRecPtr; Tcl_PathType type = TCL_PATH_RELATIVE; @@ -4475,9 +4446,7 @@ Tcl_Filesystem * Tcl_FSGetFileSystemForPath( Tcl_Obj* pathPtr) { -#ifdef TCL_THREADS ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey); -#endif FilesystemRecord *fsRecPtr; Tcl_Filesystem* retVal = NULL; -- cgit v0.12 From 5f8dff42ac6dc46d1aca06a1e94c41ac27c41cf2 Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 18 Jun 2012 20:36:22 +0000 Subject: Next draft fix. This one appears to solve the problem, at least as demo'd by the test attached to Tcl Bug 3024359. --- generic/tclIOUtil.c | 86 +++++++++++++++++++++++++---------------------------- 1 file changed, 40 insertions(+), 46 deletions(-) diff --git a/generic/tclIOUtil.c b/generic/tclIOUtil.c index d98e760..80eccbf 100644 --- a/generic/tclIOUtil.c +++ b/generic/tclIOUtil.c @@ -40,10 +40,9 @@ static void FsAddMountsToGlobResult(Tcl_Obj *resultPtr, static void FsUpdateCwd(Tcl_Obj *cwdObj, ClientData clientData); static void FsRecacheFilesystemList(void); -static void Purge(FilesystemRecord *fsRecPtr); +static void Claim(void); +static void Disclaim(void); -#define Claim() (tsdPtr->claims++) -#define Disclaim() if (--tsdPtr->claims <= 0) Purge(tsdPtr->filesystemList); /* * These form part of the native filesystem support. They are needed here @@ -589,23 +588,31 @@ static void FsRecacheFilesystemList(void) { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey); - FilesystemRecord *fsRecPtr, *tmpFsRecPtr = NULL; + FilesystemRecord *fsRecPtr, *tmpFsRecPtr = NULL, *chain = NULL; /* * Trash the current cache. */ + fsRecPtr = tsdPtr->filesystemList; if (tsdPtr->claims <= 0) { - fsRecPtr = tsdPtr->filesystemList; while (fsRecPtr != NULL) { - tmpFsRecPtr = fsRecPtr->nextPtr; + tmpFsRecPtr = fsRecPtr->nextPtr; if (--fsRecPtr->fileRefCount <= 0) { ckfree((char *)fsRecPtr); } fsRecPtr = tmpFsRecPtr; } - tsdPtr->filesystemList = NULL; + } else { + chain = fsRecPtr; + while (fsRecPtr->nextPtr != NULL) { + fsRecPtr->prevPtr = fsRecPtr->nextPtr; + fsRecPtr->nextPtr = NULL; + fsRecPtr = fsRecPtr->prevPtr; + } + fsRecPtr->prevPtr = fsRecPtr; } + tsdPtr->filesystemList = NULL; /* * Locate tail of the global filesystem list. @@ -627,7 +634,8 @@ FsRecacheFilesystemList(void) tmpFsRecPtr = (FilesystemRecord *) ckalloc(sizeof(FilesystemRecord)); *tmpFsRecPtr = *fsRecPtr; tmpFsRecPtr->nextPtr = tsdPtr->filesystemList; - tmpFsRecPtr->prevPtr = NULL; + tmpFsRecPtr->prevPtr = chain; + chain = NULL; tsdPtr->filesystemList = tmpFsRecPtr; fsRecPtr = fsRecPtr->prevPtr; } @@ -668,24 +676,39 @@ TclFSEpochOk( } static void -Purge( - FilesystemRecord *fsRecPtr) +Claim() +{ + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey); + + tsdPtr->claims++; +} + +static void +Disclaim() { - FilesystemRecord *toRelease; + ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey); + FilesystemRecord *fsRecPtr, *toRelease, *lastCurrent; + + if (--tsdPtr->claims > 0) { + return; + } + fsRecPtr = tsdPtr->filesystemList; /* * Release all out of date FilesystemRecords. * First skip the current list. */ - while (fsRecPtr->fsPtr != &tclNativeFilesystem) { + while (fsRecPtr->nextPtr != NULL) { fsRecPtr = fsRecPtr->nextPtr; } /* Then release everything that comes after. */ - toRelease = fsRecPtr->nextPtr; + lastCurrent = fsRecPtr; + toRelease = lastCurrent->prevPtr; + lastCurrent->prevPtr = NULL; while (toRelease != NULL) { - fsRecPtr = toRelease->nextPtr; - + fsRecPtr = (toRelease == toRelease->prevPtr) ? NULL + : toRelease->prevPtr; if (--toRelease->fileRefCount <= 0) { ckfree((char *)toRelease); } @@ -1384,9 +1407,6 @@ Tcl_FSData( if (fsRecPtr->fsPtr == fsPtr) { retVal = fsRecPtr->clientData; } - if (fsRecPtr->fsPtr == &tclNativeFilesystem) { - break; - } fsRecPtr = fsRecPtr->nextPtr; } @@ -1432,7 +1452,6 @@ TclFSNormalizeToUniquePath( * for a given filesystem, we can optionally * return an fs-specific clientdata here. */ { - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey); FilesystemRecord *fsRecPtr, *firstFsRecPtr; /* Ignore this variable */ (void) clientDataPtr; @@ -1465,9 +1484,7 @@ TclFSNormalizeToUniquePath( * Skip the native system next time through. */ - if (fsRecPtr->fsPtr == &tclNativeFilesystem) { - break; - } else { + if (fsRecPtr->fsPtr != &tclNativeFilesystem) { Tcl_FSNormalizePathProc *proc = fsRecPtr->fsPtr->normalizePathProc; if (proc != NULL) { startAt = (*proc)(interp, pathPtr, startAt); @@ -2714,6 +2731,7 @@ Tcl_FSGetCwd( } Tcl_DecrRefCount(retVal); retVal = NULL; + Disclaim(); goto cdDidNotChange; } else if (interp != NULL) { Tcl_AppendResult(interp, @@ -2724,9 +2742,6 @@ Tcl_FSGetCwd( retVal = (*proc)(interp); } } - if (fsRecPtr->fsPtr == &tclNativeFilesystem) { - break; - } fsRecPtr = fsRecPtr->nextPtr; } Disclaim(); @@ -3665,7 +3680,6 @@ Tcl_FSLink( Tcl_Obj* Tcl_FSListVolumes(void) { - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey); FilesystemRecord *fsRecPtr; Tcl_Obj *resultPtr = Tcl_NewObj(); @@ -3687,9 +3701,6 @@ Tcl_FSListVolumes(void) Tcl_DecrRefCount(thisFsVolumes); } } - if (fsRecPtr->fsPtr == &tclNativeFilesystem) { - break; - } fsRecPtr = fsRecPtr->nextPtr; } Disclaim(); @@ -3720,7 +3731,6 @@ FsListMounts( Tcl_Obj *pathPtr, /* Contains path to directory to search. */ const char *pattern) /* Pattern to match against. */ { - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey); FilesystemRecord *fsRecPtr; Tcl_GlobTypeData mountsOnly = { TCL_GLOB_TYPE_MOUNT, 0, NULL, NULL }; Tcl_Obj *resultPtr = NULL; @@ -3745,9 +3755,6 @@ FsListMounts( (*proc)(NULL, resultPtr, pathPtr, pattern, &mountsOnly); } } - if (fsRecPtr->fsPtr == &tclNativeFilesystem) { - break; - } fsRecPtr = fsRecPtr->nextPtr; } Disclaim(); @@ -3867,7 +3874,6 @@ TclFSInternalToNormalized( ClientData clientData, FilesystemRecord **fsRecPtrPtr) { - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey); FilesystemRecord *fsRecPtr = FsGetFirstFilesystem(); Claim(); @@ -3876,10 +3882,6 @@ TclFSInternalToNormalized( *fsRecPtrPtr = fsRecPtr; break; } - if (fsRecPtr->fsPtr == &tclNativeFilesystem) { - fsRecPtr = NULL; - break; - } fsRecPtr = fsRecPtr->nextPtr; } Disclaim(); @@ -3985,7 +3987,6 @@ TclFSNonnativePathType( * path, already with a refCount for the * caller. */ { - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey); FilesystemRecord *fsRecPtr; Tcl_PathType type = TCL_PATH_RELATIVE; @@ -4073,9 +4074,6 @@ TclFSNonnativePathType( } } } - if (fsRecPtr->fsPtr == &tclNativeFilesystem) { - break; - } fsRecPtr = fsRecPtr->nextPtr; } Disclaim(); @@ -4446,7 +4444,6 @@ Tcl_Filesystem * Tcl_FSGetFileSystemForPath( Tcl_Obj* pathPtr) { - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey); FilesystemRecord *fsRecPtr; Tcl_Filesystem* retVal = NULL; @@ -4501,9 +4498,6 @@ Tcl_FSGetFileSystemForPath( retVal = fsRecPtr->fsPtr; } } - if (fsRecPtr->fsPtr == &tclNativeFilesystem) { - break; - } fsRecPtr = fsRecPtr->nextPtr; } Disclaim(); -- cgit v0.12 From 3c7c7211e92d675398a7bbda6dcc19d9edc3fc0d Mon Sep 17 00:00:00 2001 From: dgp Date: Thu, 21 Jun 2012 15:44:01 +0000 Subject: Only record the filesystemEpoch when it actually marks the validity of something we are caching. --- generic/tclIOUtil.c | 4 ++-- generic/tclPathObj.c | 21 +++++++++++++++------ 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/generic/tclIOUtil.c b/generic/tclIOUtil.c index 0600a6c..96f1b30 100644 --- a/generic/tclIOUtil.c +++ b/generic/tclIOUtil.c @@ -411,7 +411,7 @@ static FilesystemRecord nativeFilesystemRecord = { * trigger cache cleanup in all threads. */ -static int theFilesystemEpoch = 0; +static int theFilesystemEpoch = 1; /* * Stores the linked list of filesystems. A 1:1 copy of this list is also @@ -672,7 +672,7 @@ int TclFSEpochOk( int filesystemEpoch) { - return (filesystemEpoch == theFilesystemEpoch); + return (filesystemEpoch == 0 || filesystemEpoch == theFilesystemEpoch); } static void diff --git a/generic/tclPathObj.c b/generic/tclPathObj.c index 147c619..e76f450 100644 --- a/generic/tclPathObj.c +++ b/generic/tclPathObj.c @@ -565,8 +565,8 @@ TclPathPart( if (pathPtr->typePtr == &tclFsPathType) { FsPath *fsPathPtr = PATHOBJ(pathPtr); - if (TclFSEpochOk(fsPathPtr->filesystemEpoch) - && (PATHFLAGS(pathPtr) != 0)) { + if (/*TclFSEpochOk(fsPathPtr->filesystemEpoch) + && */(PATHFLAGS(pathPtr) != 0)) { switch (portion) { case TCL_PATH_DIRNAME: { /* @@ -1313,7 +1313,7 @@ TclNewFSPathObj( Tcl_IncrRefCount(dirPtr); fsPathPtr->nativePathPtr = NULL; fsPathPtr->fsRecPtr = NULL; - fsPathPtr->filesystemEpoch = tsdPtr->filesystemEpoch; + fsPathPtr->filesystemEpoch = 0; SETPATHOBJ(pathPtr, fsPathPtr); PATHFLAGS(pathPtr) = TCLPATH_APPENDED; @@ -1419,7 +1419,6 @@ TclFSMakePathRelative( { int cwdLen, len; const char *tempStr; - ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey); if (pathPtr->typePtr == &tclFsPathType) { FsPath *fsPathPtr = PATHOBJ(pathPtr); @@ -1483,7 +1482,7 @@ TclFSMakePathRelative( Tcl_IncrRefCount(cwdPtr); fsPathPtr->nativePathPtr = NULL; fsPathPtr->fsRecPtr = NULL; - fsPathPtr->filesystemEpoch = tsdPtr->filesystemEpoch; + fsPathPtr->filesystemEpoch = 0; SETPATHOBJ(pathPtr, fsPathPtr); PATHFLAGS(pathPtr) = 0; @@ -1593,6 +1592,7 @@ TclFSMakePathFromNormalized( fsPathPtr->cwdPtr = NULL; fsPathPtr->nativePathPtr = NULL; fsPathPtr->fsRecPtr = NULL; + /* Remember the epoch under which we decided pathPtr was normalized */ fsPathPtr->filesystemEpoch = tsdPtr->filesystemEpoch; SETPATHOBJ(pathPtr, fsPathPtr); @@ -1730,6 +1730,12 @@ Tcl_FSGetTranslatedPath( retObj = Tcl_FSJoinToPath(translatedCwdPtr, 1, &(srcFsPathPtr->normPathPtr)); srcFsPathPtr->translatedPathPtr = retObj; + if (translatedCwdPtr->typePtr == &tclFsPathType) { + srcFsPathPtr->filesystemEpoch + = PATHOBJ(translatedCwdPtr)->filesystemEpoch; + } else { + srcFsPathPtr->filesystemEpoch = 0; + } Tcl_IncrRefCount(retObj); Tcl_DecrRefCount(translatedCwdPtr); } else { @@ -2531,12 +2537,15 @@ SetFsPathFromAny( fsPathPtr->translatedPathPtr = transPtr; if (transPtr != pathPtr) { Tcl_IncrRefCount(fsPathPtr->translatedPathPtr); + /* Redo translation when $env(HOME) changes */ + fsPathPtr->filesystemEpoch = tsdPtr->filesystemEpoch; + } else { + fsPathPtr->filesystemEpoch = 0; } fsPathPtr->normPathPtr = NULL; fsPathPtr->cwdPtr = NULL; fsPathPtr->nativePathPtr = NULL; fsPathPtr->fsRecPtr = NULL; - fsPathPtr->filesystemEpoch = tsdPtr->filesystemEpoch; /* * Free old representation before installing our new one. -- cgit v0.12 From 39b1bc8eefca71fda1f8bebf08eee86cff6f5aec Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Fri, 22 Jun 2012 12:07:28 +0000 Subject: Cygwin network pathname support --- generic/tclFileName.c | 34 ++++++++++++++++++++++++++++------ tests/fileName.test | 6 +++--- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/generic/tclFileName.c b/generic/tclFileName.c index 4c57256..de91d81 100644 --- a/generic/tclFileName.c +++ b/generic/tclFileName.c @@ -414,9 +414,17 @@ TclpGetNativePathType( } #endif if (path[0] == '/') { +#ifdef __CYGWIN__ + /* + * Check for Cygwin // network path prefix + */ + if (path[1] == '/') { + path++; + } +#endif if (driveNameLengthPtr != NULL) { /* - * We need this addition in case the QNX code was used. + * We need this addition in case the QNX or Cygwin code was used. */ *driveNameLengthPtr = (1 + path - origPath); @@ -643,11 +651,20 @@ SplitUnixPath( } #endif - if (path[0] == '/') { - Tcl_ListObjAppendElement(NULL, result, Tcl_NewStringObj("/",1)); - p = path+1; - } else { - p = path; + p = path; + if (*p == '/') { + Tcl_Obj *rootElt = Tcl_NewStringObj("/", 1); + p++; +#ifdef __CYGWIN__ + /* + * Check for Cygwin // network path prefix + */ + if (*p == '/') { + Tcl_AppendToObj(rootElt, "/", 1); + p++; + } +#endif + Tcl_ListObjAppendElement(NULL, result, rootElt); } /* @@ -2196,6 +2213,11 @@ DoGlob( && (strchr(separators, lastChar) == NULL)) || ((length == 0) && (count > 0)))) { Tcl_DStringAppend(&append, "/", 1); +#ifdef __CYGWIN__ + if ((length == 0) && (count > 1)) { + Tcl_DStringAppend(&append, "/", 1); + } +#endif } break; } diff --git a/tests/fileName.test b/tests/fileName.test index c613068..a91f4b3 100644 --- a/tests/fileName.test +++ b/tests/fileName.test @@ -189,7 +189,7 @@ test filename-4.12 {Tcl_SplitPath: unix} {testsetplatform} { test filename-4.13 {Tcl_SplitPath: unix} {testsetplatform} { testsetplatform unix file split //foo -} {/ foo} +} "[file split //] foo" test filename-4.14 {Tcl_SplitPath: unix} {testsetplatform} { testsetplatform unix file split foo//bar @@ -429,11 +429,11 @@ test filename-7.16 {Tcl_JoinPath: unix} {testsetplatform} { test filename-7.17 {Tcl_JoinPath: unix} {testsetplatform} { testsetplatform unix file join //a b -} {/a/b} +} "[file split //]a/b" test filename-7.18 {Tcl_JoinPath: unix} {testsetplatform} { testsetplatform unix file join /// a b -} {/a/b} +} "[file split //]a/b" test filename-9.1 {Tcl_JoinPath: win} {testsetplatform} { -- cgit v0.12 From fc25ed040a2abd529c7aa70e95e5a2981a13c92a Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 22 Jun 2012 16:43:26 +0000 Subject: Revise the order of memory free, so that bugs that attempt to access freed memory are more likely to segfault and not remain hidden. --- generic/tclIOUtil.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/generic/tclIOUtil.c b/generic/tclIOUtil.c index 3bdcca3..9a4af9a 100644 --- a/generic/tclIOUtil.c +++ b/generic/tclIOUtil.c @@ -480,6 +480,7 @@ FsThrExitProc( while (fsRecPtr != NULL) { tmpFsRecPtr = fsRecPtr->nextPtr; if (--fsRecPtr->fileRefCount <= 0) { + fsRecPtr->fsPtr = NULL; ckfree((char *)fsRecPtr); } fsRecPtr = tmpFsRecPtr; @@ -588,7 +589,7 @@ static void FsRecacheFilesystemList(void) { ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tclFsDataKey); - FilesystemRecord *fsRecPtr, *tmpFsRecPtr = NULL; + FilesystemRecord *fsRecPtr, *tmpFsRecPtr = NULL, *toFree = NULL; /* * Trash the current cache. @@ -598,7 +599,9 @@ FsRecacheFilesystemList(void) while (fsRecPtr != NULL) { tmpFsRecPtr = fsRecPtr->nextPtr; if (--fsRecPtr->fileRefCount <= 0) { - ckfree((char *)fsRecPtr); + fsRecPtr->fsPtr = NULL; + fsRecPtr->nextPtr = toFree; + toFree = fsRecPtr; } fsRecPtr = tmpFsRecPtr; } @@ -634,6 +637,12 @@ FsRecacheFilesystemList(void) fsRecPtr = fsRecPtr->prevPtr; } + while (toFree) { + FilesystemRecord *next = toFree->nextPtr; + ckfree((char *)toFree); + toFree = next; + } + /* * Make sure the above gets released on thread exit. */ -- cgit v0.12 From e87f03c29d1158714d9319724311d1091997611d Mon Sep 17 00:00:00 2001 From: dgp Date: Fri, 22 Jun 2012 18:38:31 +0000 Subject: FilesystemRecord structs no longer need refcounting. --- generic/tclFileSystem.h | 1 - generic/tclIOUtil.c | 45 +++++++++++---------------------------------- 2 files changed, 11 insertions(+), 35 deletions(-) diff --git a/generic/tclFileSystem.h b/generic/tclFileSystem.h index 3dfc1de..c50c751 100644 --- a/generic/tclFileSystem.h +++ b/generic/tclFileSystem.h @@ -28,7 +28,6 @@ typedef struct FilesystemRecord { ClientData clientData; /* Client specific data for the new filesystem * (can be NULL) */ Tcl_Filesystem *fsPtr; /* Pointer to filesystem dispatch table. */ - int fileRefCount; /* How many Tcl_Obj's use this filesystem. */ struct FilesystemRecord *nextPtr; /* The next filesystem registered to Tcl, or * NULL if no more. */ diff --git a/generic/tclIOUtil.c b/generic/tclIOUtil.c index 9a4af9a..9e36d64 100644 --- a/generic/tclIOUtil.c +++ b/generic/tclIOUtil.c @@ -398,7 +398,6 @@ Tcl_Filesystem tclNativeFilesystem = { static FilesystemRecord nativeFilesystemRecord = { NULL, &tclNativeFilesystem, - 1, NULL, NULL }; @@ -479,10 +478,8 @@ FsThrExitProc( fsRecPtr = tsdPtr->filesystemList; while (fsRecPtr != NULL) { tmpFsRecPtr = fsRecPtr->nextPtr; - if (--fsRecPtr->fileRefCount <= 0) { - fsRecPtr->fsPtr = NULL; - ckfree((char *)fsRecPtr); - } + fsRecPtr->fsPtr = NULL; + ckfree((char *)fsRecPtr); fsRecPtr = tmpFsRecPtr; } tsdPtr->initialized = 0; @@ -598,11 +595,9 @@ FsRecacheFilesystemList(void) fsRecPtr = tsdPtr->filesystemList; while (fsRecPtr != NULL) { tmpFsRecPtr = fsRecPtr->nextPtr; - if (--fsRecPtr->fileRefCount <= 0) { - fsRecPtr->fsPtr = NULL; - fsRecPtr->nextPtr = toFree; - toFree = fsRecPtr; - } + fsRecPtr->fsPtr = NULL; + fsRecPtr->nextPtr = toFree; + toFree = fsRecPtr; fsRecPtr = tmpFsRecPtr; } tsdPtr->filesystemList = NULL; @@ -796,14 +791,11 @@ TclFinalizeFilesystem(void) fsRecPtr = filesystemList; while (fsRecPtr != NULL) { FilesystemRecord *tmpFsRecPtr = fsRecPtr->nextPtr; - if (fsRecPtr->fileRefCount <= 0) { - /* - * The native filesystem is static, so we don't free it. - */ - if (fsRecPtr->fsPtr != &tclNativeFilesystem) { - ckfree((char *)fsRecPtr); - } + /* The native filesystem is static, so we don't free it. */ + + if (fsRecPtr != &nativeFilesystemRecord) { + ckfree((char *)fsRecPtr); } fsRecPtr = tmpFsRecPtr; } @@ -845,11 +837,6 @@ TclResetFilesystem(void) { filesystemList = &nativeFilesystemRecord; - /* - * Note, at this point, I believe nativeFilesystemRecord -> fileRefCount - * should equal 1 and if not, we should try to track down the cause. - */ - #ifdef __WIN32__ /* * Cleans up the win32 API filesystem proc lookup table. This must happen @@ -907,13 +894,6 @@ Tcl_FSRegister( newFilesystemPtr->fsPtr = fsPtr; /* - * We start with a refCount of 1. If this drops to zero, then anyone is - * welcome to ckfree us. - */ - - newFilesystemPtr->fileRefCount = 1; - - /* * Is this lock and wait strictly speaking necessary? Since any iterators * out there will have grabbed a copy of the head of the list and be * iterating away from that, if we add a new element to the head of the @@ -986,7 +966,7 @@ Tcl_FSUnregister( */ fsRecPtr = filesystemList; - while ((retVal == TCL_ERROR) && (fsRecPtr->fsPtr != &tclNativeFilesystem)) { + while ((retVal == TCL_ERROR) && (fsRecPtr != &nativeFilesystemRecord)) { if (fsRecPtr->fsPtr == fsPtr) { if (fsRecPtr->prevPtr) { fsRecPtr->prevPtr->nextPtr = fsRecPtr->nextPtr; @@ -1007,10 +987,7 @@ Tcl_FSUnregister( theFilesystemEpoch++; - fsRecPtr->fileRefCount--; - if (fsRecPtr->fileRefCount <= 0) { - ckfree((char *)fsRecPtr); - } + ckfree((char *)fsRecPtr); retVal = TCL_OK; } else { -- cgit v0.12 From c6060d6e629b818850b39214f796339032378217 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Sun, 24 Jun 2012 06:00:34 +0000 Subject: some wrong versions --- tests/msgcat.test | 4 ++-- unix/configure | 2 +- unix/tcl.m4 | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/msgcat.test b/tests/msgcat.test index 0669810..6fe4b31 100644 --- a/tests/msgcat.test +++ b/tests/msgcat.test @@ -17,8 +17,8 @@ if {[catch {package require tcltest 2}]} { puts stderr "Skipping tests in [info script]. tcltest 2 required." return } -if {[catch {package require msgcat 1.4.2}]} { - puts stderr "Skipping tests in [info script]. No msgcat 1.4.2 found to test." +if {[catch {package require msgcat 1.4.4}]} { + puts stderr "Skipping tests in [info script]. No msgcat 1.4.4 found to test." return } diff --git a/unix/configure b/unix/configure index 36ddde6..27a7f50 100755 --- a/unix/configure +++ b/unix/configure @@ -7006,7 +7006,7 @@ echo "$as_me: error: ${CC} is not a cygwin compiler." >&2;} echo "$as_me: error: CYGWIN compile is only supported with --enable-threads" >&2;} { (exit 1); exit 1; }; } fi - if test ! -f "../win/tcldde12.dll" -a ! -f "../win/tk84.dll"; then + if test ! -f "../win/tcldde13.dll" -a ! -f "../win/tk85.dll"; then { { echo "$as_me:$LINENO: error: Please configure and make the ../win directory first." >&5 echo "$as_me: error: Please configure and make the ../win directory first." >&2;} { (exit 1); exit 1; }; } diff --git a/unix/tcl.m4 b/unix/tcl.m4 index 744d6ed..390f4ec 100644 --- a/unix/tcl.m4 +++ b/unix/tcl.m4 @@ -1263,7 +1263,7 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [ if test "x${TCL_THREADS}" = "x0"; then AC_MSG_ERROR([CYGWIN compile is only supported with --enable-threads]) fi - if test ! -f "../win/tcldde12.dll" -a ! -f "../win/tk84.dll"; then + if test ! -f "../win/tcldde13.dll" -a ! -f "../win/tk85.dll"; then AC_MSG_ERROR([Please configure and make the ../win directory first.]) fi ;; -- cgit v0.12 From 527a4f67fa396747502ba37514a882725f401110 Mon Sep 17 00:00:00 2001 From: dkf Date: Mon, 25 Jun 2012 12:54:29 +0000 Subject: [Bug 3537605]: Make [encoding dirs ? ?] report the right error message. --- ChangeLog | 5 +++++ generic/tclCmdAH.c | 18 +++++++++++------- tests/encoding.test | 8 ++++++++ 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index c8ecc4f..e2ca3f2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2012-06-25 Donal K. Fellows + + * generic/tclCmdAH.c (EncodingDirsObjCmd): [Bug 3537605]: Do the right + thing when reporting errors with the number of arguments. + 2012-06-25 Jan Nijtmans * generic/tclfileName.c: [Patch #1536227]: Cygwin network pathname diff --git a/generic/tclCmdAH.c b/generic/tclCmdAH.c index e1ec927..8e32389 100644 --- a/generic/tclCmdAH.c +++ b/generic/tclCmdAH.c @@ -505,7 +505,7 @@ Tcl_EncodingObjCmd( break; } case ENC_DIRS: - return EncodingDirsObjCmd(dummy, interp, objc-1, objv+1); + return EncodingDirsObjCmd(dummy, interp, objc, objv); case ENC_NAMES: if (objc > 2) { Tcl_WrongNumArgs(interp, 2, objv, NULL); @@ -552,20 +552,24 @@ EncodingDirsObjCmd( int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { - if (objc > 2) { - Tcl_WrongNumArgs(interp, 1, objv, "?dirList?"); + Tcl_Obj *dirListObj; + + if (objc > 3) { + Tcl_WrongNumArgs(interp, 2, objv, "?dirList?"); return TCL_ERROR; } - if (objc == 1) { + if (objc == 2) { Tcl_SetObjResult(interp, Tcl_GetEncodingSearchPath()); return TCL_OK; } - if (Tcl_SetEncodingSearchPath(objv[1]) == TCL_ERROR) { + + dirListObj = objv[2]; + if (Tcl_SetEncodingSearchPath(dirListObj) == TCL_ERROR) { Tcl_AppendResult(interp, "expected directory list but got \"", - TclGetString(objv[1]), "\"", NULL); + TclGetString(dirListObj), "\"", NULL); return TCL_ERROR; } - Tcl_SetObjResult(interp, objv[1]); + Tcl_SetObjResult(interp, dirListObj); return TCL_OK; } diff --git a/tests/encoding.test b/tests/encoding.test index 836f277..aa50360 100644 --- a/tests/encoding.test +++ b/tests/encoding.test @@ -586,6 +586,14 @@ file delete {*}[glob -directory [temporaryDirectory] *.chars *.tcltestout] # EscapeFreeProc, GetTableEncoding, unilen # are fully tested by the rest of this file + +test encoding-27.1 {encoding dirs basic behavior} -returnCodes error -body { + encoding dirs ? ? +} -result {wrong # args: should be "encoding dirs ?dirList?"} +test encoding-27.2 {encoding dirs basic behavior} -returnCodes error -body { + encoding dirs "\{not a list" +} -result "expected directory list but got \"\{not a list\"" + } runtests -- cgit v0.12 From 5b2718a49ed67a4ac9378b222b1cab87cf55856b Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 25 Jun 2012 16:19:42 +0000 Subject: Repair Claim/Disclaim imbalance --- generic/tclIOUtil.c | 1 + 1 file changed, 1 insertion(+) diff --git a/generic/tclIOUtil.c b/generic/tclIOUtil.c index dccbeb5..b1b8961 100644 --- a/generic/tclIOUtil.c +++ b/generic/tclIOUtil.c @@ -4390,6 +4390,7 @@ Tcl_FSGetFileSystemForPath( Claim(); if (TclFSEnsureEpochOk(pathPtr, &retVal) != TCL_OK) { + Disclaim(); return NULL; } -- cgit v0.12 From ed0df6fdc2fe5089d09dc9c806ceb2fe98a67d89 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 26 Jun 2012 14:09:25 +0000 Subject: use cygwin_conv_path() in stead of deprecated cygwin_conv_to_full_posix_path --- unix/tclUnixFile.c | 7 +++---- unix/tclUnixPort.h | 10 ++++++++-- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/unix/tclUnixFile.c b/unix/tclUnixFile.c index 56acf6c..73237c5 100644 --- a/unix/tclUnixFile.c +++ b/unix/tclUnixFile.c @@ -48,7 +48,7 @@ TclpFindExecutable(argv0) { int length; #ifdef __CYGWIN__ - char buf[PATH_MAX * TCL_UTF_MAX + 1]; + char buf[PATH_MAX * 2]; char name[PATH_MAX * TCL_UTF_MAX + 1]; #else CONST char *name, *p; @@ -61,9 +61,8 @@ TclpFindExecutable(argv0) } #ifdef __CYGWIN__ - GetModuleFileNameW(NULL, name, PATH_MAX); - WideCharToMultiByte(CP_UTF8, 0, name, -1, buf, PATH_MAX, NULL, NULL); - cygwin_conv_to_full_posix_path(buf, name); + GetModuleFileNameW(NULL, buf, PATH_MAX); + cygwin_conv_path(3, buf, name, PATH_MAX); length = strlen(name); if ((length > 4) && !strcasecmp(name + length - 4, ".exe")) { /* Strip '.exe' part. */ diff --git a/unix/tclUnixPort.h b/unix/tclUnixPort.h index 7f913ca..e6e8303 100644 --- a/unix/tclUnixPort.h +++ b/unix/tclUnixPort.h @@ -26,7 +26,7 @@ #ifndef _TCLINT # include "tclInt.h" #endif - + /* *--------------------------------------------------------------------------- * The following sets of #includes and #ifdefs are required to get Tcl to @@ -54,6 +54,12 @@ # include #endif #endif + +/* + *--------------------------------------------------------------------------- + * Parameterize for 64-bit filesystem support. + *--------------------------------------------------------------------------- + */ #ifdef HAVE_STRUCT_DIRENT64 typedef struct dirent64 Tcl_DirEntry; @@ -88,7 +94,7 @@ typedef off_t Tcl_SeekOffset; DLLIMPORT extern __stdcall int WideCharToMultiByte(int, int, const char *, int, const char *, int, const char *, const char *); - DLLIMPORT extern int cygwin_conv_to_full_posix_path(const char *, char *); + DLLIMPORT extern int cygwin_conv_path(int, const void *, void *, int); EXTERN int TclOSstat(const char *name, Tcl_StatBuf *statBuf); EXTERN int TclOSlstat(const char *name, Tcl_StatBuf *statBuf); # define NO_FSTATFS -- cgit v0.12 From 20211223f452acef311b0d5a2b5467cad66b4ce5 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 26 Jun 2012 18:55:04 +0000 Subject: fix some gcc 64-bit warnings quoting improvements --- generic/tclIOSock.c | 8 ++++---- unix/configure | 12 ++++++------ unix/tcl.m4 | 12 ++++++------ 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/generic/tclIOSock.c b/generic/tclIOSock.c index 1e57cc0..251780c 100644 --- a/generic/tclIOSock.c +++ b/generic/tclIOSock.c @@ -97,16 +97,16 @@ TclSockMinimumBuffers(sock, size) socklen_t len; len = sizeof(int); - getsockopt((SOCKET)sock, SOL_SOCKET, SO_SNDBUF, (char *)¤t, &len); + getsockopt((SOCKET)(size_t)sock, SOL_SOCKET, SO_SNDBUF, (char *)¤t, &len); if (current < size) { len = sizeof(int); - setsockopt((SOCKET)sock, SOL_SOCKET, SO_SNDBUF, (char *)&size, len); + setsockopt((SOCKET)(size_t)sock, SOL_SOCKET, SO_SNDBUF, (char *)&size, len); } len = sizeof(int); - getsockopt((SOCKET)sock, SOL_SOCKET, SO_RCVBUF, (char *)¤t, &len); + getsockopt((SOCKET)(size_t)sock, SOL_SOCKET, SO_RCVBUF, (char *)¤t, &len); if (current < size) { len = sizeof(int); - setsockopt((SOCKET)sock, SOL_SOCKET, SO_RCVBUF, (char *)&size, len); + setsockopt((SOCKET)(size_t)sock, SOL_SOCKET, SO_RCVBUF, (char *)&size, len); } return TCL_OK; } diff --git a/unix/configure b/unix/configure index 183af23..3830e1b 100755 --- a/unix/configure +++ b/unix/configure @@ -4439,20 +4439,20 @@ fi LIB_SUFFIX=${SHARED_LIB_SUFFIX} MAKE_LIB='${SHLIB_LD} -o $@ ${OBJS} ${SHLIB_LD_LIBS} ${TCL_SHLIB_LD_EXTRAS} ${TK_SHLIB_LD_EXTRAS} ${LD_SEARCH_FLAGS}' if test "${SHLIB_SUFFIX}" = ".dll"; then - INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) $(BIN_INSTALL_DIR)/$(LIB_FILE)' + INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(BIN_INSTALL_DIR)/$(LIB_FILE)"' DLL_INSTALL_DIR="\$(BIN_INSTALL_DIR)" else - INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) $(LIB_INSTALL_DIR)/$(LIB_FILE)' + INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(LIB_INSTALL_DIR)/$(LIB_FILE)"' fi else LIB_SUFFIX=${UNSHARED_LIB_SUFFIX} if test "$RANLIB" = "" ; then MAKE_LIB='$(STLIB_LD) $@ ${OBJS}' - INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) $(LIB_INSTALL_DIR)/$(LIB_FILE)' + INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(LIB_INSTALL_DIR)/$(LIB_FILE)"' else MAKE_LIB='${STLIB_LD} $@ ${OBJS} ; ${RANLIB} $@' - INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) $(LIB_INSTALL_DIR)/$(LIB_FILE) ; (cd $(LIB_INSTALL_DIR) ; $(RANLIB) $(LIB_FILE))' + INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(LIB_INSTALL_DIR)/$(LIB_FILE)" ; (cd $(LIB_INSTALL_DIR) ; $(RANLIB) $(LIB_FILE))' fi fi @@ -4460,10 +4460,10 @@ fi # Stub lib does not depend on shared/static configuration if test "$RANLIB" = "" ; then MAKE_STUB_LIB='${STLIB_LD} $@ ${STUB_LIB_OBJS}' - INSTALL_STUB_LIB='$(INSTALL_LIBRARY) $(STUB_LIB_FILE) $(LIB_INSTALL_DIR)/$(STUB_LIB_FILE)' + INSTALL_STUB_LIB='$(INSTALL_LIBRARY) $(STUB_LIB_FILE) "$(LIB_INSTALL_DIR)/$(STUB_LIB_FILE)"' else MAKE_STUB_LIB='${STLIB_LD} $@ ${STUB_LIB_OBJS} ; ${RANLIB} $@' - INSTALL_STUB_LIB='$(INSTALL_LIBRARY) $(STUB_LIB_FILE) $(LIB_INSTALL_DIR)/$(STUB_LIB_FILE) ; (cd $(LIB_INSTALL_DIR) ; $(RANLIB) $(STUB_LIB_FILE))' + INSTALL_STUB_LIB='$(INSTALL_LIBRARY) $(STUB_LIB_FILE) "$(LIB_INSTALL_DIR)/$(STUB_LIB_FILE)" ; (cd "$(LIB_INSTALL_DIR)" ; $(RANLIB) $(STUB_LIB_FILE))' fi # See if the compiler supports casting to a union type. diff --git a/unix/tcl.m4 b/unix/tcl.m4 index 7161c91..c86a3f2 100644 --- a/unix/tcl.m4 +++ b/unix/tcl.m4 @@ -2211,20 +2211,20 @@ dnl # preprocessing tests use only CPPFLAGS. LIB_SUFFIX=${SHARED_LIB_SUFFIX} MAKE_LIB='${SHLIB_LD} -o [$]@ ${OBJS} ${SHLIB_LD_LIBS} ${TCL_SHLIB_LD_EXTRAS} ${TK_SHLIB_LD_EXTRAS} ${LD_SEARCH_FLAGS}' if test "${SHLIB_SUFFIX}" = ".dll"; then - INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) $(BIN_INSTALL_DIR)/$(LIB_FILE)' + INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(BIN_INSTALL_DIR)/$(LIB_FILE)"' DLL_INSTALL_DIR="\$(BIN_INSTALL_DIR)" else - INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) $(LIB_INSTALL_DIR)/$(LIB_FILE)' + INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(LIB_INSTALL_DIR)/$(LIB_FILE)"' fi else LIB_SUFFIX=${UNSHARED_LIB_SUFFIX} if test "$RANLIB" = "" ; then MAKE_LIB='$(STLIB_LD) [$]@ ${OBJS}' - INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) $(LIB_INSTALL_DIR)/$(LIB_FILE)' + INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(LIB_INSTALL_DIR)/$(LIB_FILE)"' else MAKE_LIB='${STLIB_LD} [$]@ ${OBJS} ; ${RANLIB} [$]@' - INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) $(LIB_INSTALL_DIR)/$(LIB_FILE) ; (cd $(LIB_INSTALL_DIR) ; $(RANLIB) $(LIB_FILE))' + INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(LIB_INSTALL_DIR)/$(LIB_FILE)" ; (cd $(LIB_INSTALL_DIR) ; $(RANLIB) $(LIB_FILE))' fi fi @@ -2232,10 +2232,10 @@ dnl # preprocessing tests use only CPPFLAGS. # Stub lib does not depend on shared/static configuration if test "$RANLIB" = "" ; then MAKE_STUB_LIB='${STLIB_LD} [$]@ ${STUB_LIB_OBJS}' - INSTALL_STUB_LIB='$(INSTALL_LIBRARY) $(STUB_LIB_FILE) $(LIB_INSTALL_DIR)/$(STUB_LIB_FILE)' + INSTALL_STUB_LIB='$(INSTALL_LIBRARY) $(STUB_LIB_FILE) "$(LIB_INSTALL_DIR)/$(STUB_LIB_FILE)"' else MAKE_STUB_LIB='${STLIB_LD} [$]@ ${STUB_LIB_OBJS} ; ${RANLIB} [$]@' - INSTALL_STUB_LIB='$(INSTALL_LIBRARY) $(STUB_LIB_FILE) $(LIB_INSTALL_DIR)/$(STUB_LIB_FILE) ; (cd $(LIB_INSTALL_DIR) ; $(RANLIB) $(STUB_LIB_FILE))' + INSTALL_STUB_LIB='$(INSTALL_LIBRARY) $(STUB_LIB_FILE) "$(LIB_INSTALL_DIR)/$(STUB_LIB_FILE)" ; (cd "$(LIB_INSTALL_DIR)" ; $(RANLIB) $(STUB_LIB_FILE))' fi # See if the compiler supports casting to a union type. -- cgit v0.12 From 5d1b8bbdece14d4ef6e3e24a73c13f0d46d2d77a Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Tue, 26 Jun 2012 19:48:12 +0000 Subject: merge fix --- unix/configure | 2 +- unix/tcl.m4 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/unix/configure b/unix/configure index af0aed2..86f3bd6 100755 --- a/unix/configure +++ b/unix/configure @@ -9001,7 +9001,7 @@ else else MAKE_LIB='${STLIB_LD} $@ ${OBJS} ; ${RANLIB} $@' - INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(LIB_INSTALL_DIR)/$(LIB_FILE) ; (cd "$(LIB_INSTALL_DIR)" ; $(RANLIB) $(LIB_FILE))' + INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(LIB_INSTALL_DIR)/$(LIB_FILE)" ; (cd "$(LIB_INSTALL_DIR)" ; $(RANLIB) $(LIB_FILE))' fi diff --git a/unix/tcl.m4 b/unix/tcl.m4 index da27719..0d64cc7 100644 --- a/unix/tcl.m4 +++ b/unix/tcl.m4 @@ -2118,7 +2118,7 @@ dnl # preprocessing tests use only CPPFLAGS. INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(LIB_INSTALL_DIR)/$(LIB_FILE)"' ], [ MAKE_LIB='${STLIB_LD} [$]@ ${OBJS} ; ${RANLIB} [$]@' - INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(LIB_INSTALL_DIR)/$(LIB_FILE) ; (cd "$(LIB_INSTALL_DIR)" ; $(RANLIB) $(LIB_FILE))' + INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(LIB_INSTALL_DIR)/$(LIB_FILE)" ; (cd "$(LIB_INSTALL_DIR)" ; $(RANLIB) $(LIB_FILE))' ]) ]) -- cgit v0.12 From f4e6a60dfb4f87476b5af1da6a0e1b3d9011db51 Mon Sep 17 00:00:00 2001 From: "jan.nijtmans" Date: Wed, 27 Jun 2012 12:49:12 +0000 Subject: fix bug in cygwin's [info nameofexecutable] install dde and registry dll for cygwin --- unix/Makefile.in | 28 +++++++++++++++++++++++----- unix/configure | 2 +- unix/tcl.m4 | 2 +- unix/tclConfig.sh.in | 2 +- unix/tclUnixFile.c | 2 +- 5 files changed, 27 insertions(+), 9 deletions(-) diff --git a/unix/Makefile.in b/unix/Makefile.in index aa771cc..04e8629 100644 --- a/unix/Makefile.in +++ b/unix/Makefile.in @@ -580,7 +580,7 @@ valgrindshell: tclsh topDirName: @cd $(TOP_DIR); pwd -# The following target generates the file generic/tclDate.c +# The following target generates the file generic/tclDate.c # from the yacc grammar found in generic/tclGetDate.y. This is # only run by hand as yacc is not available in all environments. # The name of the .c file is different than the name of the .y file @@ -619,7 +619,7 @@ install-strip: # possible (e.g. if installing as root). install-binaries: binaries - @for i in $(LIB_INSTALL_DIR) $(BIN_INSTALL_DIR) ; \ + @for i in "$(LIB_INSTALL_DIR)" "$(BIN_INSTALL_DIR)" ; \ do \ if [ ! -d $$i ] ; then \ echo "Making directory $$i"; \ @@ -647,10 +647,28 @@ install-binaries: binaries echo "Installing $(STUB_LIB_FILE) to $(LIB_INSTALL_DIR)/"; \ @INSTALL_STUB_LIB@ ; \ fi + @if test "x$(DLL_INSTALL_DIR)" = "x$(BIN_INSTALL_DIR)"; then\ + for i in dde1.2 reg1.1; do \ + if [ ! -d $(LIB_INSTALL_DIR)/$$i ] ; then \ + echo "Making directory $(LIB_INSTALL_DIR)/$$i";\ + mkdir -p $(LIB_INSTALL_DIR)/$$i;\ + chmod 755 $(LIB_INSTALL_DIR)/$$i;\ + else true;\ + fi;\ + done;\ + echo "Installing tcldde12.dll";\ + $(INSTALL_DATA) "$(TOP_DIR)/library/dde/pkgIndex.tcl" "$(LIB_INSTALL_DIR)/dde1.2";\ + $(INSTALL_LIBRARY) "$(TOP_DIR)/win/tcldde12.dll" "$(LIB_INSTALL_DIR)/dde1.2";\ + chmod 555 "$(LIB_INSTALL_DIR)/dde1.2/tcldde12.dll";\ + echo "Installing tclreg11.dll";\ + $(INSTALL_DATA) "$(TOP_DIR)/library/reg/pkgIndex.tcl" "$(LIB_INSTALL_DIR)/reg1.1";\ + $(INSTALL_LIBRARY) "$(TOP_DIR)/win/tclreg11.dll" "$(LIB_INSTALL_DIR)/reg1.1";\ + chmod 555 "$(LIB_INSTALL_DIR)/reg1.1/tclreg11.dll";\ + fi @EXTRA_INSTALL_BINARIES@ install-libraries: libraries - @for i in $(INCLUDE_INSTALL_DIR) $(SCRIPT_INSTALL_DIR); \ + @for i in "$(INCLUDE_INSTALL_DIR)" "$(SCRIPT_INSTALL_DIR)"; \ do \ if [ ! -d $$i ] ; then \ echo "Making directory $$i"; \ @@ -1443,7 +1461,7 @@ machtml: # # Targets to build Solaris package of the distribution for the current # architecture. To build stream packages for both sun4 and i86pc -# architectures: +# architectures: # # On the sun4 machine, execute the following: # make distclean; ./configure @@ -1497,7 +1515,7 @@ package-common: # Build and install the architecture specific files in the dist directory. # -package-binaries: +package-binaries: cd $(DISTDIR)/unix/`arch`; \ $(MAKE); \ $(MAKE) install-binaries prefix=$(DISTDIR)/$(PACKAGE)/$(VERSION) \ diff --git a/unix/configure b/unix/configure index 3830e1b..8d7cc20 100755 --- a/unix/configure +++ b/unix/configure @@ -4452,7 +4452,7 @@ fi INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(LIB_INSTALL_DIR)/$(LIB_FILE)"' else MAKE_LIB='${STLIB_LD} $@ ${OBJS} ; ${RANLIB} $@' - INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(LIB_INSTALL_DIR)/$(LIB_FILE)" ; (cd $(LIB_INSTALL_DIR) ; $(RANLIB) $(LIB_FILE))' + INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(LIB_INSTALL_DIR)/$(LIB_FILE)" ; (cd "$(LIB_INSTALL_DIR)" ; $(RANLIB) $(LIB_FILE))' fi fi diff --git a/unix/tcl.m4 b/unix/tcl.m4 index c86a3f2..ac9b3bf 100644 --- a/unix/tcl.m4 +++ b/unix/tcl.m4 @@ -2224,7 +2224,7 @@ dnl # preprocessing tests use only CPPFLAGS. INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(LIB_INSTALL_DIR)/$(LIB_FILE)"' else MAKE_LIB='${STLIB_LD} [$]@ ${OBJS} ; ${RANLIB} [$]@' - INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(LIB_INSTALL_DIR)/$(LIB_FILE)" ; (cd $(LIB_INSTALL_DIR) ; $(RANLIB) $(LIB_FILE))' + INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(LIB_INSTALL_DIR)/$(LIB_FILE)" ; (cd "$(LIB_INSTALL_DIR)" ; $(RANLIB) $(LIB_FILE))' fi fi diff --git a/unix/tclConfig.sh.in b/unix/tclConfig.sh.in index e3509df..07a524f 100644 --- a/unix/tclConfig.sh.in +++ b/unix/tclConfig.sh.in @@ -1,5 +1,5 @@ # tclConfig.sh -- -# +# # This shell script (for sh) is generated automatically by Tcl's # configure script. It will create shell variables for most of # the configuration options discovered by the configure script. diff --git a/unix/tclUnixFile.c b/unix/tclUnixFile.c index 73237c5..2616eda 100644 --- a/unix/tclUnixFile.c +++ b/unix/tclUnixFile.c @@ -70,7 +70,7 @@ TclpFindExecutable(argv0) } tclNativeExecutableName = (char *) ckalloc(length + 1); memcpy(tclNativeExecutableName, name, length); - buf[length] = '\0'; + tclNativeExecutableName[length] = '\0'; #else if (argv0 == NULL) { return NULL; -- cgit v0.12