summaryrefslogtreecommitdiffstats
path: root/win/tclWinFCmd.c
diff options
context:
space:
mode:
authorvincentdarley <vincentdarley>2003-12-17 17:47:27 (GMT)
committervincentdarley <vincentdarley>2003-12-17 17:47:27 (GMT)
commit298b0c4ef39a21c71fcb823f41bb903203d8430b (patch)
tree90eee000212ab783686879d39d2836490e8198c8 /win/tclWinFCmd.c
parent1e34c25106c2c1a8713ef0aef0ffc4d2eccdbeeb (diff)
downloadtcl-298b0c4ef39a21c71fcb823f41bb903203d8430b.zip
tcl-298b0c4ef39a21c71fcb823f41bb903203d8430b.tar.gz
tcl-298b0c4ef39a21c71fcb823f41bb903203d8430b.tar.bz2
fix to file normalization with relative links
Diffstat (limited to 'win/tclWinFCmd.c')
-rw-r--r--win/tclWinFCmd.c47
1 files changed, 42 insertions, 5 deletions
diff --git a/win/tclWinFCmd.c b/win/tclWinFCmd.c
index 519df62..c565d33 100644
--- a/win/tclWinFCmd.c
+++ b/win/tclWinFCmd.c
@@ -9,7 +9,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclWinFCmd.c,v 1.37 2003/10/13 16:48:07 vincentdarley Exp $
+ * RCS: @(#) $Id: tclWinFCmd.c,v 1.38 2003/12/17 17:47:28 vincentdarley Exp $
*/
#include "tclWinInt.h"
@@ -22,6 +22,7 @@
#define DOTREE_PRED 1 /* pre-order directory */
#define DOTREE_POSTD 2 /* post-order directory */
#define DOTREE_F 3 /* regular file */
+#define DOTREE_LINK 4 /* symbolic link */
/*
* Callbacks for file attributes code.
@@ -969,6 +970,7 @@ DoRemoveJustDirectory(
* DString filled with UTF-8 name of file
* causing error. */
{
+ DWORD attr;
/*
* The RemoveDirectory API acts differently under Win95/98 and NT
* WRT NULL and "". Avoid passing these values.
@@ -979,13 +981,24 @@ DoRemoveJustDirectory(
goto end;
}
- if ((*tclWinProcs->removeDirectoryProc)(nativePath) != FALSE) {
- return TCL_OK;
+ attr = (*tclWinProcs->getFileAttributesProc)(nativePath);
+
+ if (attr & FILE_ATTRIBUTE_REPARSE_POINT) {
+ /* It is a symbolic link -- remove it */
+ if (TclWinSymLinkDelete(nativePath, 0) == 0) {
+ return TCL_OK;
+ }
+ } else {
+ /* Ordinary directory */
+ if ((*tclWinProcs->removeDirectoryProc)(nativePath) != FALSE) {
+ return TCL_OK;
+ }
}
+
TclWinConvertError(GetLastError());
if (Tcl_GetErrno() == EACCES) {
- DWORD attr = (*tclWinProcs->getFileAttributesProc)(nativePath);
+ attr = (*tclWinProcs->getFileAttributesProc)(nativePath);
if (attr != 0xffffffff) {
if ((attr & FILE_ATTRIBUTE_DIRECTORY) == 0) {
/*
@@ -1021,6 +1034,7 @@ DoRemoveJustDirectory(
* 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) {
@@ -1166,6 +1180,16 @@ TraverseWinTree(
nativeErrfile = nativeSource;
goto end;
}
+
+ if (sourceAttr & FILE_ATTRIBUTE_REPARSE_POINT) {
+ /*
+ * Process the symbolic link
+ */
+
+ return (*traverseProc)(nativeSource, nativeTarget,
+ DOTREE_LINK, errorPtr);
+ }
+
if ((sourceAttr & FILE_ATTRIBUTE_DIRECTORY) == 0) {
/*
* Process the regular file
@@ -1344,10 +1368,17 @@ TraversalCopy(
}
break;
}
+ case DOTREE_LINK: {
+ if (TclWinSymLinkCopyDirectory(nativeSrc, nativeDst) == TCL_OK) {
+ return TCL_OK;
+ }
+ break;
+ }
case DOTREE_PRED: {
if (DoCreateDirectory(nativeDst) == TCL_OK) {
DWORD attr = (*tclWinProcs->getFileAttributesProc)(nativeSrc);
- if ((*tclWinProcs->setFileAttributesProc)(nativeDst, attr) != FALSE) {
+ if ((*tclWinProcs->setFileAttributesProc)(nativeDst, attr)
+ != FALSE) {
return TCL_OK;
}
TclWinConvertError(GetLastError());
@@ -1406,6 +1437,12 @@ TraversalDelete(
}
break;
}
+ case DOTREE_LINK: {
+ if (DoRemoveJustDirectory(nativeSrc, 0, NULL) == TCL_OK) {
+ return TCL_OK;
+ }
+ break;
+ }
case DOTREE_PRED: {
return TCL_OK;
}