summaryrefslogtreecommitdiffstats
path: root/macosx
diff options
context:
space:
mode:
Diffstat (limited to 'macosx')
-rw-r--r--macosx/README34
-rw-r--r--macosx/Tcl.xcodeproj/project.pbxproj22
-rw-r--r--macosx/tclMacOSXFCmd.c30
-rw-r--r--macosx/tclMacOSXNotify.c138
4 files changed, 168 insertions, 56 deletions
diff --git a/macosx/README b/macosx/README
index 561c468..6c2c81a 100644
--- a/macosx/README
+++ b/macosx/README
@@ -1,7 +1,7 @@
Tcl Mac OS X README
-----------------
-RCS: @(#) $Id: README,v 1.6 2005/11/27 02:33:49 das Exp $
+RCS: @(#) $Id: README,v 1.7 2006/07/20 06:18:37 das Exp $
This is the README file for the Mac OS X/Darwin version of Tcl.
@@ -36,9 +36,12 @@ Mac OS X specific bugs should usually be assigned to 'das' or 'wolfsuit'.
- At a minimum, Mac OS X 10.1 is required to run Tcl, but OS X 10.3 or higher is
recommended (certain [file] operations behave incorrectly on earlier releases).
-- Tcl built on Mac OS X 10.x will not run on 10.y for y < x, on the other hand
-Tcl built on 10.y will run on 10.x for y < x (but without any of the fixes and
-optimizations that would be available in a binary built on 10.x).
+- Unless weak-linking is used, Tcl built on Mac OS X 10.x will not run on 10.y
+with y < x; on the other hand Tcl built on 10.y will always run on 10.x with
+y <= x (but without any of the fixes and optimizations that would be available
+in a binary built on 10.x).
+Weak-linking is available on OS X 10.2 or later, it additionally allows Tcl
+built on 10.x to run on any 10.y with x > y >= z (for a chosen z >= 2).
- Tcl extensions can be installed in any of:
$HOME/Library/Tcl /Library/Tcl /Network/Library/Tcl /System/Library/Tcl
@@ -79,10 +82,9 @@ http://connect.apple.com (after you register for free ADC membership).
(see below for details), but can also be built with the standard unix configure
and make buildsystem in tcl/unix as on any other unix platform (indeed, the
GNUmakefile is just a wrapper around the unix buildsystem).
-The Mac OS X specifc configure flags are --enable-framework and
+The Mac OS X specific configure flags are --enable-framework and
--disable-corefoundation (which disables CF and notably reverts to the standard
-select based notifier, you will only need this if your require use of naked fork
-(i.e. not followed by execve) in an unthreaded core).
+select based notifier).
- It is also possible to build with Apple's IDE via the projects in tcl/macosx,
take care to only use the project matching your DevTools and OS version:
@@ -116,12 +118,22 @@ Notes about the native targets of the Xcode projects:
export CFLAGS="-arch ppc -arch ppc64 -arch i386 \
-isysroot /Developer/SDKs/MacOSX10.4u.sdk -mmacosx-version-min=10.4"
This requires Mac OS X 10.4 and Xcode 2.2 (_not_ Xcode 2.1) and will work on any
-of the architectures (on i386 DTKs, the -isysroot is not required). Note that it
-is not possible to configure correctly if the current architecture is not
+of the architectures (on intel Macs, the -isysroot is not required). Note that
+it is not possible to configure correctly if the current architecture is not
present in CFLAGS (i.e. -arch `arch` must always be there). Universal builds of
Tcl TEA extensions are also possible with CFLAGS set as above, they will be
[load]able by universal as well as thin binaries of Tcl.
+- To enable weak-linking, set the MACOSX_DEPLOYMENT_TARGET environment variable
+to the minimal OS version (>= 10.2) the binaries should be able to run on, e.g:
+ export MACOSX_DEPLOYMENT_TARGET=10.2
+This requires Mac OS X 10.2 and gcc 3.1; if you have gcc 4 or later you can set
+CFLAGS instead:
+ export CFLAGS="-mmacosx-version-min=10.2"
+The Tcl.xcodeproj is setup to produce binaires that can run on 10.2 or later,
+except for the 'ReleaseUniversal'configuration, where they require 10.4.
+Support for weak-linking was added to the code for 8.4.14/8.5a5.
+
Detailed Instructions for building with macosx/GNUmakefile
----------------------------------------------------------
@@ -152,8 +164,8 @@ instead by passing an INSTALL_ROOT argument to make:
- The default Makefile targets will build _both_ debug and optimized versions of
the Tcl framework with the standard convention of naming the debug library
Tcl.framework/Tcl_debug.
-This allows you to dynamically link to the debug libraries at runtime by setting
- setenv DYLD_IMAGE_SUFFIX _debug
+This allows switching to the debug libraries at runtime by setting
+ export DYLD_IMAGE_SUFFIX=_debug
(c.f. man dyld for more details)
If you only want to build and install the debug or optimized build, use the
diff --git a/macosx/Tcl.xcodeproj/project.pbxproj b/macosx/Tcl.xcodeproj/project.pbxproj
index 89c24e1..9c72230 100644
--- a/macosx/Tcl.xcodeproj/project.pbxproj
+++ b/macosx/Tcl.xcodeproj/project.pbxproj
@@ -1871,7 +1871,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/bash;
- shellScript = "## tcl configure shell script phase\n\ncd \"${TCL_SRCROOT}\"/macosx &&\nif [ configure.ac -nt configure -o ../unix/configure.in -nt configure -o ../unix/tcl.m4 -nt configure -o ../unix/aclocal.m4 -nt configure ]; then\n echo \"Running autoconf & autoheader in tcl/macosx\"\n rm -rf autom4te.cache\n ${AUTOCONF:-/usr/bin/autoconf} && ${AUTOHEADER:-/usr/bin/autoheader}\n rm -rf autom4te.cache\nfi\n\ncd \"${DERIVED_FILE_DIR}\" && mkdir -p tcl && cd tcl &&\nif [ \"${TCL_SRCROOT}\"/macosx/configure -nt config.status ]; then\n \"${TCL_SRCROOT}\"/macosx/configure --cache-file=../config.cache --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} --mandir=${MANDIR} --includedir=${INCLUDEDIR} --disable-shared ${CONFIGURE_ARGS}\nelse\n ./config.status\nfi\n";
+ shellScript = "## tcl configure shell script phase\n\ncd \"${TCL_SRCROOT}\"/macosx &&\nif [ configure.ac -nt configure -o ../unix/configure.in -nt configure -o ../unix/tcl.m4 -nt configure -o ../unix/aclocal.m4 -nt configure ]; then\n echo \"Running autoconf & autoheader in tcl/macosx\"\n rm -rf autom4te.cache\n ${AUTOCONF:-/usr/bin/autoconf} && ${AUTOHEADER:-/usr/bin/autoheader}\n rm -rf autom4te.cache\nfi\n\ncd \"${DERIVED_FILE_DIR}\" && mkdir -p tcl && cd tcl &&\nif [ \"${TCL_SRCROOT}\"/macosx/configure -nt config.status ]; then\n echo \"Configuring tcl\"\n \"${TCL_SRCROOT}\"/macosx/configure --cache-file=../config.cache --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} --mandir=${MANDIR} --includedir=${INCLUDEDIR} --disable-shared ${CONFIGURE_ARGS}\nelse\n ./config.status\nfi\n";
};
/* End PBXShellScriptBuildPhase section */
@@ -2084,7 +2084,6 @@
INCLUDEDIR = "${PREFIX}/include";
INSTALL_PATH = "${BINDIR}";
LIBDIR = "${PREFIX}/lib";
- MACOSX_DEPLOYMENT_TARGET = 10.4;
MANDIR = "${PREFIX}/man";
OTHER_LDFLAGS = "-headerpad_max_install_names";
PER_ARCH_CFLAGS_ppc = "-mcpu=G3 -mtune=G4";
@@ -2100,6 +2099,9 @@
WARNING_CFLAGS = (
"-Wall",
"-Wno-implicit-int",
+ "-Wextra",
+ "-Wno-unused-parameter",
+ "-Wno-missing-field-initializers",
);
ZERO_LINK = NO;
};
@@ -2111,6 +2113,7 @@
CFLAGS = "-arch ppc -arch ppc64 -arch i386 -isysroot ${SDKROOT} -mmacosx-version-min=10.4";
CONFIGURE_ARGS = "--disable-symbols";
GCC_PREPROCESSOR_DEFINITIONS = NDEBUG;
+ MACOSX_DEPLOYMENT_TARGET = 10.4;
SDKROOT = /Developer/SDKs/MacOSX10.4u.sdk;
};
name = ReleaseUniversal;
@@ -2184,7 +2187,6 @@
INCLUDEDIR = "${PREFIX}/include";
INSTALL_PATH = "${BINDIR}";
LIBDIR = "${PREFIX}/lib";
- MACOSX_DEPLOYMENT_TARGET = 10.4;
MANDIR = "${PREFIX}/man";
OTHER_LDFLAGS = "-headerpad_max_install_names";
PER_ARCH_CFLAGS_ppc = "-mcpu=G3 -mtune=G4";
@@ -2200,6 +2202,9 @@
WARNING_CFLAGS = (
"-Wall",
"-Wno-implicit-int",
+ "-Wextra",
+ "-Wno-unused-parameter",
+ "-Wno-missing-field-initializers",
);
ZERO_LINK = YES;
};
@@ -2231,7 +2236,6 @@
INCLUDEDIR = "${PREFIX}/include";
INSTALL_PATH = "${BINDIR}";
LIBDIR = "${PREFIX}/lib";
- MACOSX_DEPLOYMENT_TARGET = 10.4;
MANDIR = "${PREFIX}/man";
OTHER_LDFLAGS = "-headerpad_max_install_names";
PER_ARCH_CFLAGS_ppc = "-mcpu=G3 -mtune=G4";
@@ -2247,6 +2251,9 @@
WARNING_CFLAGS = (
"-Wall",
"-Wno-implicit-int",
+ "-Wextra",
+ "-Wno-unused-parameter",
+ "-Wno-missing-field-initializers",
);
ZERO_LINK = NO;
};
@@ -2279,7 +2286,6 @@
INCLUDEDIR = "${PREFIX}/include";
INSTALL_PATH = "${BINDIR}";
LIBDIR = "${PREFIX}/lib";
- MACOSX_DEPLOYMENT_TARGET = 10.4;
MANDIR = "${PREFIX}/man";
OTHER_LDFLAGS = "-headerpad_max_install_names";
PER_ARCH_CFLAGS_ppc = "-mcpu=G3 -mtune=G4";
@@ -2295,6 +2301,9 @@
WARNING_CFLAGS = (
"-Wall",
"-Wno-implicit-int",
+ "-Wextra",
+ "-Wno-unused-parameter",
+ "-Wno-missing-field-initializers",
);
ZERO_LINK = NO;
};
@@ -2305,6 +2314,7 @@
buildSettings = {
CONFIGURE_ARGS = "--enable-symbols";
GCC_PREPROCESSOR_DEFINITIONS = "__private_extern__=extern";
+ MACOSX_DEPLOYMENT_TARGET = 10.2;
};
name = Debug;
};
@@ -2313,6 +2323,7 @@
buildSettings = {
CONFIGURE_ARGS = "--disable-symbols";
GCC_PREPROCESSOR_DEFINITIONS = NDEBUG;
+ MACOSX_DEPLOYMENT_TARGET = 10.2;
};
name = Release;
};
@@ -2321,6 +2332,7 @@
buildSettings = {
CONFIGURE_ARGS = "--enable-symbols";
GCC_PREPROCESSOR_DEFINITIONS = "";
+ MACOSX_DEPLOYMENT_TARGET = 10.2;
};
name = DebugNoFixZL;
};
diff --git a/macosx/tclMacOSXFCmd.c b/macosx/tclMacOSXFCmd.c
index 80e9785..51fe222 100644
--- a/macosx/tclMacOSXFCmd.c
+++ b/macosx/tclMacOSXFCmd.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: tclMacOSXFCmd.c,v 1.8 2006/03/21 11:06:23 das Exp $
+ * RCS: @(#) $Id: tclMacOSXFCmd.c,v 1.9 2006/07/20 06:18:37 das Exp $
*/
#include "tclInt.h"
@@ -21,7 +21,7 @@
#include <libkern/OSByteOrder.h>
#endif
-/* Darwin 8 copyfile API */
+/* Darwin 8 copyfile API. */
#ifdef HAVE_COPYFILE
#ifdef HAVE_COPYFILE_H
#include <copyfile.h>
@@ -30,8 +30,14 @@ 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
+#endif /* HAVE_COPYFILE_H */
+#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, void *state,
+ uint32_t flags) WEAK_IMPORT_ATTRIBUTE;
+#endif /* HAVE_WEAK_IMPORT */
+#endif /* HAVE_COPYFILE */
#include <libkern/OSByteOrder.h>
@@ -365,14 +371,22 @@ TclMacOSXCopyFileAttributes(
CONST Tcl_StatBuf *statBufPtr)
/* Stat info for source file */
{
-#if defined(HAVE_COPYFILE)
+#ifdef WEAK_IMPORT_COPYFILE
+ if (copyfile != NULL) {
+#endif
+#ifdef 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)
+#endif /* HAVE_COPYFILE */
+#ifdef WEAK_IMPORT_COPYFILE
+ } else {
+#endif
+#if !defined(HAVE_COPYFILE) || defined(WEAK_IMPORT_COPYFILE)
+#ifdef HAVE_GETATTRLIST
struct attrlist alist;
fileinfobuf finfo;
off_t *rsrcForkSize = (off_t*)(&finfo.data);
@@ -430,6 +444,10 @@ TclMacOSXCopyFileAttributes(
return TCL_OK;
#else
return TCL_ERROR;
+#endif /* HAVE_GETATTRLIST */
+#endif /* !defined(HAVE_COPYFILE) || defined(WEAK_IMPORT_COPYFILE) */
+#ifdef WEAK_IMPORT_COPYFILE
+ }
#endif
}
diff --git a/macosx/tclMacOSXNotify.c b/macosx/tclMacOSXNotify.c
index a99e11b..6d892ea 100644
--- a/macosx/tclMacOSXNotify.c
+++ b/macosx/tclMacOSXNotify.c
@@ -13,7 +13,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclMacOSXNotify.c,v 1.7 2006/05/27 05:22:58 das Exp $
+ * RCS: @(#) $Id: tclMacOSXNotify.c,v 1.8 2006/07/20 06:18:37 das Exp $
*/
#include "tclInt.h"
@@ -163,6 +163,32 @@ static int receivePipe = -1; /* Output end of triggerPipe */
#include <libkern/OSAtomic.h>
+#if defined(HAVE_WEAK_IMPORT) && MAC_OS_X_VERSION_MIN_REQUIRED < 1040
+/*
+ * Support for weakly importing spinlock API.
+ */
+#define WEAK_IMPORT_SPINLOCKLOCK
+extern void OSSpinLockLock(OSSpinLock *lock) WEAK_IMPORT_ATTRIBUTE;
+extern void OSSpinLockUnlock(OSSpinLock *lock) WEAK_IMPORT_ATTRIBUTE;
+extern void _spin_lock(OSSpinLock *lock) WEAK_IMPORT_ATTRIBUTE;
+extern void _spin_unlock(OSSpinLock *lock) WEAK_IMPORT_ATTRIBUTE;
+static void (* lockLock)(OSSpinLock *lock) = NULL;
+static void (* lockUnlock)(OSSpinLock *lock) = NULL;
+static pthread_once_t spinLockLockInitControl = PTHREAD_ONCE_INIT;
+static void SpinLockLockInit(void) {
+ lockLock = OSSpinLockLock != NULL ? OSSpinLockLock : _spin_lock;
+ lockUnlock = OSSpinLockUnlock != NULL ? OSSpinLockUnlock : _spin_unlock;
+ if (lockLock == NULL || lockUnlock == NULL) {
+ Tcl_Panic("SpinLockLockInit: no spinlock API available.");
+ }
+}
+#define SpinLockLock(p) lockLock(p)
+#define SpinLockUnlock(p) lockUnlock(p)
+#else
+#define SpinLockLock(p) OSSpinLockLock(p)
+#define SpinLockUnlock(p) OSSpinLockUnlock(p)
+#endif /* HAVE_WEAK_IMPORT */
+
#else
/*
* Otherwise, use commpage spinlock SPI directly.
@@ -171,8 +197,8 @@ static int receivePipe = -1; /* Output end of triggerPipe */
typedef uint32_t OSSpinLock;
extern void _spin_lock(OSSpinLock *lock);
extern void _spin_unlock(OSSpinLock *lock);
-#define OSSpinLockLock(p) _spin_lock(p)
-#define OSSpinLockUnlock(p) _spin_unlock(p)
+#define SpinLockLock(p) _spin_lock(p)
+#define SpinLockUnlock(p) _spin_unlock(p)
#endif /* HAVE_LIBKERN_OSATOMIC_H && HAVE_OSSPINLOCKLOCK */
@@ -187,10 +213,10 @@ static OSSpinLock notifierLock = 0;
* Macros abstracting notifier locking/unlocking
*/
-#define LOCK_NOTIFIER_INIT OSSpinLockLock(&notifierInitLock)
-#define UNLOCK_NOTIFIER_INIT OSSpinLockUnlock(&notifierInitLock)
-#define LOCK_NOTIFIER OSSpinLockLock(&notifierLock)
-#define UNLOCK_NOTIFIER OSSpinLockUnlock(&notifierLock)
+#define LOCK_NOTIFIER_INIT SpinLockLock(&notifierInitLock)
+#define UNLOCK_NOTIFIER_INIT SpinLockUnlock(&notifierInitLock)
+#define LOCK_NOTIFIER SpinLockLock(&notifierLock)
+#define UNLOCK_NOTIFIER SpinLockUnlock(&notifierLock)
/*
* The pollState bits
@@ -222,7 +248,13 @@ static int atForkInit = 0;
static void AtForkPrepare(void);
static void AtForkParent(void);
static void AtForkChild(void);
-#endif
+#if defined(HAVE_WEAK_IMPORT) && MAC_OS_X_VERSION_MIN_REQUIRED < 1040
+/* Support for weakly importing pthread_atfork. */
+#define WEAK_IMPORT_PTHREAD_ATFORK
+extern int pthread_atfork(void (*prepare)(void), void (*parent)(void),
+ void (*child)(void)) WEAK_IMPORT_ATTRIBUTE;
+#endif /* HAVE_WEAK_IMPORT */
+#endif /* HAVE_PTHREAD_ATFORK */
/*
*----------------------------------------------------------------------
@@ -247,8 +279,17 @@ Tcl_InitNotifier(void)
tsdPtr->eventReady = 0;
+#ifdef WEAK_IMPORT_SPINLOCKLOCK
+ /*
+ * Initialize support for weakly imported spinlock API.
+ */
+ if (pthread_once(&spinLockLockInitControl, SpinLockLockInit)) {
+ Tcl_Panic("Tcl_InitNotifier: pthread_once failed.");
+ }
+#endif
+
/*
- * Initialize CFRunLoopSource and add it to CFRunLoop of this thread
+ * Initialize CFRunLoopSource and add it to CFRunLoop of this thread.
*/
if (!tsdPtr->runLoop) {
@@ -267,28 +308,31 @@ Tcl_InitNotifier(void)
tsdPtr->runLoop = runLoop;
}
- /*
- * Initialize trigger pipe and start the Notifier thread if necessary.
- */
-
LOCK_NOTIFIER_INIT;
#ifdef HAVE_PTHREAD_ATFORK
/*
- * Install pthread_atfork handlers to reinstall the notifier thread in the
+ * Install pthread_atfork handlers to reinitialize the notifier in the
* child of a fork.
*/
- if (!atForkInit) {
+ if (
+#ifdef WEAK_IMPORT_PTHREAD_ATFORK
+ pthread_atfork != NULL &&
+#endif
+ !atForkInit) {
int result = pthread_atfork(AtForkPrepare, AtForkParent, AtForkChild);
if (result) {
- Tcl_Panic("Tcl_InitNotifier: pthread_atfork failed");
+ Tcl_Panic("Tcl_InitNotifier: pthread_atfork failed.");
}
atForkInit = 1;
}
#endif
if (notifierCount == 0) {
- int fds[2], status, result;
- pthread_attr_t attr;
+ int fds[2], status;
+
+ /*
+ * Initialize trigger pipe.
+ */
if (pipe(fds) != 0) {
Tcl_Panic("Tcl_InitNotifier: could not create trigger pipe.");
@@ -308,16 +352,13 @@ Tcl_InitNotifier(void)
receivePipe = fds[0];
triggerPipe = fds[1];
- pthread_attr_init(&attr);
- pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
- pthread_attr_setstacksize(&attr, 60 * 1024);
- result = pthread_create(&notifierThread, &attr,
- (void * (*)(void *))NotifierThreadProc, NULL);
- pthread_attr_destroy(&attr);
- if (result) {
- Tcl_Panic("Tcl_InitNotifier: unable to start notifier thread.");
- }
+ /*
+ * Create notifier thread lazily in Tcl_WaitForEvent() to avoid
+ * interfering with fork() followed immediately by execve()
+ * (cannot execve() when more than one thread is present).
+ */
+
+ notifierThread = 0;
}
notifierCount++;
UNLOCK_NOTIFIER_INIT;
@@ -378,9 +419,12 @@ Tcl_FinalizeNotifier(
write(triggerPipe, "q", 1);
close(triggerPipe);
- result = pthread_join(notifierThread, NULL);
- if (result) {
- Tcl_Panic("Tcl_FinalizeNotifier: unable to join notifier thread.");
+ if (notifierThread) {
+ result = pthread_join(notifierThread, NULL);
+ if (result) {
+ Tcl_Panic("Tcl_FinalizeNotifier: unable to join notifier thread.");
+ }
+ notifierThread = 0;
}
close(receivePipe);
@@ -784,6 +828,28 @@ Tcl_WaitForEvent(
}
/*
+ * Start notifier thread if necessary.
+ */
+
+ LOCK_NOTIFIER_INIT;
+ if (!notifierThread) {
+ int result;
+ pthread_attr_t attr;
+
+ pthread_attr_init(&attr);
+ pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
+ pthread_attr_setstacksize(&attr, 60 * 1024);
+ result = pthread_create(&notifierThread, &attr,
+ (void * (*)(void *))NotifierThreadProc, NULL);
+ pthread_attr_destroy(&attr);
+ if (result || !notifierThread) {
+ Tcl_Panic("Tcl_WaitForEvent: unable to start notifier thread.");
+ }
+ }
+ UNLOCK_NOTIFIER_INIT;
+
+ /*
* Place this thread on the list of interested threads, signal the
* notifier thread, and wait for a response or a timeout.
*/
@@ -1158,9 +1224,13 @@ AtForkChild(void)
}
if (notifierCount > 0) {
notifierCount = 0;
- /* Note that Tcl_FinalizeNotifier does not use its clientData
- * parameter, so discard return value of Tcl_InitNotifier here and
- * leave stale clientData in tclNotify.c's ThreadSpecificData.
+ /*
+ * Assume that the return value of Tcl_InitNotifier() in the child
+ * will be identical to the one stored as clientData in tclNotify.c's
+ * ThreadSpecificData by the parent's TclInitNotifier(), so discard
+ * the return value here. This assumption may require the fork() to
+ * be executed in the main thread of the parent, otherwise
+ * Tcl_AlertNotifier() may break in the child.
*/
Tcl_InitNotifier();
}