diff options
Diffstat (limited to 'win')
-rw-r--r-- | win/tclWinFCmd.c | 47 |
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; } |