diff options
author | das <das> | 2003-05-14 19:21:20 (GMT) |
---|---|---|
committer | das <das> | 2003-05-14 19:21:20 (GMT) |
commit | e7e62365449aec7d4e02ab0a58d7b185a74342e8 (patch) | |
tree | 18a23b38b5ab18b3714c78cd1f0f131855938b1f /mac | |
parent | 12f7a06929318bdfae5af285f1502aa2f5d4aa86 (diff) | |
download | tcl-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.c | 81 | ||||
-rw-r--r-- | mac/tclMacResource.c | 26 |
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); } /* |