TIP: 118
Title: Enhance [file attributes] and [file copy] on Mac OS X & BSD
Version: $Revision: 1.7 $
Author: Daniel A. Steffen <[email protected]>
State: Final
Type: Project
Vote: Done
Created: 01-Nov-2002
Post-History:
Tcl-Version: 8.5
~ Abstract
This TIP proposes a set of changes to ''[file attributes]'' and
''[file copy]'' to make them function better on MacOS X and other
BSD-Unix systems.
~ Summary of Proposed Changes
This TIP proposes five sets of changes to ''[file attributes]'' and
''[file copy]'':
1. Add support for the Macintosh and Windows specific flag ''[file
attributes -readonly]'' to Unixes that support the ''chflags()''
API, to allow the ''user immutable'' flag to be accessed &
modified from Tcl.
2. Add support for the Macintosh specific flags ''[file attributes
-readonly -creator -type -hidden]'' to Mac OS X via the POSIX
level API ''getattrlist()''.
3. Add a new flag ''[file attributes -rsrclength]'' to Mac OS X and
Mac OS 9 that gives the length of the resource fork of a file; 0
is the only value that this attribute can be set to, which strips
the resource fork off a file.
4. Change ''[file attributes]'' to 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.
5. Enhance ''[file copy]'' on Mac OS X (more precisely, the native
file-system ''Tcl_FSCopyFile'') to copy finder attributes (i.e.
''-readonly -creator -type -hidden'') and resource forks
transparently.
~ Rationale
There is currently no way to access and modify HFS file-system metadata
from Tcl on Mac OS X whereas Tcl on Mac OS 9 (or Classic) on the same
Macintosh has that capability. Worse, ''[file copy]'' (and
potentially even ''[file rename]'' if it results in a copy) on Mac OS
X can be a destructive operation at present if it operates on a file
that has essential data in its resource fork or its HFS metadata.
This again in contrast to the same operations in Tcl on Mac OS 9 where
this information is preserved. This TIP seeks to rectify these
asymmetries in order to better hide such file-system related platform
specificities from the scripter.
~ Details
Additional information & examples:
1. Unix versions that support ''chflags()'' include BSD >= 4.4 and
Darwin/Mac OS X (where ''user immutable'' is the flag
corresponding to the file locked state on the HFS file-system,
which is what ''[file attributes -readonly]'' controls on Mac OS
9).
2. The use of ''getattrlist()'' does not require linking with Carbon
and thus allows access to HFS file-system metadata from Tcl on pure
open-source Darwin systems (which is something no other scripting
language can claim at present).
3. The new attribute ''-rsrclength'' is useful to check whether a
file has a resource fork and to calculate total file size on Mac
OS 9 and X (note that ''[file size]'' returns the size of the data
fork only). Stripping a file's resource fork (by setting
''-rsrclength'' to 0) is a common operation on Mac OS when dealing
with files that are destined for other platforms. This is a
feature that has been requested several times and given that it
ties in well with the implementation of the other new attributes
it comes at essentially no additional cost.
|% file attributes test
|-group admin -owner steffen -permissions 00644 -readonly 0 -creator Doug -type RSRC -hidden 0 -rsrclength 314
|% file attributes test -rsrclength 5
|setting nonzero rsrclength not supported
|% file attributes test -rsrclength 0
|% file attributes test
|-group admin -owner steffen -permissions 00644 -readonly 0 -creator Doug -type RSRC -hidden 0 -rsrclength 0
4. On Mac OS X, trying to retrieve the new attributes ''-creator
-type -rsrclength'' fails on non-regular files & directories (and
on any file located on a non-HFS file-system that doesn't support
''getattrlist()''). Returning only the list of attributes that
are valid seems like much more sensible behaviour in this case
than failing with an error and not returning anything. In the
case where no valid attributes can be retrieved at all, the error
returned by the last attempt is passed upstream, to preserve
existing error handling. This proposed change in behaviour of
''[file attributes]'' seems necessary to allow the command to
continue to work in a consistent way on all inputs and on all
platforms; it should not impact existing code since for current
attributes, failure to retrieve any one attribute is equivalent to
failure to retrieve all attributes.
|% close [open test w]
|% file attributes test
|-group admin -owner steffen -permissions 00644 -readonly 0 -creator {} -type {} -hidden 0 -rsrclength 0
|% file delete test
|% file mkdir test
|% file attributes test
|-group admin -owner steffen -permissions 040755 -readonly 0 -hidden 0
|% file delete test
5. Unlike the Finder and other HFS aware tools on Mac OS X, Tcl
currently ignores HFS metadata and the resource fork, which will
undoubtedly surprise scripters unpleasantly. ''[file copy]''
should hide such platform specificities and copy a file in the
same way as the Finder:
|% file attributes test
|-group admin -owner steffen -permissions 00644 -readonly 0 -creator Doug -type RSRC -hidden 0 -rsrclength 314
|% file copy test test1
|% file attributes test1
|-group admin -owner steffen -permissions 00644 -readonly 0 -creator Doug -type RSRC -hidden 0 -rsrclength 314
|% file delete test1
~ Comments
Additional implementation details:
* To support the new attributes ''-creator -type'', routines to
convert from numerical OSTypes (''u_int32_t'') to the usual four
character human readable format have been adapted from
''mac/tclMacResource.c''; the new versions accept/return strings of
length 0-4 unlike the originals that only dealt with length 4.
This is important because creator/type 0 (i.e. ''-creator {} -type
{}'') is common on Mac OS X. The Mac OS 9 implementation of the
OSType string representation code has been modified accordingly by
adding support for strings of length 0-4 and missing
''UtfToExternal/ExternalToUtf'' conversions.
* ''macRoman'' is the encoding used for the string representation of
OSTypes, for consistency with Tcl on Mac OS 9 as well as with
common Mac OS X tools such as Resorcerer & SuperGetInfo that all
use ''macRoman'' to display creator/type codes; this encoding is
probably what most people would expect. It's unfortunate that this
means that use of ''[file attributes]'' on Darwin/Mac OS X will
cause the non-builtin ''macRoman'' encoding to load. ASCII-only
OSTypes will still work properly if ''macRoman'' is not available,
fallback to ''latin1'' in that case could also be added if deemed
necessary. However, the Tk Aqua port already relies on
''macRoman'' being present so in the most common usage pattern
''macRoman'' should be present and loaded anyway.
* The Mac OS 9 implementation of ''[file attributes -creator -type]''
currently returns the bogus 'Fldr' type & creator for directories,
this has been changed to return an error for consistency with the
Mac OS X implementation.
* Most of the implementation of the new Mac OS X specific features
has been added added at the end of ''unix/tclUnixFCmd.c'', it might
be cleaner to move this code to a separate file
''macosx/tclMacOSXFCmd.c'', but that would require several routines
in both ''unix/tclUnixFCmd.c'' and ''mac/tclMacOSXFCmd.c'' to be
made non-static. It's unclear whether this is an acceptable change
just for the sake of code separation/cleanliness.
~ Reference Implementation
SourceForge patch #626360
[[http://sourceforge.net/tracker/index.php?func=detail&aid=626360&group_id=10894&atid=310894]]
implements this TIP as a patch to the current HEAD.
The patch has been tested on the SF compile-farm on hosts:
[Alpha] Linux 2.4 (Debian 3.0): where ''chflags()'' and
''getattrlist()'' are not available and no ill effects ensue
(i.e. no new tests fail).
[x86] FreeBSD (4.7-RC): where ''chflags()'' is available and ''[file
attributes -readonly]'' can successfully be interrogated (but not
set due to permission issues at SourceForge). No new tests fail.
as well as on Mac OS 9, X 10.1.5 and X 10.2.1, where all the new
functionality is available and no new tests fail.
~ Copyright
This document has been placed in the public domain.