diff options
author | das <das> | 2002-04-19 14:18:33 (GMT) |
---|---|---|
committer | das <das> | 2002-04-19 14:18:33 (GMT) |
commit | 26bb2b5da7f034e47d6544e3d84e54c861f61206 (patch) | |
tree | 323d0314781d4b46fbb081c3751bb12a9e56feb8 /mac | |
parent | d2af1305c613b7c578a4b5be8e1ff487917b4237 (diff) | |
download | tcl-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)
Diffstat (limited to 'mac')
-rw-r--r-- | mac/tclMacFCmd.c | 32 | ||||
-rw-r--r-- | mac/tclMacFile.c | 36 | ||||
-rw-r--r-- | mac/tclMacUtil.c | 51 |
3 files changed, 100 insertions, 19 deletions
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; } |