summaryrefslogtreecommitdiffstats
path: root/mac
diff options
context:
space:
mode:
authordas <das>2003-05-14 19:21:20 (GMT)
committerdas <das>2003-05-14 19:21:20 (GMT)
commite7e62365449aec7d4e02ab0a58d7b185a74342e8 (patch)
tree18a23b38b5ab18b3714c78cd1f0f131855938b1f /mac
parent12f7a06929318bdfae5af285f1502aa2f5d4aa86 (diff)
downloadtcl-e7e62365449aec7d4e02ab0a58d7b185a74342e8.zip
tcl-e7e62365449aec7d4e02ab0a58d7b185a74342e8.tar.gz
tcl-e7e62365449aec7d4e02ab0a58d7b185a74342e8.tar.bz2
Implementation of TIP 118:
* generic/tclFCmd.c (TclFileAttrsCmd): return the list of attributes that can be retrieved without error for a given file, instead of aborting the whole command when any error occurs. * unix/tclUnixFCmd.c: added support for new file attributes and for copying Mac OS X file attributes & resource fork during [file copy]. * generic/tclInt.decls: added declarations of new external commands needed by new file attributes support in tclUnixFCmd.c. * macosx/tclMacOSXFCmd.c (new): Mac OS X specific implementation of new file attributes and of attribute & resource fork copying. * mac/tclMacFCmd.c: added implementation of -rsrclength attribute & fixes to other attributes for consistency with OSX implementation. * mac/tclMacResource.c: fixes to OSType handling. * doc/file.n: documentation of [file attributes] changes. * unix/configure.in: check for APIs needed by new file attributes. * unix/Makefile.in: * unix/tcl.m4: added new platform specifc tclMacOSXFCmd.c source. * unix/configure: * generic/tclStubInit.c: * generic/tclIntPlatDecls.h: regen. * tools/genStubs.tcl: fixes to completely broken code trying to prevent overlap of "aqua", "macosx", "x11" and "unix" stub entries. * tests/unixFCmd.test: added tests of -readonly attribute. * tests/macOSXFCmd.test (new): tests of macosx file attributes and of preservation of attributes & resource fork during [file copy]. * tests/macFCmd.test: restore -readonly attribute of test dir, as otherwise its removal can fail on unices supporting -readonly.
Diffstat (limited to 'mac')
-rw-r--r--mac/tclMacFCmd.c81
-rw-r--r--mac/tclMacResource.c26
2 files changed, 94 insertions, 13 deletions
diff --git a/mac/tclMacFCmd.c b/mac/tclMacFCmd.c
index 58b81c2..a1307b4 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.19 2003/02/04 17:06:51 vincentdarley Exp $
+ * RCS: @(#) $Id: tclMacFCmd.c,v 1.20 2003/05/14 19:21:23 das Exp $
*/
#include "tclInt.h"
@@ -26,6 +26,7 @@
#include <string.h>
#include <Finder.h>
#include <Aliases.h>
+#include <Resources.h>
/*
* Callback for the file attributes code.
@@ -52,17 +53,19 @@ static int SetFileReadOnly _ANSI_ARGS_((Tcl_Interp *interp,
#define MAC_HIDDEN_ATTRIBUTE 1
#define MAC_READONLY_ATTRIBUTE 2
#define MAC_TYPE_ATTRIBUTE 3
+#define MAC_RSRCLENGTH_ATTRIBUTE 4
/*
* Global variables for the file attributes code.
*/
CONST char *tclpFileAttrStrings[] = {"-creator", "-hidden", "-readonly",
- "-type", (char *) NULL};
+ "-type", "-rsrclength", (char *) NULL};
CONST TclFileAttrProcs tclpFileAttrProcs[] = {
{GetFileFinderAttributes, SetFileFinderAttributes},
{GetFileFinderAttributes, SetFileFinderAttributes},
{GetFileReadOnly, SetFileReadOnly},
+ {GetFileFinderAttributes, SetFileFinderAttributes},
{GetFileFinderAttributes, SetFileFinderAttributes}};
/*
@@ -1102,6 +1105,7 @@ GetFileFinderAttributes(
OSErr err;
FSSpec fileSpec;
FInfo finfo;
+ CInfoPBRec pb;
CONST char *native;
native=Tcl_FSGetNativePath(fileName);
@@ -1109,7 +1113,16 @@ GetFileFinderAttributes(
native, &fileSpec);
if (err == noErr) {
- err = FSpGetFInfo(&fileSpec, &finfo);
+ if (objIndex != MAC_RSRCLENGTH_ATTRIBUTE) {
+ err = FSpGetFInfo(&fileSpec, &finfo);
+ } else {
+ pb.hFileInfo.ioCompletion = NULL;
+ pb.hFileInfo.ioNamePtr = fileSpec.name;
+ pb.hFileInfo.ioVRefNum = fileSpec.vRefNum;
+ pb.hFileInfo.ioFDirIndex = 0;
+ pb.hFileInfo.ioDirID = fileSpec.parID;
+ err = PBGetCatInfo(&pb, 0);
+ }
}
if (err == noErr) {
@@ -1124,6 +1137,9 @@ GetFileFinderAttributes(
case MAC_TYPE_ATTRIBUTE:
*attributePtrPtr = Tcl_NewOSTypeObj(finfo.fdType);
break;
+ case MAC_RSRCLENGTH_ATTRIBUTE:
+ *attributePtrPtr = Tcl_NewLongObj(pb.hFileInfo.ioFlRLgLen);
+ break;
}
} else if (err == fnfErr) {
long dirID;
@@ -1134,7 +1150,11 @@ GetFileFinderAttributes(
if (objIndex == MAC_HIDDEN_ATTRIBUTE) {
*attributePtrPtr = Tcl_NewBooleanObj(0);
} else {
- *attributePtrPtr = Tcl_NewOSTypeObj('Fldr');
+ /* Directories only support attribute "-hidden" */
+ errno = EISDIR;
+ Tcl_AppendResult(interp, "invalid attribute: ",
+ Tcl_PosixError(interp), (char *) NULL);
+ return TCL_ERROR;
}
}
}
@@ -1244,6 +1264,7 @@ SetFileFinderAttributes(
OSErr err;
FSSpec fileSpec;
FInfo finfo;
+ CInfoPBRec pb;
CONST char *native;
native=Tcl_FSGetNativePath(fileName);
@@ -1251,7 +1272,16 @@ SetFileFinderAttributes(
native, &fileSpec);
if (err == noErr) {
- err = FSpGetFInfo(&fileSpec, &finfo);
+ if (objIndex != MAC_RSRCLENGTH_ATTRIBUTE) {
+ err = FSpGetFInfo(&fileSpec, &finfo);
+ } else {
+ pb.hFileInfo.ioCompletion = NULL;
+ pb.hFileInfo.ioNamePtr = fileSpec.name;
+ pb.hFileInfo.ioVRefNum = fileSpec.vRefNum;
+ pb.hFileInfo.ioFDirIndex = 0;
+ pb.hFileInfo.ioDirID = fileSpec.parID;
+ err = PBGetCatInfo(&pb, 0);
+ }
}
if (err == noErr) {
@@ -1282,8 +1312,47 @@ SetFileFinderAttributes(
return TCL_ERROR;
}
break;
+ case MAC_RSRCLENGTH_ATTRIBUTE:
+ {
+ long newRsrcForkSize;
+
+ if (Tcl_GetLongFromObj(interp, attributePtr,
+ &newRsrcForkSize) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if(newRsrcForkSize != pb.hFileInfo.ioFlRLgLen) {
+ short rf;
+ /*
+ * Only setting rsrclength to 0 to strip
+ * a file's resource fork is supported.
+ */
+ if(newRsrcForkSize != 0) {
+ Tcl_AppendResult(interp,
+ "setting nonzero rsrclength not supported",
+ (char *) NULL);
+ return TCL_ERROR;
+ }
+
+ if ((rf = FSpOpenResFile(&fileSpec, fsWrPerm)) >= 0) {
+ err = SetEOF(rf, 0);
+ CloseResFile(rf);
+ }
+
+ if (err != noErr) {
+ errno = TclMacOSErrorToPosixError(err);
+ Tcl_AppendResult(interp,
+ "could not truncate resource fork of \"",
+ Tcl_GetString(fileName), "\": ",
+ Tcl_PosixError(interp), (char *) NULL);
+ return TCL_ERROR;
+ }
+ }
+ break;
+ }
+ }
+ if (objIndex != MAC_RSRCLENGTH_ATTRIBUTE) {
+ err = FSpSetFInfo(&fileSpec, &finfo);
}
- err = FSpSetFInfo(&fileSpec, &finfo);
} else if (err == fnfErr) {
long dirID;
Boolean isDirectory = 0;
diff --git a/mac/tclMacResource.c b/mac/tclMacResource.c
index 78f0bc5..49e1110 100644
--- a/mac/tclMacResource.c
+++ b/mac/tclMacResource.c
@@ -11,7 +11,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclMacResource.c,v 1.14 2002/06/05 11:59:49 das Exp $
+ * RCS: @(#) $Id: tclMacResource.c,v 1.15 2003/05/14 19:21:24 das Exp $
*/
#include <Errors.h>
@@ -1711,24 +1711,29 @@ SetOSTypeFromAny(
Tcl_ObjType *oldTypePtr = objPtr->typePtr;
char *string;
int length;
- long newOSType;
+ OSType newOSType = 0UL;
+ Tcl_DString ds;
/*
* Get the string representation. Make it up-to-date if necessary.
*/
string = Tcl_GetStringFromObj(objPtr, &length);
+ Tcl_UtfToExternalDString(NULL, string, length, &ds);
- if (length != 4) {
+ if (Tcl_DStringLength(&ds) > sizeof(OSType)) {
if (interp != NULL) {
Tcl_ResetResult(interp);
Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
"expected Macintosh OS type but got \"", string, "\"",
(char *) NULL);
}
+ Tcl_DStringFree(&ds);
return TCL_ERROR;
}
- newOSType = *((long *) string);
+ memcpy(&newOSType, Tcl_DStringValue(&ds),
+ (size_t) Tcl_DStringLength(&ds));
+ Tcl_DStringFree(&ds);
/*
* The conversion to resource type succeeded. Free the old internalRep
@@ -1767,9 +1772,16 @@ static void
UpdateStringOfOSType(
register Tcl_Obj *objPtr) /* Int object whose string rep to update. */
{
- objPtr->bytes = ckalloc(5);
- sprintf(objPtr->bytes, "%-4.4s", &(objPtr->internalRep.longValue));
- objPtr->length = 4;
+ char string[sizeof(OSType)+1];
+ Tcl_DString ds;
+
+ memcpy(string, &(objPtr->internalRep.longValue), sizeof(OSType));
+ string[sizeof(OSType)] = '\0';
+ Tcl_ExternalToUtfDString(NULL, string, -1, &ds);
+ objPtr->bytes = ckalloc(Tcl_DStringLength(&ds) + 1);
+ memcpy(objPtr->bytes, Tcl_DStringValue(&ds), Tcl_DStringLength(&ds) + 1);
+ objPtr->length = Tcl_DStringLength(&ds);
+ Tcl_DStringFree(&ds);
}
/*