summaryrefslogtreecommitdiffstats
path: root/macosx/tclMacOSXFCmd.c
diff options
context:
space:
mode:
Diffstat (limited to 'macosx/tclMacOSXFCmd.c')
-rw-r--r--macosx/tclMacOSXFCmd.c120
1 files changed, 79 insertions, 41 deletions
diff --git a/macosx/tclMacOSXFCmd.c b/macosx/tclMacOSXFCmd.c
index aab5b44..17cccc2 100644
--- a/macosx/tclMacOSXFCmd.c
+++ b/macosx/tclMacOSXFCmd.c
@@ -5,11 +5,12 @@
* subcommands of the "file" command.
*
* Copyright (c) 2003 Tcl Core Team.
+ * Copyright (c) 2003-2005 Daniel A. Steffen <das@users.sourceforge.net>
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclMacOSXFCmd.c,v 1.5 2005/11/04 00:06:49 dkf Exp $
+ * RCS: @(#) $Id: tclMacOSXFCmd.c,v 1.6 2005/11/27 02:33:49 das Exp $
*/
#include "tclInt.h"
@@ -19,6 +20,20 @@
#include <sys/paths.h>
#endif
+/* Darwin 8 copyfile API */
+#ifdef HAVE_COPYFILE
+#ifdef HAVE_COPYFILE_H
+#include <copyfile.h>
+#else
+int copyfile(const char *from, const char *to, void *state, uint32_t flags);
+#define COPYFILE_ACL (1<<0)
+#define COPYFILE_XATTR (1<<2)
+#define COPYFILE_NOFOLLOW_SRC (1<<18)
+#endif
+#endif
+
+#include <libkern/OSByteOrder.h>
+
/*
* Constants for file attributes subcommand. Need to be kept in sync with
* tclUnixFCmd.c !
@@ -46,21 +61,23 @@ static int Tcl_GetOSTypeFromObj(Tcl_Interp *interp,
static Tcl_Obj * Tcl_NewOSTypeStringObj(CONST OSType newOSType);
enum {
- kFinfoIsInvisible = 0x4000,
+ kIsInvisible = 0x4000,
};
+#define kFinfoIsInvisible (OSSwapHostToBigConstInt16(kIsInvisible))
+
+typedef struct finderinfo {
+ u_int32_t type;
+ u_int32_t creator;
+ u_int16_t fdFlags;
+ u_int32_t location;
+ u_int16_t reserved;
+ u_int32_t extendedFileInfo[4];
+} __attribute__ ((__packed__)) finderinfo;
+
typedef struct fileinfobuf {
u_int32_t info_length;
- union {
- struct {
- u_int32_t type;
- u_int32_t creator;
- u_int16_t fdFlags;
- u_int16_t location;
- u_int32_t padding[4];
- } finder;
- off_t rsrcForkSize;
- } data __attribute__ ((packed));
+ u_int32_t data[8];
} fileinfobuf;
/*
@@ -93,6 +110,8 @@ TclMacOSXGetFileAttribute(
Tcl_StatBuf statBuf;
struct attrlist alist;
fileinfobuf finfo;
+ finderinfo *finder = (finderinfo*)(&finfo.data);
+ off_t *rsrcForkSize = (off_t*)(&finfo.data);
CONST char *native;
result = TclpObjStat(fileName, &statBuf);
@@ -114,7 +133,7 @@ TclMacOSXGetFileAttribute(
return TCL_ERROR;
}
- memset(&alist, 0, sizeof(struct attrlist));
+ bzero(&alist, sizeof(struct attrlist));
alist.bitmapcount = ATTR_BIT_MAP_COUNT;
if (objIndex == MACOSX_RSRCLENGTH_ATTRIBUTE) {
alist.fileattr = ATTR_FILE_RSRCLENGTH;
@@ -132,17 +151,19 @@ TclMacOSXGetFileAttribute(
switch (objIndex) {
case MACOSX_CREATOR_ATTRIBUTE:
- *attributePtrPtr = Tcl_NewOSTypeStringObj(finfo.data.finder.creator);
+ *attributePtrPtr = Tcl_NewOSTypeStringObj(
+ OSSwapBigToHostInt32(finder->creator));
break;
case MACOSX_TYPE_ATTRIBUTE:
- *attributePtrPtr = Tcl_NewOSTypeStringObj(finfo.data.finder.type);
+ *attributePtrPtr = Tcl_NewOSTypeStringObj(
+ OSSwapBigToHostInt32(finder->type));
break;
case MACOSX_HIDDEN_ATTRIBUTE:
*attributePtrPtr = Tcl_NewBooleanObj(
- (finfo.data.finder.fdFlags & kFinfoIsInvisible) != 0);
+ (finder->fdFlags & kFinfoIsInvisible) != 0);
break;
case MACOSX_RSRCLENGTH_ATTRIBUTE:
- *attributePtrPtr = Tcl_NewWideIntObj(finfo.data.rsrcForkSize);
+ *attributePtrPtr = Tcl_NewWideIntObj(*rsrcForkSize);
break;
}
return TCL_OK;
@@ -181,6 +202,8 @@ TclMacOSXSetFileAttribute(
Tcl_StatBuf statBuf;
struct attrlist alist;
fileinfobuf finfo;
+ finderinfo *finder = (finderinfo*)(&finfo.data);
+ off_t *rsrcForkSize = (off_t*)(&finfo.data);
CONST char *native;
result = TclpObjStat(fileName, &statBuf);
@@ -202,7 +225,7 @@ TclMacOSXSetFileAttribute(
return TCL_ERROR;
}
- memset(&alist, 0, sizeof(struct attrlist));
+ bzero(&alist, sizeof(struct attrlist));
alist.bitmapcount = ATTR_BIT_MAP_COUNT;
if (objIndex == MACOSX_RSRCLENGTH_ATTRIBUTE) {
alist.fileattr = ATTR_FILE_RSRCLENGTH;
@@ -219,33 +242,33 @@ TclMacOSXSetFileAttribute(
}
if (objIndex != MACOSX_RSRCLENGTH_ATTRIBUTE) {
+ OSType t;
+ int h;
+
switch (objIndex) {
case MACOSX_CREATOR_ATTRIBUTE:
- if (Tcl_GetOSTypeFromObj(interp, attributePtr,
- &finfo.data.finder.creator) != TCL_OK) {
+ if (Tcl_GetOSTypeFromObj(interp, attributePtr, &t) != TCL_OK) {
return TCL_ERROR;
}
+ finder->creator = OSSwapHostToBigInt32(t);
break;
case MACOSX_TYPE_ATTRIBUTE:
- if (Tcl_GetOSTypeFromObj(interp, attributePtr,
- &finfo.data.finder.type) != TCL_OK) {
+ if (Tcl_GetOSTypeFromObj(interp, attributePtr, &t) != TCL_OK) {
return TCL_ERROR;
}
+ finder->type = OSSwapHostToBigInt32(t);
break;
- case MACOSX_HIDDEN_ATTRIBUTE: {
- int hidden;
-
- if (Tcl_GetBooleanFromObj(interp,attributePtr,&hidden) != TCL_OK) {
+ case MACOSX_HIDDEN_ATTRIBUTE:
+ if (Tcl_GetBooleanFromObj(interp, attributePtr, &h) != TCL_OK) {
return TCL_ERROR;
}
- if (hidden) {
- finfo.data.finder.fdFlags |= kFinfoIsInvisible;
+ if (h) {
+ finder->fdFlags |= kFinfoIsInvisible;
} else {
- finfo.data.finder.fdFlags &= ~kFinfoIsInvisible;
+ finder->fdFlags &= ~kFinfoIsInvisible;
}
break;
}
- }
result = setattrlist(native, &alist,
&finfo.data, sizeof(finfo.data), 0);
@@ -257,14 +280,14 @@ TclMacOSXSetFileAttribute(
return TCL_ERROR;
}
} else {
- off_t newRsrcForkSize;
+ Tcl_WideInt newRsrcForkSize;
if (Tcl_GetWideIntFromObj(interp, attributePtr,
&newRsrcForkSize) != TCL_OK) {
return TCL_ERROR;
}
- if (newRsrcForkSize != finfo.data.rsrcForkSize) {
+ if (newRsrcForkSize != *rsrcForkSize) {
Tcl_DString ds;
/*
@@ -331,11 +354,19 @@ TclMacOSXCopyFileAttributes(
CONST Tcl_StatBuf *statBufPtr)
/* Stat info for source file */
{
-#ifdef HAVE_GETATTRLIST
+#if defined(HAVE_COPYFILE)
+ if (copyfile(src, dst, NULL, COPYFILE_XATTR |
+ (S_ISLNK(statBufPtr->st_mode) ? COPYFILE_NOFOLLOW_SRC :
+ COPYFILE_ACL)) < 0) {
+ return TCL_ERROR;
+ }
+ return TCL_OK;
+#elif defined(HAVE_GETATTRLIST)
struct attrlist alist;
fileinfobuf finfo;
+ off_t *rsrcForkSize = (off_t*)(&finfo.data);
- memset(&alist, 0, sizeof(struct attrlist));
+ bzero(&alist, sizeof(struct attrlist));
alist.bitmapcount = ATTR_BIT_MAP_COUNT;
alist.commonattr = ATTR_CMN_FNDRINFO;
@@ -359,7 +390,7 @@ TclMacOSXCopyFileAttributes(
return TCL_ERROR;
}
- if(finfo.data.rsrcForkSize > 0) {
+ if(*rsrcForkSize > 0) {
int result;
Tcl_DString ds_src, ds_dst;
@@ -422,14 +453,18 @@ Tcl_GetOSTypeFromObj(
string = Tcl_GetStringFromObj(objPtr, &length);
Tcl_UtfToExternalDString(encoding, string, length, &ds);
- if (Tcl_DStringLength(&ds) > sizeof(OSType)) {
+ if (Tcl_DStringLength(&ds) > 4) {
Tcl_AppendResult(interp, "expected Macintosh OS type but got \"",
string, "\": ", NULL);
result = TCL_ERROR;
} else {
- memset(osTypePtr, 0, sizeof(OSType));
- memcpy(osTypePtr, Tcl_DStringValue(&ds),
+ char string[4] = {'\0','\0','\0','\0'};
+ memcpy(string, Tcl_DStringValue(&ds),
(size_t) Tcl_DStringLength(&ds));
+ *osTypePtr = (OSType) string[0] << 24 |
+ (OSType) string[1] << 16 |
+ (OSType) string[2] << 8 |
+ (OSType) string[3];
}
Tcl_DStringFree(&ds);
Tcl_FreeEncoding(encoding);
@@ -456,13 +491,16 @@ static Tcl_Obj *
Tcl_NewOSTypeStringObj(
CONST OSType newOSType) /* OSType used to initialize the new object. */
{
- char string[sizeof(OSType)+1];
+ char string[5];
Tcl_Obj *resultPtr;
Tcl_DString ds;
Tcl_Encoding encoding = Tcl_GetEncoding(NULL, "macRoman");
- memcpy(string, &newOSType, sizeof(OSType));
- string[sizeof(OSType)] = '\0';
+ string[0] = (char) (newOSType >> 24);
+ string[1] = (char) (newOSType >> 16);
+ string[2] = (char) (newOSType >> 8);
+ string[3] = (char) (newOSType);
+ string[4] = '\0';
Tcl_ExternalToUtfDString(encoding, string, -1, &ds);
resultPtr = Tcl_NewStringObj(Tcl_DStringValue(&ds),
Tcl_DStringLength(&ds));