summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordas <das>2002-04-19 14:18:33 (GMT)
committerdas <das>2002-04-19 14:18:33 (GMT)
commit26bb2b5da7f034e47d6544e3d84e54c861f61206 (patch)
tree323d0314781d4b46fbb081c3751bb12a9e56feb8
parentd2af1305c613b7c578a4b5be8e1ff487917b4237 (diff)
downloadtcl-26bb2b5da7f034e47d6544e3d84e54c861f61206.zip
tcl-26bb2b5da7f034e47d6544e3d84e54c861f61206.tar.gz
tcl-26bb2b5da7f034e47d6544e3d84e54c861f61206.tar.bz2
2002-04-20 Daniel Steffen <das@users.sourceforge.net>
* generic/tclInt.decls: * generic/tclIntPlatDecls.h: * generic/tclStubInit.c: * mac/tclMacFCmd.c: * mac/tclMacFile.c: * mac/tclMacUtil.c: Modified TclpObjNormalizePath to be alias file aware, and replaced various calls to FSpLocationFrom*Path by calls to new alias file aware versions FSpLLocationFrom*Path. The alias file aware routines don't resolve the last component of a path if it is an alias. This allows [file copy/delete] etc. to act correctly on alias files. (c.f. discussion in Bug #511666)
-rw-r--r--ChangeLog14
-rw-r--r--generic/tclInt.decls6
-rw-r--r--generic/tclIntPlatDecls.h10
-rw-r--r--generic/tclStubInit.c3
-rw-r--r--mac/tclMacFCmd.c32
-rw-r--r--mac/tclMacFile.c36
-rw-r--r--mac/tclMacUtil.c51
7 files changed, 130 insertions, 22 deletions
diff --git a/ChangeLog b/ChangeLog
index 2748cf5..098c648 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2002-04-20 Daniel Steffen <das@users.sourceforge.net>
+
+ * generic/tclInt.decls:
+ * generic/tclIntPlatDecls.h:
+ * generic/tclStubInit.c:
+ * mac/tclMacFCmd.c:
+ * mac/tclMacFile.c:
+ * mac/tclMacUtil.c: Modified TclpObjNormalizePath to be alias
+ file aware, and replaced various calls to FSpLocationFrom*Path
+ by calls to new alias file aware versions FSpLLocationFrom*Path.
+ The alias file aware routines don't resolve the last component of
+ a path if it is an alias. This allows [file copy/delete] etc. to
+ act correctly on alias files. (c.f. discussion in Bug #511666)
+
2002-04-19 Donal K. Fellows <fellowsd@cs.man.ac.uk>
* tests/lindex.test (lindex-3.7):
diff --git a/generic/tclInt.decls b/generic/tclInt.decls
index ca33071..4b6523c 100644
--- a/generic/tclInt.decls
+++ b/generic/tclInt.decls
@@ -12,7 +12,7 @@
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
-# RCS: @(#) $Id: tclInt.decls,v 1.47 2002/03/20 22:47:36 dgp Exp $
+# RCS: @(#) $Id: tclInt.decls,v 1.48 2002/04/19 14:18:33 das Exp $
library tcl
@@ -780,6 +780,10 @@ declare 24 mac {
declare 25 mac {
int TclMacChmod(CONST char *path, int mode)
}
+# version of FSpLocationFromPath that doesn't resolve the last path component
+declare 26 mac {
+ int FSpLLocationFromPath(int length, CONST char *path, FSSpecPtr theSpec)
+}
############################
# Windows specific internals
diff --git a/generic/tclIntPlatDecls.h b/generic/tclIntPlatDecls.h
index 907a648..090d3d1 100644
--- a/generic/tclIntPlatDecls.h
+++ b/generic/tclIntPlatDecls.h
@@ -9,7 +9,7 @@
* Copyright (c) 1998-1999 by Scriptics Corporation.
* All rights reserved.
*
- * RCS: @(#) $Id: tclIntPlatDecls.h,v 1.16 2002/01/27 11:09:34 das Exp $
+ * RCS: @(#) $Id: tclIntPlatDecls.h,v 1.17 2002/04/19 14:18:38 das Exp $
*/
#ifndef _TCLINTPLATDECLS
@@ -198,6 +198,9 @@ EXTERN FILE * TclMacFOpenHack _ANSI_ARGS_((CONST char * path,
EXTERN char * TclpGetTZName _ANSI_ARGS_((int isdst));
/* 25 */
EXTERN int TclMacChmod _ANSI_ARGS_((CONST char * path, int mode));
+/* 26 */
+EXTERN int FSpLLocationFromPath _ANSI_ARGS_((int length,
+ CONST char * path, FSSpecPtr theSpec));
#endif /* MAC_TCL */
typedef struct TclIntPlatStubs {
@@ -273,6 +276,7 @@ typedef struct TclIntPlatStubs {
FILE * (*tclMacFOpenHack) _ANSI_ARGS_((CONST char * path, CONST char * mode)); /* 23 */
char * (*tclpGetTZName) _ANSI_ARGS_((int isdst)); /* 24 */
int (*tclMacChmod) _ANSI_ARGS_((CONST char * path, int mode)); /* 25 */
+ int (*fSpLLocationFromPath) _ANSI_ARGS_((int length, CONST char * path, FSSpecPtr theSpec)); /* 26 */
#endif /* MAC_TCL */
} TclIntPlatStubs;
@@ -533,6 +537,10 @@ extern TclIntPlatStubs *tclIntPlatStubsPtr;
#define TclMacChmod \
(tclIntPlatStubsPtr->tclMacChmod) /* 25 */
#endif
+#ifndef FSpLLocationFromPath
+#define FSpLLocationFromPath \
+ (tclIntPlatStubsPtr->fSpLLocationFromPath) /* 26 */
+#endif
#endif /* MAC_TCL */
#endif /* defined(USE_TCL_STUBS) && !defined(USE_TCL_STUB_PROCS) */
diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c
index 0ece7d5..52ee177 100644
--- a/generic/tclStubInit.c
+++ b/generic/tclStubInit.c
@@ -8,7 +8,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclStubInit.c,v 1.68 2002/02/15 14:28:49 dkf Exp $
+ * RCS: @(#) $Id: tclStubInit.c,v 1.69 2002/04/19 14:19:02 das Exp $
*/
#include "tclInt.h"
@@ -322,6 +322,7 @@ TclIntPlatStubs tclIntPlatStubs = {
TclMacFOpenHack, /* 23 */
TclpGetTZName, /* 24 */
TclMacChmod, /* 25 */
+ FSpLLocationFromPath, /* 26 */
#endif /* MAC_TCL */
};
diff --git a/mac/tclMacFCmd.c b/mac/tclMacFCmd.c
index 1a75ce7..e22b365 100644
--- a/mac/tclMacFCmd.c
+++ b/mac/tclMacFCmd.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: tclMacFCmd.c,v 1.16 2002/01/27 11:09:44 das Exp $
+ * RCS: @(#) $Id: tclMacFCmd.c,v 1.17 2002/04/19 14:18:45 das Exp $
*/
#include "tclInt.h"
@@ -154,7 +154,7 @@ DoRenameFile(
long srcID, dummy;
Boolean srcIsDirectory, dstIsDirectory, dstExists, dstLocked;
- err = FSpLocationFromPath(strlen(src), src, &srcFileSpec);
+ err = FSpLLocationFromPath(strlen(src), src, &srcFileSpec);
if (err == noErr) {
FSpGetDirectoryID(&srcFileSpec, &srcID, &srcIsDirectory);
}
@@ -417,7 +417,7 @@ DoCopyFile(
FSSpec srcFileSpec, dstFileSpec, dstDirSpec, tmpFileSpec;
Str31 tmpName;
- err = FSpLocationFromPath(strlen(src), src, &srcFileSpec);
+ err = FSpLLocationFromPath(strlen(src), src, &srcFileSpec);
if (err == noErr) {
err = GetFileSpecs(dst, &dstFileSpec, &dstDirSpec, &dstExists,
&dstIsDirectory);
@@ -514,7 +514,7 @@ DoDeleteFile(
Boolean isDirectory;
long dirID;
- err = FSpLocationFromPath(strlen(path), path, &fileSpec);
+ err = FSpLLocationFromPath(strlen(path), path, &fileSpec);
if (err == noErr) {
/*
* Since FSpDeleteCompat will delete an empty directory, make sure
@@ -1166,7 +1166,7 @@ GetFileFinderAttributes(
CONST char *native;
native=Tcl_FSGetNativePath(fileName);
- err = FSpLocationFromPath(strlen(native),
+ err = FSpLLocationFromPath(strlen(native),
native, &fileSpec);
if (err == noErr) {
@@ -1244,7 +1244,7 @@ GetFileReadOnly(
CONST char *native;
native=Tcl_FSGetNativePath(fileName);
- err = FSpLocationFromPath(strlen(native),
+ err = FSpLLocationFromPath(strlen(native),
native, &fileSpec);
if (err == noErr) {
@@ -1308,7 +1308,7 @@ SetFileFinderAttributes(
CONST char *native;
native=Tcl_FSGetNativePath(fileName);
- err = FSpLocationFromPath(strlen(native),
+ err = FSpLLocationFromPath(strlen(native),
native, &fileSpec);
if (err == noErr) {
@@ -1400,7 +1400,7 @@ SetFileReadOnly(
CONST char *native;
native=Tcl_FSGetNativePath(fileName);
- err = FSpLocationFromPath(strlen(native),
+ err = FSpLLocationFromPath(strlen(native),
native, &fileSpec);
if (err == noErr) {
@@ -1543,8 +1543,8 @@ TclpObjNormalizePath(interp, pathPtr, nextCheckpoint)
short vRefNum;
long dirID;
Boolean isDirectory;
- Boolean wasAlias;
- FSSpec fileSpec;
+ Boolean wasAlias=FALSE;
+ FSSpec fileSpec, lastFileSpec;
Tcl_DString nativeds;
@@ -1570,14 +1570,19 @@ TclpObjNormalizePath(interp, pathPtr, nextCheckpoint)
nextCheckpoint++; cur = path[nextCheckpoint];
}
Tcl_UtfToExternalDString(NULL,path,nextCheckpoint,&nativeds);
- err = FSpLocationFromPath(Tcl_DStringLength(&nativeds),
+ err = FSpLLocationFromPath(Tcl_DStringLength(&nativeds),
Tcl_DStringValue(&nativeds),
&fileSpec);
Tcl_DStringFree(&nativeds);
if (err == noErr) {
+ lastFileSpec=fileSpec;
+ err = ResolveAliasFile(&fileSpec, true, &isDirectory,
+ &wasAlias);
+ if (err == noErr) {
err = FSpGetDirectoryID(&fileSpec, &dirID, &isDirectory);
currDirValid = ((err == noErr) && isDirectory);
vRefNum = fileSpec.vRefNum;
+ }
}
break;
}
@@ -1651,6 +1656,7 @@ TclpObjNormalizePath(interp, pathPtr, nextCheckpoint)
break; /* arrived at nonexistent file or dir */
} else {
/* fileSpec could point to an alias, resolve it */
+ lastFileSpec=fileSpec;
err = ResolveAliasFile(&fileSpec, true, &isDirectory,
&wasAlias);
if (err != noErr || !isDirectory) {
@@ -1669,9 +1675,13 @@ TclpObjNormalizePath(interp, pathPtr, nextCheckpoint)
/* found a new valid subdir in path, continue processing path */
lastCheckpoint=nextCheckpoint+1;
}
+ wasAlias=FALSE;
nextCheckpoint++;
}
+ if (wasAlias)
+ fileSpec=lastFileSpec;
+
/*
* fileSpec now points to a possibly nonexisting file or dir
* inside a valid dir; get full path name to it
diff --git a/mac/tclMacFile.c b/mac/tclMacFile.c
index 243127c..01c2678 100644
--- a/mac/tclMacFile.c
+++ b/mac/tclMacFile.c
@@ -10,7 +10,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclMacFile.c,v 1.19 2002/04/08 09:02:43 das Exp $
+ * RCS: @(#) $Id: tclMacFile.c,v 1.20 2002/04/19 14:18:50 das Exp $
*/
/*
@@ -35,6 +35,8 @@ static int NativeMatchType(Tcl_Obj *tempName, Tcl_GlobTypeData *types,
HFileInfo fileInfo, OSType okType, OSType okCreator);
static OSErr FspLocationFromFsPath _ANSI_ARGS_((Tcl_Obj *pathPtr,
FSSpec* specPtr));
+static OSErr FspLLocationFromFsPath _ANSI_ARGS_((Tcl_Obj *pathPtr,
+ FSSpec* specPtr));
static OSErr
FspLocationFromFsPath(pathPtr, specPtr)
@@ -45,6 +47,15 @@ FspLocationFromFsPath(pathPtr, specPtr)
return FSpLocationFromPath(strlen(native), native, specPtr);
}
+static OSErr
+FspLLocationFromFsPath(pathPtr, specPtr)
+ Tcl_Obj *pathPtr;
+ FSSpec* specPtr;
+{
+ CONST char *native = Tcl_FSGetNativePath(pathPtr);
+ return FSpLLocationFromPath(strlen(native), native, specPtr);
+}
+
/*
*----------------------------------------------------------------------
@@ -166,7 +177,7 @@ TclpMatchInDirectory(interp, resultPtr, pathPtr, pattern, types)
return TCL_OK;
}
- if (FspLocationFromFsPath(fileNamePtr, &fileSpec) == noErr) {
+ if (FspLLocationFromFsPath(fileNamePtr, &fileSpec) == noErr) {
paramBlock.hFileInfo.ioCompletion = NULL;
paramBlock.hFileInfo.ioNamePtr = fileSpec.name;
paramBlock.hFileInfo.ioVRefNum = fileSpec.vRefNum;
@@ -438,7 +449,7 @@ TclpObjAccess(pathPtr, mode)
long dirID;
int full_mode = 0;
- err = FspLocationFromFsPath(pathPtr, &fileSpec);
+ err = FspLLocationFromFsPath(pathPtr, &fileSpec);
if (err != noErr) {
errno = TclMacOSErrorToPosixError(err);
@@ -761,6 +772,10 @@ TclpReadlink(
return Tcl_DStringValue(linkPtr);
}
+
+static int
+TclpObjStatAlias _ANSI_ARGS_((Tcl_Obj *pathPtr, Tcl_StatBuf *bufPtr, Boolean resolveLink));
+
/*
*----------------------------------------------------------------------
@@ -783,8 +798,7 @@ TclpObjLstat(pathPtr, buf)
Tcl_Obj *pathPtr;
Tcl_StatBuf *buf;
{
- /* This needs to be enhanced to deal with aliases */
- return TclpObjStat(pathPtr, buf);
+ return TclpObjStatAlias(pathPtr, buf, FALSE);
}
/*
@@ -808,6 +822,13 @@ TclpObjStat(pathPtr, bufPtr)
Tcl_Obj *pathPtr;
Tcl_StatBuf *bufPtr;
{
+ return TclpObjStatAlias(pathPtr, bufPtr, TRUE);
+}
+
+
+static int
+TclpObjStatAlias (Tcl_Obj *pathPtr, Tcl_StatBuf *bufPtr, Boolean resolveLink)
+{
HFileInfo fpb;
HVolumeParam vpb;
OSErr err;
@@ -815,7 +836,10 @@ TclpObjStat(pathPtr, bufPtr)
Boolean isDirectory;
long dirID;
- err = FspLocationFromFsPath(pathPtr, &fileSpec);
+ if (resolveLink)
+ err = FspLocationFromFsPath(pathPtr, &fileSpec);
+ else
+ err = FspLLocationFromFsPath(pathPtr, &fileSpec);
if (err != noErr) {
errno = TclMacOSErrorToPosixError(err);
diff --git a/mac/tclMacUtil.c b/mac/tclMacUtil.c
index c505c64..a67eeef 100644
--- a/mac/tclMacUtil.c
+++ b/mac/tclMacUtil.c
@@ -10,7 +10,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclMacUtil.c,v 1.5 2001/11/23 01:28:49 das Exp $
+ * RCS: @(#) $Id: tclMacUtil.c,v 1.6 2002/04/19 14:18:55 das Exp $
*/
#include "tcl.h"
@@ -178,6 +178,10 @@ FSpFindFolder(
err = FSMakeFSSpecCompat(foundVRefNum, foundDirID, "\p", spec);
return err;
}
+
+static int
+FSpLocationFromPathAlias _ANSI_ARGS_((int length, CONST char *path,
+ FSSpecPtr fileSpecPtr, Boolean resolveLink));
/*
*----------------------------------------------------------------------
@@ -204,13 +208,52 @@ FSpLocationFromPath(
CONST char *path, /* The path to convert. */
FSSpecPtr fileSpecPtr) /* On return the spec for the path. */
{
+ return FSpLocationFromPathAlias(length, path, fileSpecPtr, TRUE);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FSpLLocationFromPath --
+ *
+ * This function obtains an FSSpec for a given macintosh path.
+ * Unlike the More Files function FSpLocationFromFullPath, this
+ * function will also accept partial paths and resolve any aliases
+ * along the path expect for the last path component.
+ *
+ * Results:
+ * OSErr code.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+FSpLLocationFromPath(
+ int length, /* Length of path. */
+ CONST char *path, /* The path to convert. */
+ FSSpecPtr fileSpecPtr) /* On return the spec for the path. */
+{
+ return FSpLocationFromPathAlias(length, path, fileSpecPtr, FALSE);
+}
+
+static int
+FSpLocationFromPathAlias(
+ int length, /* Length of path. */
+ CONST char *path, /* The path to convert. */
+ FSSpecPtr fileSpecPtr, /* On return the spec for the path. */
+ Boolean resolveLink) /* Resolve the last path component? */
+{
Str255 fileName;
OSErr err;
short vRefNum;
long dirID;
int pos, cur;
Boolean isDirectory;
- Boolean wasAlias;
+ Boolean wasAlias=FALSE;
+ FSSpec lastFileSpec;
/*
* Check to see if this is a full path. If partial
@@ -277,6 +320,7 @@ FSpLocationFromPath(
}
err = FSMakeFSSpecCompat(vRefNum, dirID, fileName, fileSpecPtr);
if (err != noErr) return err;
+ lastFileSpec=*fileSpecPtr;
err = ResolveAliasFile(fileSpecPtr, true, &isDirectory, &wasAlias);
if (err != noErr) return err;
FSpGetDirectoryID(fileSpecPtr, &dirID, &isDirectory);
@@ -287,6 +331,9 @@ FSpLocationFromPath(
}
}
+ if(!resolveLink && wasAlias)
+ *fileSpecPtr=lastFileSpec;
+
return noErr;
}