summaryrefslogtreecommitdiffstats
path: root/macosx/tclMacOSXFCmd.c
diff options
context:
space:
mode:
Diffstat (limited to 'macosx/tclMacOSXFCmd.c')
-rw-r--r--macosx/tclMacOSXFCmd.c152
1 files changed, 79 insertions, 73 deletions
diff --git a/macosx/tclMacOSXFCmd.c b/macosx/tclMacOSXFCmd.c
index 7b80a9d..818b91d 100644
--- a/macosx/tclMacOSXFCmd.c
+++ b/macosx/tclMacOSXFCmd.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: tclMacOSXFCmd.c,v 1.18 2010/03/05 14:34:04 dkf Exp $
+ * RCS: @(#) $Id: tclMacOSXFCmd.c,v 1.19 2010/03/25 14:02:11 dkf Exp $
*/
#include "tclInt.h"
@@ -24,7 +24,7 @@
#ifdef HAVE_COPYFILE
#ifdef HAVE_COPYFILE_H
#include <copyfile.h>
-#if defined(HAVE_WEAK_IMPORT) && MAC_OS_X_VERSION_MIN_REQUIRED < 1040
+#if defined(HAVE_WEAK_IMPORT) && (MAC_OS_X_VERSION_MIN_REQUIRED < 1040)
/* Support for weakly importing copyfile. */
#define WEAK_IMPORT_COPYFILE
extern int copyfile(const char *from, const char *to,
@@ -34,10 +34,10 @@ extern int copyfile(const char *from, const char *to,
#else /* HAVE_COPYFILE_H */
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)
-#if defined(HAVE_WEAK_IMPORT) && MAC_OS_X_VERSION_MIN_REQUIRED < 1040
+#define COPYFILE_ACL (1<<0)
+#define COPYFILE_XATTR (1<<2)
+#define COPYFILE_NOFOLLOW_SRC (1<<18)
+#if defined(HAVE_WEAK_IMPORT) && (MAC_OS_X_VERSION_MIN_REQUIRED < 1040)
/* Support for weakly importing copyfile. */
#define WEAK_IMPORT_COPYFILE
extern int copyfile(const char *from, const char *to,
@@ -47,6 +47,14 @@ extern int copyfile(const char *from, const char *to,
#endif /* HAVE_COPYFILE_H */
#endif /* HAVE_COPYFILE */
+#ifdef WEAK_IMPORT_COPYFILE
+#define MayUseCopyFile() (copyfile != NULL)
+#elif defined(HAVE_COPYFILE)
+#define MayUseCopyFile() (1)
+#else
+#define MayUseCopyFile() (0)
+#endif
+
#include <libkern/OSByteOrder.h>
/*
@@ -86,7 +94,7 @@ static const Tcl_ObjType tclOSTypeType = {
};
enum {
- kIsInvisible = 0x4000,
+ kIsInvisible = 0x4000,
};
#define kFinfoIsInvisible (OSSwapHostToBigConstInt16(kIsInvisible))
@@ -142,8 +150,8 @@ TclMacOSXGetFileAttribute(
result = TclpObjStat(fileName, &statBuf);
if (result != 0) {
- Tcl_AppendResult(interp, "could not read \"",
- TclGetString(fileName), "\": ", Tcl_PosixError(interp), NULL);
+ Tcl_AppendResult(interp, "could not read \"", TclGetString(fileName),
+ "\": ", Tcl_PosixError(interp), NULL);
return TCL_ERROR;
}
@@ -234,8 +242,8 @@ TclMacOSXSetFileAttribute(
result = TclpObjStat(fileName, &statBuf);
if (result != 0) {
- Tcl_AppendResult(interp, "could not read \"",
- TclGetString(fileName), "\": ", Tcl_PosixError(interp), NULL);
+ Tcl_AppendResult(interp, "could not read \"", TclGetString(fileName),
+ "\": ", Tcl_PosixError(interp), NULL);
return TCL_ERROR;
}
@@ -300,8 +308,8 @@ TclMacOSXSetFileAttribute(
if (result != 0) {
Tcl_AppendResult(interp, "could not set attributes of \"",
- TclGetString(fileName), "\": ",
- Tcl_PosixError(interp), NULL);
+ TclGetString(fileName), "\": ", Tcl_PosixError(interp),
+ NULL);
return TCL_ERROR;
}
} else {
@@ -320,7 +328,7 @@ TclMacOSXSetFileAttribute(
* supported.
*/
- if(newRsrcForkSize != 0) {
+ if (newRsrcForkSize != 0) {
Tcl_AppendResult(interp,
"setting nonzero rsrclength not supported", NULL);
return TCL_ERROR;
@@ -337,11 +345,13 @@ TclMacOSXSetFileAttribute(
result = truncate(Tcl_DStringValue(&ds), (off_t)0);
if (result != 0) {
/*
- * truncate() on a valid resource fork path may fail with
- * a permission error in some OS releases, try truncating
- * with open() instead:
+ * truncate() on a valid resource fork path may fail with a
+ * permission error in some OS releases, try truncating with
+ * open() instead:
*/
+
int fd = open(Tcl_DStringValue(&ds), O_WRONLY | O_TRUNC);
+
if (fd > 0) {
result = close(fd);
}
@@ -390,25 +400,21 @@ TclMacOSXCopyFileAttributes(
const Tcl_StatBuf *statBufPtr)
/* Stat info for source file */
{
-#ifdef WEAK_IMPORT_COPYFILE
- if (copyfile != NULL) {
-#endif
+ if (MayUseCopyFile()) {
#ifdef HAVE_COPYFILE
- if (copyfile(src, dst, NULL, COPYFILE_XATTR |
- (S_ISLNK(statBufPtr->st_mode)
- ? COPYFILE_NOFOLLOW_SRC : COPYFILE_ACL)) < 0) {
- return TCL_ERROR;
+ if (0 == copyfile(src, dst, NULL, (S_ISLNK(statBufPtr->st_mode)
+ ? COPYFILE_XATTR | COPYFILE_NOFOLLOW_SRC
+ : COPYFILE_XATTR | COPYFILE_ACL))) {
+ return TCL_OK;
}
- return TCL_OK;
#endif /* HAVE_COPYFILE */
-#ifdef WEAK_IMPORT_COPYFILE
} else {
-#endif
-#if !defined(HAVE_COPYFILE) || defined(WEAK_IMPORT_COPYFILE)
-#ifdef HAVE_GETATTRLIST
+#if (!defined(HAVE_COPYFILE) || defined(WEAK_IMPORT_COPYFILE)) && defined(HAVE_GETATTRLIST)
struct attrlist alist;
fileinfobuf finfo;
off_t *rsrcForkSize = (off_t *) &finfo.data;
+ Tcl_DString srcBuf, dstBuf;
+ int result;
bzero(&alist, sizeof(struct attrlist));
alist.bitmapcount = ATTR_BIT_MAP_COUNT;
@@ -417,57 +423,56 @@ TclMacOSXCopyFileAttributes(
if (getattrlist(src, &alist, &finfo, sizeof(fileinfobuf), 0)) {
return TCL_ERROR;
}
-
if (setattrlist(dst, &alist, &finfo.data, sizeof(finfo.data), 0)) {
return TCL_ERROR;
}
- if (!S_ISDIR(statBufPtr->st_mode)) {
- /*
- * Only copy non-empty resource fork.
- */
-
- alist.commonattr = 0;
- alist.fileattr = ATTR_FILE_RSRCLENGTH;
+ /*
+ * If we're a directory, we're done as they never have resource forks.
+ */
- if (getattrlist(src, &alist, &finfo, sizeof(fileinfobuf), 0)) {
- return TCL_ERROR;
- }
+ if (S_ISDIR(statBufPtr->st_mode)) {
+ return TCL_OK;
+ }
- if (*rsrcForkSize > 0) {
- int result;
- Tcl_DString ds_src, ds_dst;
+ /*
+ * We only copy a non-empty resource fork, so determine if that's the
+ * case first.
+ */
- /*
- * Construct paths to resource forks.
- */
+ alist.commonattr = 0;
+ alist.fileattr = ATTR_FILE_RSRCLENGTH;
+ if (getattrlist(src, &alist, &finfo, sizeof(fileinfobuf), 0)) {
+ return TCL_ERROR;
+ } else if (*rsrcForkSize == 0) {
+ return TCL_OK;
+ }
- Tcl_DStringInit(&ds_src);
- Tcl_DStringAppend(&ds_src, src, -1);
- Tcl_DStringAppend(&ds_src, _PATH_RSRCFORKSPEC, -1);
- Tcl_DStringInit(&ds_dst);
- Tcl_DStringAppend(&ds_dst, dst, -1);
- Tcl_DStringAppend(&ds_dst, _PATH_RSRCFORKSPEC, -1);
+ /*
+ * Construct paths to resource forks.
+ */
- result = TclUnixCopyFile(Tcl_DStringValue(&ds_src),
- Tcl_DStringValue(&ds_dst), statBufPtr, 1);
+ Tcl_DStringInit(&srcBuf);
+ Tcl_DStringAppend(&srcBuf, src, -1);
+ Tcl_DStringAppend(&srcBuf, _PATH_RSRCFORKSPEC, -1);
+ Tcl_DStringInit(&dstBuf);
+ Tcl_DStringAppend(&dstBuf, dst, -1);
+ Tcl_DStringAppend(&dstBuf, _PATH_RSRCFORKSPEC, -1);
- Tcl_DStringFree(&ds_src);
- Tcl_DStringFree(&ds_dst);
+ /*
+ * Do the copy.
+ */
- if (result != 0) {
- return TCL_ERROR;
- }
- }
+ result = TclUnixCopyFile(Tcl_DStringValue(&srcBuf),
+ Tcl_DStringValue(&dstBuf), statBufPtr, 1);
+ Tcl_DStringFree(&srcBuf);
+ Tcl_DStringFree(&dstBuf);
+ if (result == 0) {
+ return TCL_OK;
}
- return TCL_OK;
-#else
- return TCL_ERROR;
-#endif /* HAVE_GETATTRLIST */
-#endif /* !defined(HAVE_COPYFILE) || defined(WEAK_IMPORT_COPYFILE) */
-#ifdef WEAK_IMPORT_COPYFILE
+#endif /* (!HAVE_COPYFILE || WEAK_IMPORT_COPYFILE) && HAVE_GETATTRLIST */
}
-#endif
+ return TCL_ERROR;
}
/*
@@ -491,11 +496,11 @@ TclMacOSXCopyFileAttributes(
int
TclMacOSXMatchType(
- Tcl_Interp *interp, /* Interpreter to receive errors. */
- const char *pathName, /* Native path to check. */
- const char *fileName, /* Native filename to check. */
- Tcl_StatBuf *statBufPtr, /* Stat info for file to check */
- Tcl_GlobTypeData *types) /* Type description to match against. */
+ Tcl_Interp *interp, /* Interpreter to receive errors. */
+ const char *pathName, /* Native path to check. */
+ const char *fileName, /* Native filename to check. */
+ Tcl_StatBuf *statBufPtr, /* Stat info for file to check */
+ Tcl_GlobTypeData *types) /* Type description to match against. */
{
#ifdef HAVE_GETATTRLIST
struct attrlist alist;
@@ -676,7 +681,8 @@ SetOSTypeFromAny(
static void
UpdateStringOfOSType(
- register Tcl_Obj *objPtr) /* OSType object whose string rep to update. */
+ register Tcl_Obj *objPtr) /* OSType object whose string rep to
+ * update. */
{
char string[5];
OSType osType = (OSType) objPtr->internalRep.longValue;