summaryrefslogtreecommitdiffstats
path: root/win/tclWinFCmd.c
diff options
context:
space:
mode:
Diffstat (limited to 'win/tclWinFCmd.c')
-rw-r--r--win/tclWinFCmd.c387
1 files changed, 237 insertions, 150 deletions
diff --git a/win/tclWinFCmd.c b/win/tclWinFCmd.c
index 52ea8c6..441337e 100644
--- a/win/tclWinFCmd.c
+++ b/win/tclWinFCmd.c
@@ -54,12 +54,12 @@ static const int attributeArray[] = {FILE_ATTRIBUTE_ARCHIVE, FILE_ATTRIBUTE_HIDD
0, FILE_ATTRIBUTE_READONLY, 0, FILE_ATTRIBUTE_SYSTEM};
-const char *const tclpFileAttrStrings[] = {
+CONST char *tclpFileAttrStrings[] = {
"-archive", "-hidden", "-longname", "-readonly",
"-shortname", "-system", (char *) NULL
};
-const TclFileAttrProcs tclpFileAttrProcs[] = {
+CONST TclFileAttrProcs tclpFileAttrProcs[] = {
{GetWinFileAttributes, SetWinFileAttributes},
{GetWinFileAttributes, SetWinFileAttributes},
{GetWinFileLongName, CannotSetAttribute},
@@ -71,7 +71,7 @@ const TclFileAttrProcs tclpFileAttrProcs[] = {
* Prototype for the TraverseWinTree callback function.
*/
-typedef int (TraversalProc)(const TCHAR *srcPtr, const TCHAR *dstPtr,
+typedef int (TraversalProc)(CONST TCHAR *srcPtr, CONST TCHAR *dstPtr,
int type, Tcl_DString *errorPtr);
/*
@@ -82,18 +82,18 @@ static void StatError(Tcl_Interp *interp, Tcl_Obj *fileName);
static int ConvertFileNameFormat(Tcl_Interp *interp,
int objIndex, Tcl_Obj *fileName, int longShort,
Tcl_Obj **attributePtrPtr);
-static int DoCopyFile(const TCHAR *srcPtr, const TCHAR *dstPtr);
-static int DoCreateDirectory(const TCHAR *pathPtr);
-static int DoRemoveJustDirectory(const TCHAR *nativeSrc,
+static int DoCopyFile(CONST TCHAR *srcPtr, CONST TCHAR *dstPtr);
+static int DoCreateDirectory(CONST TCHAR *pathPtr);
+static int DoRemoveJustDirectory(CONST TCHAR *nativeSrc,
int ignoreError, Tcl_DString *errorPtr);
static int DoRemoveDirectory(Tcl_DString *pathPtr, int recursive,
Tcl_DString *errorPtr);
-static int DoRenameFile(const TCHAR *nativeSrc,
- const TCHAR *dstPtr);
-static int TraversalCopy(const TCHAR *srcPtr, const TCHAR *dstPtr,
+static int DoRenameFile(CONST TCHAR *nativeSrc,
+ CONST TCHAR *dstPtr);
+static int TraversalCopy(CONST TCHAR *srcPtr, CONST TCHAR *dstPtr,
int type, Tcl_DString *errorPtr);
-static int TraversalDelete(const TCHAR *srcPtr,
- const TCHAR *dstPtr, int type,
+static int TraversalDelete(CONST TCHAR *srcPtr,
+ CONST TCHAR *dstPtr, int type,
Tcl_DString *errorPtr);
static int TraverseWinTree(TraversalProc *traverseProc,
Tcl_DString *sourcePtr, Tcl_DString *dstPtr,
@@ -151,9 +151,9 @@ TclpObjRenameFile(
static int
DoRenameFile(
- const TCHAR *nativeSrc, /* Pathname of file or dir to be renamed
+ CONST TCHAR *nativeSrc, /* Pathname of file or dir to be renamed
* (native). */
- const TCHAR *nativeDst) /* New pathname for file or directory
+ CONST TCHAR *nativeDst) /* New pathname for file or directory
* (native). */
{
#if defined(HAVE_NO_SEH) && !defined(_WIN64)
@@ -256,7 +256,7 @@ DoRenameFile(
[registration] "m" (registration),
[nativeDst] "m" (nativeDst),
[nativeSrc] "m" (nativeSrc),
- [moveFile] "r" (MoveFile)
+ [moveFile] "r" (tclWinProcs->moveFileProc)
:
"%eax", "%ebx", "%ecx", "%edx", "memory"
);
@@ -267,7 +267,7 @@ DoRenameFile(
#ifndef HAVE_NO_SEH
__try {
#endif
- if ((*MoveFile)(nativeSrc, nativeDst) != FALSE) {
+ if ((*tclWinProcs->moveFileProc)(nativeSrc, nativeDst) != FALSE) {
retval = TCL_OK;
}
#ifndef HAVE_NO_SEH
@@ -281,10 +281,10 @@ DoRenameFile(
TclWinConvertError(GetLastError());
- srcAttr = GetFileAttributes(nativeSrc);
- dstAttr = GetFileAttributes(nativeDst);
+ srcAttr = (*tclWinProcs->getFileAttributesProc)(nativeSrc);
+ dstAttr = (*tclWinProcs->getFileAttributesProc)(nativeDst);
if (srcAttr == 0xffffffff) {
- if (GetFullPathName(nativeSrc, 0, NULL,
+ if ((*tclWinProcs->getFullPathNameProc)(nativeSrc, 0, NULL,
NULL) >= MAX_PATH) {
errno = ENAMETOOLONG;
return TCL_ERROR;
@@ -292,7 +292,7 @@ DoRenameFile(
srcAttr = 0;
}
if (dstAttr == 0xffffffff) {
- if (GetFullPathName(nativeDst, 0, NULL,
+ if ((*tclWinProcs->getFullPathNameProc)(nativeDst, 0, NULL,
NULL) >= MAX_PATH) {
errno = ENAMETOOLONG;
return TCL_ERROR;
@@ -308,28 +308,28 @@ DoRenameFile(
decode:
if (srcAttr & FILE_ATTRIBUTE_DIRECTORY) {
TCHAR *nativeSrcRest, *nativeDstRest;
- const char **srcArgv, **dstArgv;
+ CONST char **srcArgv, **dstArgv;
int size, srcArgc, dstArgc;
- TCHAR nativeSrcPath[MAX_PATH];
- TCHAR nativeDstPath[MAX_PATH];
+ WCHAR nativeSrcPath[MAX_PATH];
+ WCHAR nativeDstPath[MAX_PATH];
Tcl_DString srcString, dstString;
- const char *src, *dst;
+ CONST char *src, *dst;
- size = GetFullPathName(nativeSrc, MAX_PATH,
+ size = (*tclWinProcs->getFullPathNameProc)(nativeSrc, MAX_PATH,
nativeSrcPath, &nativeSrcRest);
if ((size == 0) || (size > MAX_PATH)) {
return TCL_ERROR;
}
- size = GetFullPathName(nativeDst, MAX_PATH,
+ size = (*tclWinProcs->getFullPathNameProc)(nativeDst, MAX_PATH,
nativeDstPath, &nativeDstRest);
if ((size == 0) || (size > MAX_PATH)) {
return TCL_ERROR;
}
- CharLower(nativeSrcPath);
- CharLower(nativeDstPath);
+ (*tclWinProcs->charLowerProc)((TCHAR *) nativeSrcPath);
+ (*tclWinProcs->charLowerProc)((TCHAR *) nativeDstPath);
- src = Tcl_WinTCharToUtf(nativeSrcPath, -1, &srcString);
- dst = Tcl_WinTCharToUtf(nativeDstPath, -1, &dstString);
+ src = Tcl_WinTCharToUtf((TCHAR *) nativeSrcPath, -1, &srcString);
+ dst = Tcl_WinTCharToUtf((TCHAR *) nativeDstPath, -1, &dstString);
/*
* Check whether the destination path is actually inside the
@@ -376,8 +376,8 @@ DoRenameFile(
Tcl_SetErrno(EXDEV);
}
- ckfree(srcArgv);
- ckfree(dstArgv);
+ ckfree((char *) srcArgv);
+ ckfree((char *) dstArgv);
}
/*
@@ -408,7 +408,7 @@ DoRenameFile(
* directory back, for completeness.
*/
- if (MoveFile(nativeSrc,
+ if ((*tclWinProcs->moveFileProc)(nativeSrc,
nativeDst) != FALSE) {
return TCL_OK;
}
@@ -419,8 +419,8 @@ DoRenameFile(
*/
TclWinConvertError(GetLastError());
- CreateDirectory(nativeDst, NULL);
- SetFileAttributes(nativeDst, dstAttr);
+ (*tclWinProcs->createDirectoryProc)(nativeDst, NULL);
+ (*tclWinProcs->setFileAttributesProc)(nativeDst, dstAttr);
if (Tcl_GetErrno() == EACCES) {
/*
* Decode the EACCES to a more meaningful error.
@@ -447,20 +447,22 @@ DoRenameFile(
TCHAR *nativeRest, *nativeTmp, *nativePrefix;
int result, size;
- TCHAR tempBuf[MAX_PATH];
+ WCHAR tempBuf[MAX_PATH];
- size = GetFullPathName(nativeDst, MAX_PATH,
+ size = (*tclWinProcs->getFullPathNameProc)(nativeDst, MAX_PATH,
tempBuf, &nativeRest);
if ((size == 0) || (size > MAX_PATH) || (nativeRest == NULL)) {
return TCL_ERROR;
}
nativeTmp = (TCHAR *) tempBuf;
- nativeRest[0] = L'\0';
+ ((char *) nativeRest)[0] = '\0';
+ ((char *) nativeRest)[1] = '\0'; /* In case it's Unicode. */
result = TCL_ERROR;
- nativePrefix = (TCHAR *) L"tclr";
- if (GetTempFileName(nativeTmp, nativePrefix,
- 0, tempBuf) != 0) {
+ nativePrefix = (tclWinProcs->useWide)
+ ? (TCHAR *) L"tclr" : (TCHAR *) "tclr";
+ if ((*tclWinProcs->getTempFileNameProc)(nativeTmp,
+ nativePrefix, 0, tempBuf) != 0) {
/*
* Strictly speaking, need the following DeleteFile and
* MoveFile to be joined as an atomic operation so no
@@ -468,16 +470,19 @@ DoRenameFile(
* same temp file.
*/
- nativeTmp = tempBuf;
- DeleteFile(nativeTmp);
- if (MoveFile(nativeDst, nativeTmp) != FALSE) {
- if (MoveFile(nativeSrc, nativeDst) != FALSE) {
- SetFileAttributes(nativeTmp, FILE_ATTRIBUTE_NORMAL);
- DeleteFile(nativeTmp);
+ nativeTmp = (TCHAR *) tempBuf;
+ (*tclWinProcs->deleteFileProc)(nativeTmp);
+ if ((*tclWinProcs->moveFileProc)(nativeDst,
+ nativeTmp) != FALSE) {
+ if ((*tclWinProcs->moveFileProc)(nativeSrc,
+ nativeDst) != FALSE) {
+ (*tclWinProcs->setFileAttributesProc)(nativeTmp,
+ FILE_ATTRIBUTE_NORMAL);
+ (*tclWinProcs->deleteFileProc)(nativeTmp);
return TCL_OK;
} else {
- DeleteFile(nativeDst);
- MoveFile(nativeTmp, nativeDst);
+ (*tclWinProcs->deleteFileProc)(nativeDst);
+ (*tclWinProcs->moveFileProc)(nativeTmp, nativeDst);
}
}
@@ -540,8 +545,8 @@ TclpObjCopyFile(
static int
DoCopyFile(
- const TCHAR *nativeSrc, /* Pathname of file to be copied (native). */
- const TCHAR *nativeDst) /* Pathname of file to copy to (native). */
+ CONST TCHAR *nativeSrc, /* Pathname of file to be copied (native). */
+ CONST TCHAR *nativeDst) /* Pathname of file to copy to (native). */
{
#if defined(HAVE_NO_SEH) && !defined(_WIN64)
TCLEXCEPTION_REGISTRATION registration;
@@ -644,7 +649,7 @@ DoCopyFile(
[registration] "m" (registration),
[nativeDst] "m" (nativeDst),
[nativeSrc] "m" (nativeSrc),
- [copyFile] "r" (CopyFile)
+ [copyFile] "r" (tclWinProcs->copyFileProc)
:
"%eax", "%ebx", "%ecx", "%edx", "memory"
);
@@ -655,7 +660,7 @@ DoCopyFile(
#ifndef HAVE_NO_SEH
__try {
#endif
- if (CopyFile(nativeSrc, nativeDst, 0) != FALSE) {
+ if ((*tclWinProcs->copyFileProc)(nativeSrc, nativeDst, 0) != FALSE) {
retval = TCL_OK;
}
#ifndef HAVE_NO_SEH
@@ -675,8 +680,8 @@ DoCopyFile(
if (Tcl_GetErrno() == EACCES) {
DWORD srcAttr, dstAttr;
- srcAttr = GetFileAttributes(nativeSrc);
- dstAttr = GetFileAttributes(nativeDst);
+ srcAttr = (*tclWinProcs->getFileAttributesProc)(nativeSrc);
+ dstAttr = (*tclWinProcs->getFileAttributesProc)(nativeDst);
if (srcAttr != 0xffffffff) {
if (dstAttr == 0xffffffff) {
dstAttr = 0;
@@ -692,9 +697,9 @@ DoCopyFile(
Tcl_SetErrno(EISDIR);
}
if (dstAttr & FILE_ATTRIBUTE_READONLY) {
- SetFileAttributes(nativeDst,
+ (*tclWinProcs->setFileAttributesProc)(nativeDst,
dstAttr & ~((DWORD)FILE_ATTRIBUTE_READONLY));
- if (CopyFile(nativeSrc, nativeDst,
+ if ((*tclWinProcs->copyFileProc)(nativeSrc, nativeDst,
0) != FALSE) {
return TCL_OK;
}
@@ -705,7 +710,7 @@ DoCopyFile(
*/
TclWinConvertError(GetLastError());
- SetFileAttributes(nativeDst, dstAttr);
+ (*tclWinProcs->setFileAttributesProc)(nativeDst, dstAttr);
}
}
}
@@ -746,35 +751,34 @@ TclpObjDeleteFile(
int
TclpDeleteFile(
- const void *nativePath) /* Pathname of file to be removed (native). */
+ CONST TCHAR *nativePath) /* Pathname of file to be removed (native). */
{
DWORD attr;
- const TCHAR *path = nativePath;
/*
* The DeleteFile API acts differently under Win95/98 and NT WRT NULL and
* "". Avoid passing these values.
*/
- if (path == NULL || path[0] == '\0') {
+ if (nativePath == NULL || nativePath[0] == '\0') {
Tcl_SetErrno(ENOENT);
return TCL_ERROR;
}
- if (DeleteFile(path) != FALSE) {
+ if ((*tclWinProcs->deleteFileProc)(nativePath) != FALSE) {
return TCL_OK;
}
TclWinConvertError(GetLastError());
if (Tcl_GetErrno() == EACCES) {
- attr = GetFileAttributes(path);
+ attr = (*tclWinProcs->getFileAttributesProc)(nativePath);
if (attr != 0xffffffff) {
if (attr & FILE_ATTRIBUTE_DIRECTORY) {
if (attr & FILE_ATTRIBUTE_REPARSE_POINT) {
/*
* It is a symbolic link - remove it.
*/
- if (TclWinSymLinkDelete(path, 0) == 0) {
+ if (TclWinSymLinkDelete(nativePath, 0) == 0) {
return TCL_OK;
}
}
@@ -788,21 +792,21 @@ TclpDeleteFile(
Tcl_SetErrno(EISDIR);
} else if (attr & FILE_ATTRIBUTE_READONLY) {
- int res = SetFileAttributes(path,
- attr & ~((DWORD) FILE_ATTRIBUTE_READONLY));
+ int res = (*tclWinProcs->setFileAttributesProc)(nativePath,
+ attr & ~((DWORD)FILE_ATTRIBUTE_READONLY));
- if ((res != 0) &&
- (DeleteFile(path) != FALSE)) {
+ if ((res != 0) && ((*tclWinProcs->deleteFileProc)(nativePath)
+ != FALSE)) {
return TCL_OK;
}
TclWinConvertError(GetLastError());
if (res != 0) {
- SetFileAttributes(path, attr);
+ (*tclWinProcs->setFileAttributesProc)(nativePath, attr);
}
}
}
} else if (Tcl_GetErrno() == ENOENT) {
- attr = GetFileAttributes(path);
+ attr = (*tclWinProcs->getFileAttributesProc)(nativePath);
if (attr != 0xffffffff) {
if (attr & FILE_ATTRIBUTE_DIRECTORY) {
/*
@@ -859,11 +863,11 @@ TclpObjCreateDirectory(
static int
DoCreateDirectory(
- const TCHAR *nativePath) /* Pathname of directory to create (native). */
+ CONST TCHAR *nativePath) /* Pathname of directory to create (native). */
{
- if (CreateDirectory(nativePath, NULL) == 0) {
- DWORD error = GetLastError();
-
+ DWORD error;
+ if ((*tclWinProcs->createDirectoryProc)(nativePath, NULL) == 0) {
+ error = GetLastError();
TclWinConvertError(error);
return TCL_ERROR;
}
@@ -992,12 +996,13 @@ TclpObjRemoveDirectory(
}
if (ret != TCL_OK) {
- if (Tcl_DStringLength(&ds) > 0) {
+ int len = Tcl_DStringLength(&ds);
+ if (len > 0) {
if (normPtr != NULL &&
!strcmp(Tcl_DStringValue(&ds), TclGetString(normPtr))) {
*errorPtr = pathPtr;
} else {
- *errorPtr = TclDStringToObj(&ds);
+ *errorPtr = Tcl_NewStringObj(Tcl_DStringValue(&ds), -1);
}
Tcl_IncrRefCount(*errorPtr);
}
@@ -1009,7 +1014,7 @@ TclpObjRemoveDirectory(
static int
DoRemoveJustDirectory(
- const TCHAR *nativePath, /* Pathname of directory to be removed
+ CONST TCHAR *nativePath, /* Pathname of directory to be removed
* (native). */
int ignoreError, /* If non-zero, don't initialize the errorPtr
* under some circumstances on return. */
@@ -1029,7 +1034,7 @@ DoRemoveJustDirectory(
goto end;
}
- attr = GetFileAttributes(nativePath);
+ attr = (*tclWinProcs->getFileAttributesProc)(nativePath);
if (attr & FILE_ATTRIBUTE_REPARSE_POINT) {
/*
@@ -1043,7 +1048,7 @@ DoRemoveJustDirectory(
* Ordinary directory.
*/
- if (RemoveDirectory(nativePath) != FALSE) {
+ if ((*tclWinProcs->removeDirectoryProc)(nativePath) != FALSE) {
return TCL_OK;
}
}
@@ -1051,7 +1056,7 @@ DoRemoveJustDirectory(
TclWinConvertError(GetLastError());
if (Tcl_GetErrno() == EACCES) {
- attr = GetFileAttributes(nativePath);
+ attr = (*tclWinProcs->getFileAttributesProc)(nativePath);
if (attr != 0xffffffff) {
if ((attr & FILE_ATTRIBUTE_DIRECTORY) == 0) {
/*
@@ -1075,17 +1080,60 @@ DoRemoveJustDirectory(
if (attr & FILE_ATTRIBUTE_READONLY) {
attr &= ~FILE_ATTRIBUTE_READONLY;
- if (SetFileAttributes(nativePath,
+ if ((*tclWinProcs->setFileAttributesProc)(nativePath,
attr) == FALSE) {
goto end;
}
- if (RemoveDirectory(nativePath) != FALSE) {
+ if ((*tclWinProcs->removeDirectoryProc)(nativePath) != FALSE) {
return TCL_OK;
}
TclWinConvertError(GetLastError());
- SetFileAttributes(nativePath,
+ (*tclWinProcs->setFileAttributesProc)(nativePath,
attr | FILE_ATTRIBUTE_READONLY);
}
+
+ /*
+ * Windows 95 and Win32s report removing a non-empty directory as
+ * EACCES, not EEXIST. If the directory is not empty, change errno
+ * so caller knows what's going on.
+ */
+
+ if (TclWinGetPlatformId() != VER_PLATFORM_WIN32_NT) {
+ CONST char *path, *find;
+ HANDLE handle;
+ WIN32_FIND_DATAA data;
+ Tcl_DString buffer;
+ int len;
+
+ path = (CONST char *) nativePath;
+
+ Tcl_DStringInit(&buffer);
+ len = strlen(path);
+ find = Tcl_DStringAppend(&buffer, path, len);
+ if ((len > 0) && (find[len - 1] != '\\')) {
+ Tcl_DStringAppend(&buffer, "\\", 1);
+ }
+ find = Tcl_DStringAppend(&buffer, "*.*", 3);
+ handle = FindFirstFileA(find, &data);
+ if (handle != INVALID_HANDLE_VALUE) {
+ while (1) {
+ if ((strcmp(data.cFileName, ".") != 0)
+ && (strcmp(data.cFileName, "..") != 0)) {
+ /*
+ * Found something in this directory.
+ */
+
+ Tcl_SetErrno(EEXIST);
+ break;
+ }
+ if (FindNextFileA(handle, &data) == FALSE) {
+ break;
+ }
+ }
+ FindClose(handle);
+ }
+ Tcl_DStringFree(&buffer);
+ }
}
}
@@ -1130,7 +1178,7 @@ DoRemoveDirectory(
* filled with UTF-8 name of file causing
* error. */
{
- int res = DoRemoveJustDirectory((const TCHAR *)Tcl_DStringValue(pathPtr), recursive,
+ int res = DoRemoveJustDirectory(Tcl_DStringValue(pathPtr), recursive,
errorPtr);
if ((res == TCL_ERROR) && (recursive != 0) && (Tcl_GetErrno() == EEXIST)) {
@@ -1184,7 +1232,7 @@ TraverseWinTree(
TCHAR *nativeSource, *nativeTarget, *nativeErrfile;
int result, found, sourceLen, targetLen = 0, oldSourceLen, oldTargetLen;
HANDLE handle;
- WIN32_FIND_DATA data;
+ WIN32_FIND_DATAT data;
nativeErrfile = NULL;
result = TCL_OK;
@@ -1195,7 +1243,7 @@ TraverseWinTree(
(targetPtr == NULL ? NULL : Tcl_DStringValue(targetPtr));
oldSourceLen = Tcl_DStringLength(sourcePtr);
- sourceAttr = GetFileAttributes(nativeSource);
+ sourceAttr = (*tclWinProcs->getFileAttributesProc)(nativeSource);
if (sourceAttr == 0xffffffff) {
nativeErrfile = nativeSource;
goto end;
@@ -1206,7 +1254,7 @@ TraverseWinTree(
* Process the symbolic link
*/
- return traverseProc(nativeSource, nativeTarget, DOTREE_LINK,
+ return (*traverseProc)(nativeSource, nativeTarget, DOTREE_LINK,
errorPtr);
}
@@ -1215,14 +1263,18 @@ TraverseWinTree(
* Process the regular file
*/
- return traverseProc(nativeSource, nativeTarget, DOTREE_F, errorPtr);
+ return (*traverseProc)(nativeSource, nativeTarget, DOTREE_F, errorPtr);
}
- Tcl_DStringAppend(sourcePtr, (char *) TEXT("\\*.*"), 4 * sizeof(TCHAR) + 1);
- Tcl_DStringSetLength(sourcePtr, Tcl_DStringLength(sourcePtr) - 1);
+ if (tclWinProcs->useWide) {
+ Tcl_DStringAppend(sourcePtr, (char *) L"\\*.*", 4 * sizeof(WCHAR) + 1);
+ Tcl_DStringSetLength(sourcePtr, Tcl_DStringLength(sourcePtr) - 1);
+ } else {
+ Tcl_DStringAppend(sourcePtr, "\\*.*", 4);
+ }
nativeSource = (TCHAR *) Tcl_DStringValue(sourcePtr);
- handle = FindFirstFile(nativeSource, &data);
+ handle = (*tclWinProcs->findFirstFileProc)(nativeSource, &data);
if (handle == INVALID_HANDLE_VALUE) {
/*
* Can't read directory.
@@ -1233,44 +1285,67 @@ TraverseWinTree(
goto end;
}
- Tcl_DStringSetLength(sourcePtr, oldSourceLen + 1);
+ nativeSource[oldSourceLen + 1] = '\0';
Tcl_DStringSetLength(sourcePtr, oldSourceLen);
- result = traverseProc(nativeSource, nativeTarget, DOTREE_PRED,
+ result = (*traverseProc)(nativeSource, nativeTarget, DOTREE_PRED,
errorPtr);
if (result != TCL_OK) {
FindClose(handle);
return result;
}
- sourceLen = oldSourceLen + sizeof(TCHAR);
- Tcl_DStringAppend(sourcePtr, (char *) TEXT("\\"), sizeof(TCHAR) + 1);
- Tcl_DStringSetLength(sourcePtr, sourceLen);
+ sourceLen = oldSourceLen;
+
+ if (tclWinProcs->useWide) {
+ sourceLen += sizeof(WCHAR);
+ Tcl_DStringAppend(sourcePtr, (char *) L"\\", sizeof(WCHAR) + 1);
+ Tcl_DStringSetLength(sourcePtr, sourceLen);
+ } else {
+ sourceLen += 1;
+ Tcl_DStringAppend(sourcePtr, "\\", 1);
+ }
if (targetPtr != NULL) {
oldTargetLen = Tcl_DStringLength(targetPtr);
targetLen = oldTargetLen;
- targetLen += sizeof(TCHAR);
- Tcl_DStringAppend(targetPtr, (char *) TEXT("\\"), sizeof(TCHAR) + 1);
- Tcl_DStringSetLength(targetPtr, targetLen);
+ if (tclWinProcs->useWide) {
+ targetLen += sizeof(WCHAR);
+ Tcl_DStringAppend(targetPtr, (char *) L"\\", sizeof(WCHAR) + 1);
+ Tcl_DStringSetLength(targetPtr, targetLen);
+ } else {
+ targetLen += 1;
+ Tcl_DStringAppend(targetPtr, "\\", 1);
+ }
}
found = 1;
- for (; found; found = FindNextFile(handle, &data)) {
+ for (; found; found = (*tclWinProcs->findNextFileProc)(handle, &data)) {
TCHAR *nativeName;
int len;
- TCHAR *wp = data.cFileName;
- if (*wp == '.') {
- wp++;
+ if (tclWinProcs->useWide) {
+ WCHAR *wp;
+
+ wp = data.w.cFileName;
if (*wp == '.') {
wp++;
+ if (*wp == '.') {
+ wp++;
+ }
+ if (*wp == '\0') {
+ continue;
+ }
}
- if (*wp == '\0') {
+ nativeName = (TCHAR *) data.w.cFileName;
+ len = wcslen(data.w.cFileName) * sizeof(WCHAR);
+ } else {
+ if ((strcmp(data.a.cFileName, ".") == 0)
+ || (strcmp(data.a.cFileName, "..") == 0)) {
continue;
}
+ nativeName = (TCHAR *) data.a.cFileName;
+ len = strlen(data.a.cFileName);
}
- nativeName = (TCHAR *) data.cFileName;
- len = _tcslen(data.cFileName) * sizeof(TCHAR);
/*
* Append name after slash, and recurse on the file.
@@ -1315,8 +1390,8 @@ TraverseWinTree(
* files in that directory.
*/
- result = traverseProc((const TCHAR *)Tcl_DStringValue(sourcePtr),
- (const TCHAR *)(targetPtr == NULL ? NULL : Tcl_DStringValue(targetPtr)),
+ result = (*traverseProc)(Tcl_DStringValue(sourcePtr),
+ (targetPtr == NULL ? NULL : Tcl_DStringValue(targetPtr)),
DOTREE_POSTD, errorPtr);
}
@@ -1351,8 +1426,8 @@ TraverseWinTree(
static int
TraversalCopy(
- const TCHAR *nativeSrc, /* Source pathname to copy. */
- const TCHAR *nativeDst, /* Destination pathname of copy. */
+ CONST TCHAR *nativeSrc, /* Source pathname to copy. */
+ CONST TCHAR *nativeDst, /* Destination pathname of copy. */
int type, /* Reason for call - see TraverseWinTree() */
Tcl_DString *errorPtr) /* If non-NULL, initialized DString filled
* with UTF-8 name of file causing error. */
@@ -1370,9 +1445,9 @@ TraversalCopy(
break;
case DOTREE_PRED:
if (DoCreateDirectory(nativeDst) == TCL_OK) {
- DWORD attr = GetFileAttributes(nativeSrc);
+ DWORD attr = (tclWinProcs->getFileAttributesProc)(nativeSrc);
- if (SetFileAttributes(nativeDst,
+ if ((tclWinProcs->setFileAttributesProc)(nativeDst,
attr) != FALSE) {
return TCL_OK;
}
@@ -1417,8 +1492,8 @@ TraversalCopy(
static int
TraversalDelete(
- const TCHAR *nativeSrc, /* Source pathname to delete. */
- const TCHAR *dstPtr, /* Not used. */
+ CONST TCHAR *nativeSrc, /* Source pathname to delete. */
+ CONST TCHAR *dstPtr, /* Not used. */
int type, /* Reason for call - see TraverseWinTree() */
Tcl_DString *errorPtr) /* If non-NULL, initialized DString filled
* with UTF-8 name of file causing error. */
@@ -1473,8 +1548,8 @@ StatError(
* error. */
{
TclWinConvertError(GetLastError());
- Tcl_SetObjResult(interp, Tcl_ObjPrintf("could not read \"%s\": %s",
- TclGetString(fileName), Tcl_PosixError(interp)));
+ Tcl_AppendResult(interp, "could not read \"", TclGetString(fileName),
+ "\": ", Tcl_PosixError(interp), (char *) NULL);
}
/*
@@ -1504,11 +1579,11 @@ GetWinFileAttributes(
Tcl_Obj **attributePtrPtr) /* A pointer to return the object with. */
{
DWORD result;
- const TCHAR *nativeName;
+ CONST TCHAR *nativeName;
int attr;
nativeName = Tcl_FSGetNativePath(fileName);
- result = GetFileAttributes(nativeName);
+ result = (*tclWinProcs->getFileAttributesProc)(nativeName);
if (result == 0xffffffff) {
StatError(interp, fileName);
@@ -1526,7 +1601,7 @@ GetWinFileAttributes(
*/
int len;
- const char *str = Tcl_GetStringFromObj(fileName,&len);
+ char *str = Tcl_GetStringFromObj(fileName,&len);
if (len < 4) {
if (len == 0) {
@@ -1592,11 +1667,9 @@ ConvertFileNameFormat(
if (splitPath == NULL || pathc == 0) {
if (interp != NULL) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "could not read \"%s\": no such file or directory",
- Tcl_GetString(fileName)));
- errno = ENOENT;
- Tcl_PosixError(interp);
+ Tcl_AppendResult(interp, "could not read \"",
+ Tcl_GetString(fileName), "\": no such file or directory",
+ (char *) NULL);
}
goto cleanup;
}
@@ -1637,10 +1710,10 @@ ConvertFileNameFormat(
Tcl_Obj *tempPath;
Tcl_DString ds;
Tcl_DString dsTemp;
- const TCHAR *nativeName;
- const char *tempString;
+ TCHAR *nativeName;
+ char *tempString;
int tempLen;
- WIN32_FIND_DATA data;
+ WIN32_FIND_DATAT data;
HANDLE handle;
DWORD attr;
@@ -1656,7 +1729,7 @@ ConvertFileNameFormat(
tempString = Tcl_GetStringFromObj(tempPath,&tempLen);
nativeName = Tcl_WinUtfToTChar(tempString, tempLen, &ds);
Tcl_DecrRefCount(tempPath);
- handle = FindFirstFile(nativeName, &data);
+ handle = (*tclWinProcs->findFirstFileProc)(nativeName, &data);
if (handle == INVALID_HANDLE_VALUE) {
/*
* FindFirstFile() doesn't like root directories. We would
@@ -1665,7 +1738,7 @@ ConvertFileNameFormat(
* root directory
*/
- attr = GetFileAttributes(nativeName);
+ attr = (*tclWinProcs->getFileAttributesProc)(nativeName);
if ((attr!=0xFFFFFFFF) && (attr & FILE_ATTRIBUTE_DIRECTORY)) {
Tcl_DStringFree(&ds);
goto simple;
@@ -1679,14 +1752,27 @@ ConvertFileNameFormat(
}
goto cleanup;
}
- nativeName = data.cAlternateFileName;
- if (longShort) {
- if (data.cFileName[0] != '\0') {
- nativeName = data.cFileName;
+ if (tclWinProcs->useWide) {
+ nativeName = (TCHAR *) data.w.cAlternateFileName;
+ if (longShort) {
+ if (data.w.cFileName[0] != '\0') {
+ nativeName = (TCHAR *) data.w.cFileName;
+ }
+ } else {
+ if (data.w.cAlternateFileName[0] == '\0') {
+ nativeName = (TCHAR *) data.w.cFileName;
+ }
}
} else {
- if (data.cAlternateFileName[0] == '\0') {
- nativeName = (TCHAR *) data.cFileName;
+ nativeName = (TCHAR *) data.a.cAlternateFileName;
+ if (longShort) {
+ if (data.a.cFileName[0] != '\0') {
+ nativeName = (TCHAR *) data.a.cFileName;
+ }
+ } else {
+ if (data.a.cAlternateFileName[0] == '\0') {
+ nativeName = (TCHAR *) data.a.cFileName;
+ }
}
}
@@ -1704,21 +1790,22 @@ ConvertFileNameFormat(
Tcl_DStringInit(&dsTemp);
Tcl_WinTCharToUtf(nativeName, -1, &dsTemp);
- Tcl_DStringFree(&ds);
/*
* Deal with issues of tildes being absolute.
*/
if (Tcl_DStringValue(&dsTemp)[0] == '~') {
- TclNewLiteralStringObj(tempPath, "./");
+ tempPath = Tcl_NewStringObj("./",2);
Tcl_AppendToObj(tempPath, Tcl_DStringValue(&dsTemp),
Tcl_DStringLength(&dsTemp));
- Tcl_DStringFree(&dsTemp);
} else {
- tempPath = TclDStringToObj(&dsTemp);
+ tempPath = Tcl_NewStringObj(Tcl_DStringValue(&dsTemp),
+ Tcl_DStringLength(&dsTemp));
}
Tcl_ListObjReplace(NULL, splitPath, i, 1, 1, &tempPath);
+ Tcl_DStringFree(&ds);
+ Tcl_DStringFree(&dsTemp);
FindClose(handle);
}
}
@@ -1830,12 +1917,13 @@ SetWinFileAttributes(
Tcl_Obj *fileName, /* The name of the file. */
Tcl_Obj *attributePtr) /* The new value of the attribute. */
{
- DWORD fileAttributes, old;
- int yesNo, result;
- const TCHAR *nativeName;
+ DWORD fileAttributes;
+ int yesNo;
+ int result;
+ CONST TCHAR *nativeName;
nativeName = Tcl_FSGetNativePath(fileName);
- fileAttributes = old = GetFileAttributes(nativeName);
+ fileAttributes = (*tclWinProcs->getFileAttributesProc)(nativeName);
if (fileAttributes == 0xffffffff) {
StatError(interp, fileName);
@@ -1853,8 +1941,7 @@ SetWinFileAttributes(
fileAttributes &= ~(attributeArray[objIndex]);
}
- if ((fileAttributes != old)
- && !SetFileAttributes(nativeName, fileAttributes)) {
+ if (!(*tclWinProcs->setFileAttributesProc)(nativeName, fileAttributes)) {
StatError(interp, fileName);
return TCL_ERROR;
}
@@ -1885,13 +1972,13 @@ CannotSetAttribute(
Tcl_Obj *fileName, /* The name of the file. */
Tcl_Obj *attributePtr) /* The new value of the attribute. */
{
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "cannot set attribute \"%s\" for file \"%s\": attribute is readonly",
- tclpFileAttrStrings[objIndex], Tcl_GetString(fileName)));
- errno = EINVAL;
- Tcl_PosixError(interp);
+ Tcl_AppendResult(interp, "cannot set attribute \"",
+ tclpFileAttrStrings[objIndex], "\" for file \"",
+ Tcl_GetString(fileName), "\": attribute is readonly",
+ (char *) NULL);
return TCL_ERROR;
}
+
/*
*---------------------------------------------------------------------------
@@ -1909,7 +1996,7 @@ CannotSetAttribute(
*---------------------------------------------------------------------------
*/
-Tcl_Obj *
+Tcl_Obj*
TclpObjListVolumes(void)
{
Tcl_Obj *resultPtr, *elemPtr;