summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--changes6
-rwxr-xr-xunix/configure60
-rw-r--r--unix/configure.in20
-rw-r--r--unix/tclUnixFCmd.c130
5 files changed, 189 insertions, 36 deletions
diff --git a/ChangeLog b/ChangeLog
index 40528f9..290f823 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,7 +1,14 @@
-2005-12-04 Daniel Steffen <das@users.sourceforge.net>
+2005-12-05 Don Porter <dgp@users.sourceforge.net>
*** 8.4.12 TAGGED FOR RELEASE ***
+ * unix/configure.in: Revised fix for [Bug 1034337] from Daniel
+ * unix/tclUnixFCmd.c: Steffen. Uses fts_*() routines.
+ * unix/configure: autoconf-2.13
+ * changes: Update changes for 8.4.12 release
+
+2005-12-04 Daniel Steffen <das@users.sourceforge.net>
+
* README: refer to macosx/README instead of mac/README.
* mac/README: add note that mac classic port is no longer supported.
diff --git a/changes b/changes
index 017bb5b..f7178a3 100644
--- a/changes
+++ b/changes
@@ -1,6 +1,6 @@
Recent user-visible changes to Tcl:
-RCS: @(#) $Id: changes,v 1.79.2.31 2005/12/03 21:55:24 hobbs Exp $
+RCS: @(#) $Id: changes,v 1.79.2.32 2005/12/05 15:10:32 dgp Exp $
1. No more [command1] [command2] construct for grouping multiple
commands on a single command line.
@@ -6276,8 +6276,6 @@ Restores Tcl 8.4.9 behavior (porter)
2005-10-05 (bug fix)[979640] buffer overrun mixing putenv(), ::env (bold,hobbs)
-2005-10-07 (Darwin bug fix)[1034337] recursive file delete, MacOSX, NFS (hobbs)
-
2005-10-13 (bug fix)[1284178] [format] accept all integer values (porter)
2005-10-22 (bug fix)[1251791] optimization exposed wide/int difference(sofer)
@@ -6321,4 +6319,6 @@ Restores Tcl 8.4.9 behavior (porter)
2005-11-29 (enhancement)[1369597] Win 64: --enable-64bit=amd64|ia64 (hobbs)
+2005-12-05 (Darwin bug fix)[1034337] NFS recursive file delete (steffen)
+
--- Released 8.4.12, Decemeber 3, 2005 --- See ChangeLog for details ---
diff --git a/unix/configure b/unix/configure
index 44f82a0..d243def 100755
--- a/unix/configure
+++ b/unix/configure
@@ -7493,6 +7493,50 @@ EOF
#--------------------------------------------------------------------
+# Check for support of fts functions on Darwin (readdir replacement)
+#--------------------------------------------------------------------
+
+if test "`uname -s`" = "Darwin" ; then
+ echo $ac_n "checking for fts""... $ac_c" 1>&6
+echo "configure:7502: checking for fts" >&5
+if eval "test \"`echo '$''{'tcl_cv_api_fts'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+
+ cat > conftest.$ac_ext <<EOF
+#line 7508 "configure"
+#include "confdefs.h"
+#include <sys/param.h>
+ #include <sys/stat.h>
+ #include <fts.h>
+int main() {
+char*const p[2] = {"/", NULL};
+ FTS *f = fts_open(p, FTS_PHYSICAL|FTS_NOCHDIR|FTS_NOSTAT, NULL);
+ FTSENT *e = fts_read(f); fts_close(f);
+; return 0; }
+EOF
+if { (eval echo configure:7519: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ tcl_cv_api_fts=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ tcl_cv_api_fts=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$tcl_cv_api_fts" 1>&6
+ if test $tcl_cv_api_fts = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_FTS 1
+EOF
+
+ fi
+fi
+
+#--------------------------------------------------------------------
# The statements below check for systems where POSIX-style
# non-blocking I/O (O_NONBLOCK) doesn't work or is unimplemented.
# On these systems (mostly older ones), use the old BSD-style
@@ -7504,17 +7548,17 @@ EOF
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:7508: checking for $ac_hdr" >&5
+echo "configure:7552: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 7513 "configure"
+#line 7557 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:7518: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:7562: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
@@ -7544,17 +7588,17 @@ done
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:7548: checking for $ac_hdr" >&5
+echo "configure:7592: checking for $ac_hdr" >&5
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 7553 "configure"
+#line 7597 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:7558: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:7602: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
if test -z "$ac_err"; then
rm -rf conftest*
@@ -7581,7 +7625,7 @@ fi
done
echo $ac_n "checking FIONBIO vs. O_NONBLOCK for nonblocking I/O""... $ac_c" 1>&6
-echo "configure:7585: checking FIONBIO vs. O_NONBLOCK for nonblocking I/O" >&5
+echo "configure:7629: checking FIONBIO vs. O_NONBLOCK for nonblocking I/O" >&5
if test -f /usr/lib/NextStep/software_version; then
system=NEXTSTEP-`awk '/3/,/3/' /usr/lib/NextStep/software_version`
else
@@ -7661,7 +7705,7 @@ HTML_DIR='$(DISTDIR)/html'
if test "`uname -s`" = "Darwin" ; then
echo $ac_n "checking how to package libraries""... $ac_c" 1>&6
-echo "configure:7665: checking how to package libraries" >&5
+echo "configure:7709: checking how to package libraries" >&5
# Check whether --enable-framework or --disable-framework was given.
if test "${enable_framework+set}" = set; then
enableval="$enable_framework"
diff --git a/unix/configure.in b/unix/configure.in
index 791497f..18079e9 100644
--- a/unix/configure.in
+++ b/unix/configure.in
@@ -3,7 +3,7 @@ dnl This file is an input file used by the GNU "autoconf" program to
dnl generate the file "configure", which is run during Tcl installation
dnl to configure the system for the local environment.
#
-# RCS: @(#) $Id: configure.in,v 1.106.2.21 2005/11/27 02:34:42 das Exp $
+# RCS: @(#) $Id: configure.in,v 1.106.2.22 2005/12/05 15:10:33 dgp Exp $
AC_INIT(../generic/tcl.h)
AC_PREREQ(2.13)
@@ -436,6 +436,24 @@ fi
SC_ENABLE_LANGINFO
#--------------------------------------------------------------------
+# Check for support of fts functions on Darwin (readdir replacement)
+#--------------------------------------------------------------------
+
+if test "`uname -s`" = "Darwin" ; then
+ AC_CACHE_CHECK([for fts], tcl_cv_api_fts, [
+ AC_TRY_LINK([#include <sys/param.h>
+ #include <sys/stat.h>
+ #include <fts.h>],
+ [char*const p[2] = {"/", NULL};
+ FTS *f = fts_open(p, FTS_PHYSICAL|FTS_NOCHDIR|FTS_NOSTAT, NULL);
+ FTSENT *e = fts_read(f); fts_close(f);],
+ tcl_cv_api_fts=yes, tcl_cv_api_fts=no)])
+ if test $tcl_cv_api_fts = yes; then
+ AC_DEFINE(HAVE_FTS)
+ fi
+fi
+
+#--------------------------------------------------------------------
# The statements below check for systems where POSIX-style
# non-blocking I/O (O_NONBLOCK) doesn't work or is unimplemented.
# On these systems (mostly older ones), use the old BSD-style
diff --git a/unix/tclUnixFCmd.c b/unix/tclUnixFCmd.c
index f5555b7..02bd513 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.7 2005/11/27 02:34:42 das Exp $
+ * RCS: @(#) $Id: tclUnixFCmd.c,v 1.28.2.8 2005/12/05 15:10:33 dgp Exp $
*
* Portions of this code were derived from NetBSD source code which has
* the following copyright notice:
@@ -56,6 +56,9 @@
#include <sys/statfs.h>
#endif
#endif
+#ifdef HAVE_FTS
+#include <fts.h>
+#endif
/*
* The following constants specify the type of callback when
@@ -147,7 +150,7 @@ static int CopyFile _ANSI_ARGS_((CONST char *src,
static int CopyFileAtts _ANSI_ARGS_((CONST char *src,
CONST char *dst, CONST Tcl_StatBuf *statBufPtr));
static int DoCopyFile _ANSI_ARGS_((CONST char *srcPtr,
- CONST char *dstPtr));
+ CONST char *dstPtr, CONST Tcl_StatBuf *statBufPtr));
static int DoCreateDirectory _ANSI_ARGS_((CONST char *pathPtr));
static int DoRemoveDirectory _ANSI_ARGS_((Tcl_DString *pathPtr,
int recursive, Tcl_DString *errorPtr));
@@ -343,25 +346,26 @@ TclpObjCopyFile(srcPathPtr, destPathPtr)
Tcl_Obj *srcPathPtr;
Tcl_Obj *destPathPtr;
{
- return DoCopyFile(Tcl_FSGetNativePath(srcPathPtr),
- Tcl_FSGetNativePath(destPathPtr));
+ CONST char *src = Tcl_FSGetNativePath(srcPathPtr);
+ Tcl_StatBuf srcStatBuf;
+
+ if (TclOSlstat(src, &srcStatBuf) != 0) { /* INTL: Native. */
+ return TCL_ERROR;
+ }
+
+ return DoCopyFile(src, Tcl_FSGetNativePath(destPathPtr), &srcStatBuf);
}
static int
-DoCopyFile(src, dst)
+DoCopyFile(src, dst, statBufPtr)
CONST char *src; /* Pathname of file to be copied (native). */
CONST char *dst; /* Pathname of file to copy to (native). */
+ CONST Tcl_StatBuf *statBufPtr;
+ /* Used to determine filetype. */
{
- Tcl_StatBuf srcStatBuf, dstStatBuf;
+ Tcl_StatBuf dstStatBuf;
- /*
- * Have to do a stat() to determine the filetype.
- */
-
- if (TclOSlstat(src, &srcStatBuf) != 0) { /* INTL: Native. */
- return TCL_ERROR;
- }
- if (S_ISDIR(srcStatBuf.st_mode)) {
+ if (S_ISDIR(statBufPtr->st_mode)) {
errno = EISDIR;
return TCL_ERROR;
}
@@ -383,7 +387,7 @@ DoCopyFile(src, dst)
}
}
- switch ((int) (srcStatBuf.st_mode & S_IFMT)) {
+ switch ((int) (statBufPtr->st_mode & S_IFMT)) {
#ifndef DJGPP
case S_IFLNK: {
char link[MAXPATHLEN];
@@ -405,20 +409,20 @@ DoCopyFile(src, dst)
#endif
case S_IFBLK:
case S_IFCHR: {
- if (mknod(dst, srcStatBuf.st_mode, /* INTL: Native. */
- srcStatBuf.st_rdev) < 0) {
+ if (mknod(dst, statBufPtr->st_mode, /* INTL: Native. */
+ statBufPtr->st_rdev) < 0) {
return TCL_ERROR;
}
- return CopyFileAtts(src, dst, &srcStatBuf);
+ return CopyFileAtts(src, dst, statBufPtr);
}
case S_IFIFO: {
- if (mkfifo(dst, srcStatBuf.st_mode) < 0) { /* INTL: Native. */
+ if (mkfifo(dst, statBufPtr->st_mode) < 0) { /* INTL: Native. */
return TCL_ERROR;
}
- return CopyFileAtts(src, dst, &srcStatBuf);
+ return CopyFileAtts(src, dst, statBufPtr);
}
default: {
- return CopyFile(src, dst, &srcStatBuf);
+ return CopyFile(src, dst, statBufPtr);
}
}
return TCL_OK;
@@ -832,9 +836,15 @@ TraverseUnixTree(traverseProc, sourcePtr, targetPtr, errorPtr, doRewind)
CONST char *source, *errfile;
int result, sourceLen;
int targetLen;
+#ifndef HAVE_FTS
int numProcessed = 0;
Tcl_DirEntry *dirEntPtr;
DIR *dirPtr;
+#else
+ CONST char *paths[2] = {NULL, NULL};
+ FTS *fts = NULL;
+ FTSENT *ent;
+#endif
errfile = NULL;
result = TCL_OK;
@@ -853,6 +863,7 @@ TraverseUnixTree(traverseProc, sourcePtr, targetPtr, errorPtr, doRewind)
return (*traverseProc)(sourcePtr, targetPtr, &statBuf, DOTREE_F,
errorPtr);
}
+#ifndef HAVE_FTS
dirPtr = opendir(source); /* INTL: Native. */
if (dirPtr == NULL) {
/*
@@ -938,6 +949,74 @@ TraverseUnixTree(traverseProc, sourcePtr, targetPtr, errorPtr, doRewind)
result = (*traverseProc)(sourcePtr, targetPtr, &statBuf, DOTREE_POSTD,
errorPtr);
}
+#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);
+ if (fts == NULL) {
+ errfile = source;
+ goto end;
+ }
+
+ sourceLen = Tcl_DStringLength(sourcePtr);
+ if (targetPtr != NULL) {
+ targetLen = Tcl_DStringLength(targetPtr);
+ }
+
+ while ((ent = fts_read(fts)) != NULL) {
+ unsigned short info = ent->fts_info;
+ char * path = ent->fts_path + sourceLen;
+ unsigned short pathlen = ent->fts_pathlen - sourceLen;
+ int type;
+ Tcl_StatBuf *statBufPtr = NULL;
+
+ if (info == FTS_DNR || info == FTS_ERR || info == FTS_NS) {
+ errfile = ent->fts_path;
+ break;
+ }
+ Tcl_DStringAppend(sourcePtr, path, pathlen);
+ if (targetPtr != NULL) {
+ Tcl_DStringAppend(targetPtr, path, pathlen);
+ }
+ switch (info) {
+ case FTS_D:
+ type = DOTREE_PRED;
+ break;
+ case FTS_DP:
+ type = DOTREE_POSTD;
+ break;
+ default:
+ type = DOTREE_F;
+ 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;
+ }
+#else
+ statBufPtr = ent->fts_statp;
+#endif
+ }
+ result = (*traverseProc)(sourcePtr, targetPtr, statBufPtr, type,
+ errorPtr);
+ if (result != TCL_OK) {
+ break;
+ }
+ Tcl_DStringSetLength(sourcePtr, sourceLen);
+ if (targetPtr != NULL) {
+ Tcl_DStringSetLength(targetPtr, targetLen);
+ }
+ }
+#endif /* HAVE_FTS */
+
end:
if (errfile != NULL) {
if (errorPtr != NULL) {
@@ -945,6 +1024,11 @@ TraverseUnixTree(traverseProc, sourcePtr, targetPtr, errorPtr, doRewind)
}
result = TCL_ERROR;
}
+#ifdef HAVE_FTS
+ if (fts != NULL) {
+ fts_close(fts);
+ }
+#endif /* HAVE_FTS */
return result;
}
@@ -980,8 +1064,8 @@ TraversalCopy(srcPtr, dstPtr, statBufPtr, type, errorPtr)
{
switch (type) {
case DOTREE_F:
- if (DoCopyFile(Tcl_DStringValue(srcPtr),
- Tcl_DStringValue(dstPtr)) == TCL_OK) {
+ if (DoCopyFile(Tcl_DStringValue(srcPtr), Tcl_DStringValue(dstPtr),
+ statBufPtr) == TCL_OK) {
return TCL_OK;
}
break;