summaryrefslogtreecommitdiffstats
path: root/unix/tclUnixFCmd.c
diff options
context:
space:
mode:
authordas <das>2007-04-29 02:19:51 (GMT)
committerdas <das>2007-04-29 02:19:51 (GMT)
commitdc7f0e90b924058de8ec68eb3dccc4d1604607d4 (patch)
treed6658030aa01c0f869855cef3f15363d7d770406 /unix/tclUnixFCmd.c
parent184d051d02dfd8fac7ea89ac7672f3c865b88fdd (diff)
downloadtcl-dc7f0e90b924058de8ec68eb3dccc4d1604607d4.zip
tcl-dc7f0e90b924058de8ec68eb3dccc4d1604607d4.tar.gz
tcl-dc7f0e90b924058de8ec68eb3dccc4d1604607d4.tar.bz2
* unix/tclUnixFCmd.c: add workaround for crashing bug in fts_open()
* unix/tclUnixInit.c: without FTS_NOSTAT on 64bit Darwin 8 or earlier.
Diffstat (limited to 'unix/tclUnixFCmd.c')
-rw-r--r--unix/tclUnixFCmd.c46
1 files changed, 30 insertions, 16 deletions
diff --git a/unix/tclUnixFCmd.c b/unix/tclUnixFCmd.c
index eb48103..60eb2af 100644
--- a/unix/tclUnixFCmd.c
+++ b/unix/tclUnixFCmd.c
@@ -10,7 +10,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclUnixFCmd.c,v 1.28.2.14 2006/11/07 17:29:04 andreas_kupries Exp $
+ * RCS: @(#) $Id: tclUnixFCmd.c,v 1.28.2.15 2007/04/29 02:19:51 das Exp $
*
* Portions of this code were derived from NetBSD source code which has
* the following copyright notice:
@@ -205,6 +205,25 @@ extern long tclMacOSXDarwinRelease;
#endif
#endif /* NO_REALPATH */
+#ifdef HAVE_FTS
+#ifdef HAVE_STRUCT_STAT64
+/* fts doesn't do stat64 */
+#define noFtsStat 1
+#elif defined(__APPLE__) && defined(__LP64__) && \
+ defined(MAC_OS_X_VERSION_MIN_REQUIRED) && \
+ MAC_OS_X_VERSION_MIN_REQUIRED < 1050
+/*
+ * prior to Darwin 9, 64bit fts_open() without FTS_NOSTAT may crash (due to a
+ * 64bit-unsafe ALIGN macro); if we could be running on pre-10.5 OSX, check
+ * Darwin release at runtime and do a separate stat() if necessary.
+ */
+extern long tclMacOSXDarwinRelease;
+#define noFtsStat (tclMacOSXDarwinRelease < 9)
+#else
+#define noFtsStat 0
+#endif
+#endif /* HAVE_FTS */
+
/*
*---------------------------------------------------------------------------
@@ -980,13 +999,8 @@ TraverseUnixTree(traverseProc, sourcePtr, targetPtr, errorPtr, doRewind)
}
#else /* HAVE_FTS */
paths[0] = source;
- fts = fts_open((char**)paths, FTS_PHYSICAL|FTS_NOCHDIR|
-#ifdef HAVE_STRUCT_STAT64
- FTS_NOSTAT, /* fts doesn't do stat64 */
-#else
- (doRewind ? FTS_NOSTAT : 0), /* no need to stat for delete */
-#endif
- NULL);
+ fts = fts_open((char**)paths, FTS_PHYSICAL | FTS_NOCHDIR |
+ (noFtsStat || doRewind ? FTS_NOSTAT : 0), NULL);
if (fts == NULL) {
errfile = source;
goto end;
@@ -1024,15 +1038,15 @@ TraverseUnixTree(traverseProc, sourcePtr, targetPtr, errorPtr, doRewind)
break;
}
if (!doRewind) { /* no need to stat for delete */
-#ifdef HAVE_STRUCT_STAT64
- statBufPtr = &statBuf;
- if (TclOSlstat(ent->fts_path, statBufPtr) != 0) {
- errfile = ent->fts_path;
- break;
+ if (noFtsStat) {
+ statBufPtr = &statBuf;
+ if (TclOSlstat(ent->fts_path, statBufPtr) != 0) {
+ errfile = ent->fts_path;
+ break;
+ }
+ } else {
+ statBufPtr = ent->fts_statp;
}
-#else
- statBufPtr = ent->fts_statp;
-#endif
}
result = (*traverseProc)(sourcePtr, targetPtr, statBufPtr, type,
errorPtr);