summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog14
-rw-r--r--generic/tclIOUtil.c14
-rw-r--r--mac/tclMacChan.c33
-rw-r--r--mac/tclMacFile.c84
-rw-r--r--mac/tclMacPort.h6
-rw-r--r--mac/tclMacUtil.c8
6 files changed, 125 insertions, 34 deletions
diff --git a/ChangeLog b/ChangeLog
index 11c0585..ea92d8f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,20 @@
*** 8.4.2 TAGGED FOR RELEASE ***
+2003-03-03 Daniel Steffen <das@users.sourceforge.net>
+
+ Mac OS Classic specific fixes:
+ * generic/tclIOUtil.c (TclNewFSPathObj): on TCL_PLATFORM_MAC,
+ skip potential directory separator at the beginning of addStrRep.
+ * mac/tclMacChan.c (OpenFileChannel, CommonWatch): followup
+ fixes to cut and splice implementation for file channels.
+ * mac/tclMacFile.c (TclpUtime): pass native path to utime().
+ * mac/tclMacFile.c (TclpObjLink): correctly implemented creation
+ of alias files via new static proc CreateAliasFile().
+ * mac/tclMacPort.h: define S_ISLNK macro to fix stat'ing of links.
+ * mac/tclMacUtil.c (FSpLocationFromPathAlias): fix to enable
+ stat'ing of broken links.
+
2003-03-03 Kevin Kenny <kennykb@users.sourceforge.net>
* win/Makefile.vc: corrected bug introduced by 'g' for debug builds.
diff --git a/generic/tclIOUtil.c b/generic/tclIOUtil.c
index 43c9f5a..29ba700 100644
--- a/generic/tclIOUtil.c
+++ b/generic/tclIOUtil.c
@@ -17,7 +17,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclIOUtil.c,v 1.76 2003/02/27 23:47:16 hobbs Exp $
+ * RCS: @(#) $Id: tclIOUtil.c,v 1.77 2003/03/03 20:22:41 das Exp $
*/
#include "tclInt.h"
@@ -4020,6 +4020,18 @@ TclNewFSPathObj(Tcl_Obj *dirPtr, CONST char *addStrRep, int len)
objPtr = Tcl_NewObj();
fsPathPtr = (FsPath*)ckalloc((unsigned)sizeof(FsPath));
+ if (tclPlatform == TCL_PLATFORM_MAC) {
+ /*
+ * Mac relative paths may begin with a directory separator ':'.
+ * If present, we need to skip this ':' because we assume that
+ * we can join dirPtr and addStrRep by concatenating them as
+ * strings (and we ensure that dirPtr is terminated by a ':').
+ */
+ if (addStrRep[0] == ':') {
+ addStrRep++;
+ len--;
+ }
+ }
/* Setup the path */
fsPathPtr->translatedPathPtr = NULL;
fsPathPtr->normPathPtr = Tcl_NewStringObj(addStrRep, len);
diff --git a/mac/tclMacChan.c b/mac/tclMacChan.c
index 414309e..555e333 100644
--- a/mac/tclMacChan.c
+++ b/mac/tclMacChan.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: tclMacChan.c,v 1.20 2003/02/21 20:11:35 das Exp $
+ * RCS: @(#) $Id: tclMacChan.c,v 1.21 2003/03/03 20:22:42 das Exp $
*/
#include "tclInt.h"
@@ -801,7 +801,10 @@ OpenFileChannel(
short fileRef;
FileState *fileState;
char channelName[16 + TCL_INTEGER_SPACE];
+ ThreadSpecificData *tsdPtr;
+ tsdPtr = FileInit();
+
/*
* Note we use fsRdWrShPerm instead of fsRdWrPerm which allows shared
* writes on a file. This isn't common on a mac but is common with
@@ -874,6 +877,8 @@ OpenFileChannel(
}
fileState->fileChan = chan;
+ fileState->nextPtr = tsdPtr->firstFilePtr;
+ tsdPtr->firstFilePtr = fileState;
fileState->volumeRef = fileSpec.vRefNum;
fileState->fileRef = fileRef;
fileState->pending = 0;
@@ -1195,34 +1200,12 @@ CommonWatch(
* combination of TCL_READABLE,
* TCL_WRITABLE and TCL_EXCEPTION. */
{
- FileState **nextPtrPtr, *ptr;
FileState *infoPtr = (FileState *) instanceData;
- int oldMask = infoPtr->watchMask;
- ThreadSpecificData *tsdPtr;
-
- tsdPtr = FileInit();
+ Tcl_Time blockTime = { 0, 0 };
infoPtr->watchMask = mask;
if (infoPtr->watchMask) {
- if (!oldMask) {
- infoPtr->nextPtr = tsdPtr->firstFilePtr;
- tsdPtr->firstFilePtr = infoPtr;
- }
- } else {
- if (oldMask) {
- /*
- * Remove the file from the list of watched files.
- */
-
- for (nextPtrPtr = &(tsdPtr->firstFilePtr), ptr = *nextPtrPtr;
- ptr != NULL;
- nextPtrPtr = &ptr->nextPtr, ptr = *nextPtrPtr) {
- if (infoPtr == ptr) {
- *nextPtrPtr = ptr->nextPtr;
- break;
- }
- }
- }
+ Tcl_SetMaxBlockTime(&blockTime);
}
}
diff --git a/mac/tclMacFile.c b/mac/tclMacFile.c
index c20d056..0311ecd 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.26 2003/01/09 10:38:29 vincentdarley Exp $
+ * RCS: @(#) $Id: tclMacFile.c,v 1.27 2003/03/03 20:22:43 das Exp $
*/
/*
@@ -23,6 +23,8 @@
#include "tclPort.h"
#include "tclMacInt.h"
#include <Aliases.h>
+#include <Resources.h>
+#include <Files.h>
#include <Errors.h>
#include <Processes.h>
#include <Strings.h>
@@ -38,6 +40,8 @@ static OSErr FspLocationFromFsPath _ANSI_ARGS_((Tcl_Obj *pathPtr,
static OSErr FspLLocationFromFsPath _ANSI_ARGS_((Tcl_Obj *pathPtr,
FSSpec* specPtr));
+static OSErr CreateAliasFile _ANSI_ARGS_((FSSpec *theAliasFile, FSSpec *targetFile));
+
static OSErr
FspLocationFromFsPath(pathPtr, specPtr)
Tcl_Obj *pathPtr;
@@ -1173,7 +1177,6 @@ TclpObjLink(pathPtr, toPtr, linkAction)
FSSpec linkSpec;
OSErr err;
CONST char *path;
- AliasHandle alias;
err = FspLocationFromFsPath(toPtr, &spec);
if (err != noErr) {
@@ -1186,7 +1189,7 @@ TclpObjLink(pathPtr, toPtr, linkAction)
if (err == noErr) {
err = dupFNErr; /* EEXIST. */
} else {
- err = NewAlias(&spec, &linkSpec, &alias);
+ err = CreateAliasFile(&linkSpec, &spec);
}
if (err != noErr) {
errno = TclMacOSErrorToPosixError(err);
@@ -1265,7 +1268,78 @@ TclpUtime(pathPtr, tval)
struct utimbuf local_tval;
local_tval.actime=tval->actime+gmt_offset;
local_tval.modtime=tval->modtime+gmt_offset;
- return utime(Tcl_GetString(Tcl_FSGetNormalizedPath(NULL,pathPtr)),
+ return utime(Tcl_FSGetNativePath(Tcl_FSGetNormalizedPath(NULL,pathPtr)),
&local_tval);
}
-
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * CreateAliasFile --
+ *
+ * Creates an alias file located at aliasDest referring to the targetFile.
+ *
+ * Results:
+ * 0 on success, OS error code on error.
+ *
+ * Side effects:
+ * None.
+ *
+ *---------------------------------------------------------------------------
+ */
+static OSErr
+CreateAliasFile(FSSpec *theAliasFile, FSSpec *targetFile)
+{
+ CInfoPBRec cat;
+ FInfo fndrInfo;
+ AliasHandle theAlias;
+ short saveRef, rsrc = -1;
+ OSErr err;
+
+ saveRef = CurResFile();
+ /* set up the Finder information record for the alias file */
+ cat.dirInfo.ioNamePtr = targetFile->name;
+ cat.dirInfo.ioVRefNum = targetFile->vRefNum;
+ cat.dirInfo.ioFDirIndex = 0;
+ cat.dirInfo.ioDrDirID = targetFile->parID;
+ err = PBGetCatInfoSync(&cat);
+ if (err != noErr) goto bail;
+ if ((cat.dirInfo.ioFlAttrib & 16) == 0) {
+ /* file alias */
+ switch (cat.hFileInfo.ioFlFndrInfo.fdType) {
+ case 'APPL': fndrInfo.fdType = kApplicationAliasType; break;
+ case 'APPC': fndrInfo.fdType = kApplicationCPAliasType; break;
+ case 'APPD': fndrInfo.fdType = kApplicationDAAliasType; break;
+ default: fndrInfo.fdType = cat.hFileInfo.ioFlFndrInfo.fdType; break;
+ }
+ fndrInfo.fdCreator = cat.hFileInfo.ioFlFndrInfo.fdCreator;
+ } else {
+ /* folder alias */
+ fndrInfo.fdType = kContainerFolderAliasType;
+ fndrInfo.fdCreator = 'MACS';
+ }
+ fndrInfo.fdFlags = kIsAlias;
+ fndrInfo.fdLocation.v = 0;
+ fndrInfo.fdLocation.h = 0;
+ fndrInfo.fdFldr = 0;
+ /* create new file and set the file information */
+ FSpCreateResFile( theAliasFile, fndrInfo.fdCreator, fndrInfo.fdType, smSystemScript);
+ if ((err = ResError()) != noErr) goto bail;
+ err = FSpSetFInfo( theAliasFile, &fndrInfo);
+ if (err != noErr) goto bail;
+ /* save the alias resource */
+ rsrc = FSpOpenResFile(theAliasFile, fsRdWrPerm);
+ if (rsrc == -1) { err = ResError(); goto bail; }
+ UseResFile(rsrc);
+ err = NewAlias(theAliasFile, targetFile, &theAlias);
+ if (err != noErr) goto bail;
+ AddResource((Handle) theAlias, rAliasType, 0, theAliasFile->name);
+ if ((err = ResError()) != noErr) goto bail;
+ CloseResFile(rsrc);
+ rsrc = -1;
+ /* done */
+ bail:
+ if (rsrc != -1) CloseResFile(rsrc);
+ UseResFile(saveRef);
+ return err;
+}
diff --git a/mac/tclMacPort.h b/mac/tclMacPort.h
index a868733..482f6e8 100644
--- a/mac/tclMacPort.h
+++ b/mac/tclMacPort.h
@@ -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: tclMacPort.h,v 1.16 2002/10/09 11:54:34 das Exp $
+ * RCS: @(#) $Id: tclMacPort.h,v 1.17 2003/03/03 20:22:44 das Exp $
*/
@@ -77,6 +77,10 @@
#endif /* __MWERKS__ */
+#if defined(S_IFBLK) && !defined(S_ISLNK)
+#define S_ISLNK(m) (((m)&(S_IFMT)) == (S_IFLNK))
+#endif
+
/*
* Many signals are not supported on the Mac and are thus not defined in
* <signal.h>. They are defined here so that Tcl will compile with less
diff --git a/mac/tclMacUtil.c b/mac/tclMacUtil.c
index a67eeef..ab65815 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.6 2002/04/19 14:18:55 das Exp $
+ * RCS: @(#) $Id: tclMacUtil.c,v 1.7 2003/03/03 20:22:44 das Exp $
*/
#include "tcl.h"
@@ -322,7 +322,11 @@ FSpLocationFromPathAlias(
if (err != noErr) return err;
lastFileSpec=*fileSpecPtr;
err = ResolveAliasFile(fileSpecPtr, true, &isDirectory, &wasAlias);
- if (err != noErr) return err;
+ if (err != noErr) {
+ /* ignore alias resolve errors on last path component */
+ if (pos < length) return err;
+ else *fileSpecPtr=lastFileSpec;
+ }
FSpGetDirectoryID(fileSpecPtr, &dirID, &isDirectory);
vRefNum = fileSpecPtr->vRefNum;
cur = pos;