summaryrefslogtreecommitdiffstats
path: root/unix
diff options
context:
space:
mode:
Diffstat (limited to 'unix')
-rw-r--r--unix/tclUnixNotfy.c407
-rw-r--r--unix/tclUnixPipe.c531
-rw-r--r--unix/tclXtNotify.c291
3 files changed, 618 insertions, 611 deletions
diff --git a/unix/tclUnixNotfy.c b/unix/tclUnixNotfy.c
index b0052d4..3c4dbee 100644
--- a/unix/tclUnixNotfy.c
+++ b/unix/tclUnixNotfy.c
@@ -1,64 +1,68 @@
/*
* tclUnixNotify.c --
*
- * This file contains the implementation of the select-based
- * Unix-specific notifier, which is the lowest-level part
- * of the Tcl event loop. This file works together with
- * generic/tclNotify.c.
+ * This file contains the implementation of the select()-based
+ * Unix-specific notifier, which is the lowest-level part of the Tcl
+ * event loop. This file works together with generic/tclNotify.c.
*
* Copyright (c) 1995-1997 Sun Microsystems, Inc.
*
- * See the file "license.terms" for information on usage and redistribution
- * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclUnixNotfy.c,v 1.27 2005/07/01 10:29:12 vasiljevic Exp $
+ * RCS: @(#) $Id: tclUnixNotfy.c,v 1.28 2005/07/24 22:56:44 dkf Exp $
*/
-#ifndef HAVE_COREFOUNDATION /* Darwin/Mac OS X CoreFoundation notifier
- * is in tclMacOSXNotify.c */
+#ifndef HAVE_COREFOUNDATION /* Darwin/Mac OS X CoreFoundation notifier is
+ * in tclMacOSXNotify.c */
#include "tclInt.h"
#include <signal.h>
+/*
+ * This code does deep stub magic to allow replacement of the notifier at
+ * runtime.
+ */
+
extern TclStubs tclStubs;
extern Tcl_NotifierProcs tclOriginalNotifier;
/*
- * This structure is used to keep track of the notifier info for a
- * a registered file.
+ * This structure is used to keep track of the notifier info for a registered
+ * file.
*/
typedef struct FileHandler {
int fd;
int mask; /* Mask of desired events: TCL_READABLE,
* etc. */
- int readyMask; /* Mask of events that have been seen since the
- * last time file handlers were invoked for
- * this file. */
- Tcl_FileProc *proc; /* Procedure to call, in the style of
+ int readyMask; /* Mask of events that have been seen since
+ * the last time file handlers were invoked
+ * for this file. */
+ Tcl_FileProc *proc; /* Function to call, in the style of
* Tcl_CreateFileHandler. */
ClientData clientData; /* Argument to pass to proc. */
struct FileHandler *nextPtr;/* Next in list of all files we care about. */
} FileHandler;
/*
- * The following structure is what is added to the Tcl event queue when
- * file handlers are ready to fire.
+ * The following structure is what is added to the Tcl event queue when file
+ * handlers are ready to fire.
*/
typedef struct FileHandlerEvent {
- Tcl_Event header; /* Information that is standard for
- * all events. */
- int fd; /* File descriptor that is ready. Used
- * to find the FileHandler structure for
- * the file (can't point directly to the
- * FileHandler structure because it could
- * go away while the event is queued). */
+ Tcl_Event header; /* Information that is standard for all
+ * events. */
+ int fd; /* File descriptor that is ready. Used to find
+ * the FileHandler structure for the file
+ * (can't point directly to the FileHandler
+ * structure because it could go away while
+ * the event is queued). */
} FileHandlerEvent;
/*
*
- * The following structure contains a set of select() masks to track
- * readable, writable, and exceptional conditions.
+ * The following structure contains a set of select() masks to track readable,
+ * writable, and exceptional conditions.
*/
typedef struct SelectMasks {
@@ -69,42 +73,41 @@ typedef struct SelectMasks {
/*
* The following static structure contains the state information for the
- * select based implementation of the Tcl notifier. One of these structures
- * is created for each thread that is using the notifier.
+ * select based implementation of the Tcl notifier. One of these structures is
+ * created for each thread that is using the notifier.
*/
typedef struct ThreadSpecificData {
FileHandler *firstFileHandlerPtr;
/* Pointer to head of file handler list. */
-
- SelectMasks checkMasks; /* This structure is used to build up the masks
- * to be used in the next call to select.
- * Bits are set in response to calls to
- * Tcl_CreateFileHandler. */
+ SelectMasks checkMasks; /* This structure is used to build up the
+ * masks to be used in the next call to
+ * select. Bits are set in response to calls
+ * to Tcl_CreateFileHandler. */
SelectMasks readyMasks; /* This array reflects the readable/writable
* conditions that were found to exist by the
* last call to select. */
- int numFdBits; /* Number of valid bits in checkMasks
- * (one more than highest fd for which
+ int numFdBits; /* Number of valid bits in checkMasks (one
+ * more than highest fd for which
* Tcl_WatchFile has been called). */
#ifdef TCL_THREADS
int onList; /* True if it is in this list */
- unsigned int pollState; /* pollState is used to implement a polling
+ unsigned int pollState; /* pollState is used to implement a polling
* handshake between each thread and the
* notifier thread. Bits defined below. */
struct ThreadSpecificData *nextPtr, *prevPtr;
- /* All threads that are currently waiting on
+ /* All threads that are currently waiting on
* an event have their ThreadSpecificData
* structure on a doubly-linked listed formed
* from these pointers. You must hold the
* notifierMutex lock before accessing these
* fields. */
- Tcl_Condition waitCV; /* Any other thread alerts a notifier
- * that an event is ready to be processed
- * by signaling this condition variable. */
+ Tcl_Condition waitCV; /* Any other thread alerts a notifier that an
+ * event is ready to be processed by signaling
+ * this condition variable. */
int eventReady; /* True if an event is ready to be processed.
- * Used as condition flag together with
- * waitCV above. */
+ * Used as condition flag together with waitCV
+ * above. */
#endif
} ThreadSpecificData;
@@ -112,8 +115,8 @@ static Tcl_ThreadDataKey dataKey;
#ifdef TCL_THREADS
/*
- * The following static indicates the number of threads that have
- * initialized notifiers.
+ * The following static indicates the number of threads that have initialized
+ * notifiers.
*
* You must hold the notifierMutex lock before accessing this variable.
*/
@@ -121,9 +124,9 @@ static Tcl_ThreadDataKey dataKey;
static int notifierCount = 0;
/*
- * The following variable points to the head of a doubly-linked list of
- * of ThreadSpecificData structures for all threads that are currently
- * waiting on an event.
+ * The following variable points to the head of a doubly-linked list of
+ * ThreadSpecificData structures for all threads that are currently waiting on
+ * an event.
*
* You must hold the notifierMutex lock before accessing this list.
*/
@@ -131,16 +134,15 @@ static int notifierCount = 0;
static ThreadSpecificData *waitingListPtr = NULL;
/*
- * The notifier thread spends all its time in select() waiting for a
- * file descriptor associated with one of the threads on the waitingListPtr
- * list to do something interesting. But if the contents of the
- * waitingListPtr list ever changes, we need to wake up and restart
- * the select() system call. You can wake up the notifier thread by
- * writing a single byte to the file descriptor defined below. This
- * file descriptor is the input-end of a pipe and the notifier thread is
- * listening for data on the output-end of the same pipe. Hence writing
- * to this file descriptor will cause the select() system call to return
- * and wake up the notifier thread.
+ * The notifier thread spends all its time in select() waiting for a file
+ * descriptor associated with one of the threads on the waitingListPtr list to
+ * do something interesting. But if the contents of the waitingListPtr list
+ * ever changes, we need to wake up and restart the select() system call. You
+ * can wake up the notifier thread by writing a single byte to the file
+ * descriptor defined below. This file descriptor is the input-end of a pipe
+ * and the notifier thread is listening for data on the output-end of the same
+ * pipe. Hence writing to this file descriptor will cause the select() system
+ * call to return and wake up the notifier thread.
*
* You must hold the notifierMutex lock before accessing this list.
*/
@@ -148,34 +150,35 @@ static ThreadSpecificData *waitingListPtr = NULL;
static int triggerPipe = -1;
/*
- * The notifierMutex locks access to all of the global notifier state.
+ * The notifierMutex locks access to all of the global notifier state.
*/
TCL_DECLARE_MUTEX(notifierMutex)
/*
* The notifier thread signals the notifierCV when it has finished
- * initializing the triggerPipe and right before the notifier
- * thread terminates.
+ * initializing the triggerPipe and right before the notifier thread
+ * terminates.
*/
static Tcl_Condition notifierCV;
/*
- * The pollState bits
+ * The pollState bits:
* POLL_WANT is set by each thread before it waits on its condition
- * variable. It is checked by the notifier before it does
- * select.
- * POLL_DONE is set by the notifier if it goes into select after
- * seeing POLL_WANT. The idea is to ensure it tries a select
- * with the same bits the initial thread had set.
+ * variable. It is checked by the notifier before it does select.
+ * POLL_DONE is set by the notifier if it goes into select after seeing
+ * POLL_WANT. The idea is to ensure it tries a select with the
+ * same bits the initial thread had set.
*/
+
#define POLL_WANT 0x1
#define POLL_DONE 0x2
/*
* This is the thread ID of the notifier thread that does select.
*/
+
static Tcl_ThreadId notifierThread;
#endif
@@ -244,15 +247,15 @@ Tcl_InitNotifier()
*
* Tcl_FinalizeNotifier --
*
- * This function is called to cleanup the notifier state before
- * a thread is terminated.
+ * This function is called to cleanup the notifier state before a thread
+ * is terminated.
*
* Results:
* None.
*
* Side effects:
- * May terminate the background notifier thread if this is the
- * last notifier instance.
+ * May terminate the background notifier thread if this is the last
+ * notifier instance.
*
*----------------------------------------------------------------------
*/
@@ -268,8 +271,8 @@ Tcl_FinalizeNotifier(clientData)
notifierCount--;
/*
- * If this is the last thread to use the notifier, close the notifier
- * pipe and wait for the background thread to terminate.
+ * If this is the last thread to use the notifier, close the notifier pipe
+ * and wait for the background thread to terminate.
*/
if (notifierCount == 0) {
@@ -279,14 +282,14 @@ Tcl_FinalizeNotifier(clientData)
}
/*
- * Send "q" message to the notifier thread so that it will
- * terminate. The notifier will return from its call to select()
- * and notice that a "q" message has arrived, it will then close
- * its side of the pipe and terminate its thread. Note the we can
- * not just close the pipe and check for EOF in the notifier
- * thread because if a background child process was created with
- * exec, select() would not register the EOF on the pipe until the
- * child processes had terminated. [Bug: 4139] [Bug: 1222872]
+ * Send "q" message to the notifier thread so that it will terminate.
+ * The notifier will return from its call to select() and notice that
+ * a "q" message has arrived, it will then close its side of the pipe
+ * and terminate its thread. Note the we can not just close the pipe
+ * and check for EOF in the notifier thread because if a background
+ * child process was created with exec, select() would not register
+ * the EOF on the pipe until the child processes had terminated. [Bug:
+ * 4139] [Bug: 1222872]
*/
write(triggerPipe, "q", 1);
@@ -315,18 +318,16 @@ Tcl_FinalizeNotifier(clientData)
*
* Tcl_AlertNotifier --
*
- * Wake up the specified notifier from any thread. This routine
- * is called by the platform independent notifier code whenever
- * the Tcl_ThreadAlert routine is called. This routine is
- * guaranteed not to be called on a given notifier after
- * Tcl_FinalizeNotifier is called for that notifier.
+ * Wake up the specified notifier from any thread. This routine is called
+ * by the platform independent notifier code whenever the Tcl_ThreadAlert
+ * routine is called. This routine is guaranteed not to be called on a
+ * given notifier after Tcl_FinalizeNotifier is called for that notifier.
*
* Results:
* None.
*
* Side effects:
- * Signals the notifier condition variable for the specified
- * notifier.
+ * Signals the notifier condition variable for the specified notifier.
*
*----------------------------------------------------------------------
*/
@@ -349,9 +350,9 @@ Tcl_AlertNotifier(clientData)
*
* Tcl_SetTimer --
*
- * This procedure sets the current notifier timer value. This
- * interface is not implemented in this notifier because we are
- * always running inside of Tcl_DoOneEvent.
+ * This function sets the current notifier timer value. This interface is
+ * not implemented in this notifier because we are always running inside
+ * of Tcl_DoOneEvent.
*
* Results:
* None.
@@ -367,9 +368,9 @@ Tcl_SetTimer(timePtr)
Tcl_Time *timePtr; /* Timeout value, may be NULL. */
{
/*
- * The interval timer doesn't do anything in this implementation,
- * because the only event loop is via Tcl_DoOneEvent, which passes
- * timeout values to Tcl_WaitForEvent.
+ * The interval timer doesn't do anything in this implementation, because
+ * the only event loop is via Tcl_DoOneEvent, which passes timeout values
+ * to Tcl_WaitForEvent.
*/
if (tclStubs.tcl_SetTimer != tclOriginalNotifier.setTimerProc) {
@@ -405,7 +406,7 @@ Tcl_ServiceModeHook(mode)
*
* Tcl_CreateFileHandler --
*
- * This procedure registers a file handler with the select notifier.
+ * This function registers a file handler with the select notifier.
*
* Results:
* None.
@@ -420,11 +421,11 @@ void
Tcl_CreateFileHandler(fd, mask, proc, clientData)
int fd; /* Handle of stream to watch. */
int mask; /* OR'ed combination of TCL_READABLE,
- * TCL_WRITABLE, and TCL_EXCEPTION:
- * indicates conditions under which
- * proc should be called. */
- Tcl_FileProc *proc; /* Procedure to call for each
- * selected event. */
+ * TCL_WRITABLE, and TCL_EXCEPTION: indicates
+ * conditions under which proc should be
+ * called. */
+ Tcl_FileProc *proc; /* Function to call for each selected
+ * event. */
ClientData clientData; /* Arbitrary data to pass to proc. */
{
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
@@ -481,8 +482,7 @@ Tcl_CreateFileHandler(fd, mask, proc, clientData)
*
* Tcl_DeleteFileHandler --
*
- * Cancel a previously-arranged callback arrangement for
- * a file.
+ * Cancel a previously-arranged callback arrangement for a file.
*
* Results:
* None.
@@ -495,7 +495,8 @@ Tcl_CreateFileHandler(fd, mask, proc, clientData)
void
Tcl_DeleteFileHandler(fd)
- int fd; /* Stream id for which to remove callback procedure. */
+ int fd; /* Stream id for which to remove callback
+ * function. */
{
FileHandler *filePtr, *prevPtr;
int i;
@@ -511,7 +512,7 @@ Tcl_DeleteFileHandler(fd)
*/
for (prevPtr = NULL, filePtr = tsdPtr->firstFileHandlerPtr; ;
- prevPtr = filePtr, filePtr = filePtr->nextPtr) {
+ prevPtr = filePtr, filePtr = filePtr->nextPtr) {
if (filePtr == NULL) {
return;
}
@@ -567,19 +568,19 @@ Tcl_DeleteFileHandler(fd)
*
* FileHandlerEventProc --
*
- * This procedure is called by Tcl_ServiceEvent when a file event
- * reaches the front of the event queue. This procedure is
- * responsible for actually handling the event by invoking the
- * callback for the file handler.
+ * This function is called by Tcl_ServiceEvent when a file event reaches
+ * the front of the event queue. This function is responsible for
+ * actually handling the event by invoking the callback for the file
+ * handler.
*
* Results:
- * Returns 1 if the event was handled, meaning it should be removed
- * from the queue. Returns 0 if the event was not handled, meaning
- * it should stay on the queue. The only time the event isn't
- * handled is if the TCL_FILE_EVENTS flag bit isn't set.
+ * Returns 1 if the event was handled, meaning it should be removed from
+ * the queue. Returns 0 if the event was not handled, meaning it should
+ * stay on the queue. The only time the event isn't handled is if the
+ * TCL_FILE_EVENTS flag bit isn't set.
*
* Side effects:
- * Whatever the file handler's callback procedure does.
+ * Whatever the file handler's callback function does.
*
*----------------------------------------------------------------------
*/
@@ -587,8 +588,8 @@ Tcl_DeleteFileHandler(fd)
static int
FileHandlerEventProc(evPtr, flags)
Tcl_Event *evPtr; /* Event to service. */
- int flags; /* Flags that indicate what events to
- * handle, such as TCL_FILE_EVENTS. */
+ int flags; /* Flags that indicate what events to handle,
+ * such as TCL_FILE_EVENTS. */
{
int mask;
FileHandler *filePtr;
@@ -601,9 +602,9 @@ FileHandlerEventProc(evPtr, flags)
/*
* Search through the file handlers to find the one whose handle matches
- * the event. We do this rather than keeping a pointer to the file
- * handler directly in the event, so that the handler can be deleted
- * while the event is queued without leaving a dangling pointer.
+ * the event. We do this rather than keeping a pointer to the file handler
+ * directly in the event, so that the handler can be deleted while the
+ * event is queued without leaving a dangling pointer.
*/
tsdPtr = TCL_TSD_INIT(&dataKey);
@@ -615,14 +616,14 @@ FileHandlerEventProc(evPtr, flags)
/*
* The code is tricky for two reasons:
- * 1. The file handler's desired events could have changed
- * since the time when the event was queued, so AND the
- * ready mask with the desired mask.
- * 2. The file could have been closed and re-opened since
- * the time when the event was queued. This is why the
- * ready mask is stored in the file handler rather than
- * the queued event: it will be zeroed when a new
- * file handler is created for the newly opened file.
+ * 1. The file handler's desired events could have changed since the
+ * time when the event was queued, so AND the ready mask with the
+ * desired mask.
+ * 2. The file could have been closed and re-opened since the time
+ * when the event was queued. This is why the ready mask is stored
+ * in the file handler rather than the queued event: it will be
+ * zeroed when a new file handler is created for the newly opened
+ * file.
*/
mask = filePtr->readyMask & filePtr->mask;
@@ -640,13 +641,12 @@ FileHandlerEventProc(evPtr, flags)
*
* Tcl_WaitForEvent --
*
- * This function is called by Tcl_DoOneEvent to wait for new
- * events on the message queue. If the block time is 0, then
- * Tcl_WaitForEvent just polls without blocking.
+ * This function is called by Tcl_DoOneEvent to wait for new events on
+ * the message queue. If the block time is 0, then Tcl_WaitForEvent just
+ * polls without blocking.
*
* Results:
- * Returns -1 if the select would block forever, otherwise
- * returns 0.
+ * Returns -1 if the select would block forever, otherwise returns 0.
*
* Side effects:
* Queues file events that are detected by the select.
@@ -666,13 +666,15 @@ Tcl_WaitForEvent(timePtr)
int waitForFiles;
Tcl_Time *myTimePtr;
#else
- /* Impl. notes: timeout & timeoutPtr are used if, and only if
- * threads are not enabled. They are the arguments for the regular
- * select() used when the core is not thread-enabled. */
+ /*
+ * Impl. notes: timeout & timeoutPtr are used if, and only if threads are
+ * not enabled. They are the arguments for the regular select() used when
+ * the core is not thread-enabled.
+ */
struct timeval timeout, *timeoutPtr;
int numFound;
-#endif
+#endif /* TCL_THREADS */
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
if (tclStubs.tcl_WaitForEvent != tclOriginalNotifier.waitForEventProc) {
@@ -680,15 +682,16 @@ Tcl_WaitForEvent(timePtr)
}
/*
- * Set up the timeout structure. Note that if there are no events to
- * check for, we return with a negative result rather than blocking
- * forever.
+ * Set up the timeout structure. Note that if there are no events to check
+ * for, we return with a negative result rather than blocking forever.
*/
if (timePtr != NULL) {
- /* TIP #233 (Virtualized Time). Is virtual time in effect ?
- * And do we actually have something to scale ? If yes to both
- * then we call the handler to do this scaling */
+ /*
+ * TIP #233 (Virtualized Time). Is virtual time in effect? And do we
+ * actually have something to scale? If yes to both then we call the
+ * handler to do this scaling.
+ */
myTime.sec = timePtr->sec;
myTime.usec = timePtr->usec;
@@ -700,29 +703,29 @@ Tcl_WaitForEvent(timePtr)
#ifdef TCL_THREADS
myTimePtr = &myTime;
#else
- timeout.tv_sec = myTime.sec;
+ timeout.tv_sec = myTime.sec;
timeout.tv_usec = myTime.usec;
- timeoutPtr = &timeout;
-#endif
+ timeoutPtr = &timeout;
+#endif /* TCL_THREADS */
#ifndef TCL_THREADS
} else if (tsdPtr->numFdBits == 0) {
/*
- * If there are no threads, no timeout, and no fds registered,
- * then there are no events possible and we must avoid deadlock.
- * Note that this is not entirely correct because there might
- * be a signal that could interrupt the select call, but we
- * don't handle that case if we aren't using threads.
+ * If there are no threads, no timeout, and no fds registered, then
+ * there are no events possible and we must avoid deadlock. Note that
+ * this is not entirely correct because there might be a signal that
+ * could interrupt the select call, but we don't handle that case if
+ * we aren't using threads.
*/
return -1;
-#endif
+#endif /* !TCL_THREADS */
} else {
#ifdef TCL_THREADS
myTimePtr = NULL;
#else
timeoutPtr = NULL;
-#endif
+#endif /* TCL_THREADS */
}
#ifdef TCL_THREADS
@@ -737,10 +740,10 @@ Tcl_WaitForEvent(timePtr)
if (myTimePtr != NULL && myTimePtr->sec == 0 && myTimePtr->usec == 0) {
/*
* Cannot emulate a polling select with a polling condition variable.
- * Instead, pretend to wait for files and tell the notifier
- * thread what we are doing. The notifier thread makes sure
- * it goes through select with its select mask in the same state
- * as ours currently is. We block until that happens.
+ * Instead, pretend to wait for files and tell the notifier thread
+ * what we are doing. The notifier thread makes sure it goes through
+ * select with its select mask in the same state as ours currently is.
+ * We block until that happens.
*/
waitForFiles = 1;
@@ -752,9 +755,9 @@ Tcl_WaitForEvent(timePtr)
if (waitForFiles) {
/*
- * Add the ThreadSpecificData structure of this thread to the list
- * of ThreadSpecificData structures of all threads that are waiting
- * on file events.
+ * Add the ThreadSpecificData structure of this thread to the list of
+ * ThreadSpecificData structures of all threads that are waiting on
+ * file events.
*/
tsdPtr->nextPtr = waitingListPtr;
@@ -773,14 +776,14 @@ Tcl_WaitForEvent(timePtr)
FD_ZERO(&(tsdPtr->readyMasks.exceptional));
if (!tsdPtr->eventReady) {
- Tcl_ConditionWait(&tsdPtr->waitCV, &notifierMutex, myTimePtr);
+ Tcl_ConditionWait(&tsdPtr->waitCV, &notifierMutex, myTimePtr);
}
tsdPtr->eventReady = 0;
if (waitForFiles && tsdPtr->onList) {
/*
* Remove the ThreadSpecificData structure of this thread from the
- * waiting list. Alert the notifier thread to recompute its select
+ * waiting list. Alert the notifier thread to recompute its select
* masks - skipping this caused a hang when trying to close a pipe
* which the notifier thread was still doing a select on.
*/
@@ -798,26 +801,23 @@ Tcl_WaitForEvent(timePtr)
write(triggerPipe, "", 1);
}
-
#else
tsdPtr->readyMasks = tsdPtr->checkMasks;
- numFound = select( tsdPtr->numFdBits,
- &(tsdPtr->readyMasks.readable),
- &(tsdPtr->readyMasks.writable),
- &(tsdPtr->readyMasks.exceptional),
- timeoutPtr );
+ numFound = select(tsdPtr->numFdBits, &(tsdPtr->readyMasks.readable),
+ &(tsdPtr->readyMasks.writable), &(tsdPtr->readyMasks.exceptional),
+ timeoutPtr);
/*
- * Some systems don't clear the masks after an error, so
- * we have to do it here.
+ * Some systems don't clear the masks after an error, so we have to do it
+ * here.
*/
if (numFound == -1) {
- FD_ZERO( &(tsdPtr->readyMasks.readable ) );
- FD_ZERO( &(tsdPtr->readyMasks.writable ) );
- FD_ZERO( &(tsdPtr->readyMasks.exceptional ) );
+ FD_ZERO(&(tsdPtr->readyMasks.readable));
+ FD_ZERO(&(tsdPtr->readyMasks.writable));
+ FD_ZERO(&(tsdPtr->readyMasks.exceptional));
}
-#endif
+#endif /* TCL_THREADS */
/*
* Queue all detected file events before returning.
@@ -842,8 +842,8 @@ Tcl_WaitForEvent(timePtr)
}
/*
- * Don't bother to queue an event if the mask was previously
- * non-zero since an event must still be on the queue.
+ * Don't bother to queue an event if the mask was previously non-zero
+ * since an event must still be on the queue.
*/
if (filePtr->readyMask == 0) {
@@ -856,7 +856,7 @@ Tcl_WaitForEvent(timePtr)
}
#ifdef TCL_THREADS
Tcl_MutexUnlock(&notifierMutex);
-#endif
+#endif /* TCL_THREADS */
return 0;
}
@@ -867,21 +867,20 @@ Tcl_WaitForEvent(timePtr)
* NotifierThreadProc --
*
* This routine is the initial (and only) function executed by the
- * special notifier thread. Its job is to wait for file descriptors
- * to become readable or writable or to have an exception condition
- * and then to notify other threads who are interested in this
- * information by signalling a condition variable. Other threads
- * can signal this notifier thread of a change in their interests
- * by writing a single byte to a special pipe that the notifier
- * thread is monitoring.
+ * special notifier thread. Its job is to wait for file descriptors to
+ * become readable or writable or to have an exception condition and then
+ * to notify other threads who are interested in this information by
+ * signalling a condition variable. Other threads can signal this
+ * notifier thread of a change in their interests by writing a single
+ * byte to a special pipe that the notifier thread is monitoring.
*
* Result:
- * None. Once started, this routine never exits. It dies with
- * the overall process.
+ * None. Once started, this routine never exits. It dies with the overall
+ * process.
*
* Side effects:
- * The trigger pipe used to signal the notifier thread is created
- * when the notifier thread first starts.
+ * The trigger pipe used to signal the notifier thread is created when
+ * the notifier thread first starts.
*
*----------------------------------------------------------------------
*/
@@ -924,7 +923,7 @@ NotifierThreadProc(clientData)
if (ioctl(fds[1], (int) FIONBIO, &status) < 0) {
Tcl_Panic("NotifierThreadProc: could not make trigger pipe non blocking.");
}
-#endif
+#endif /* FIONBIO */
/*
* Install the write end of the pipe into the global variable.
@@ -950,8 +949,8 @@ NotifierThreadProc(clientData)
FD_ZERO(&exceptionalMask);
/*
- * Compute the logical OR of the select masks from all the
- * waiting notifiers.
+ * Compute the logical OR of the select masks from all the waiting
+ * notifiers.
*/
Tcl_MutexLock(&notifierMutex);
@@ -973,8 +972,8 @@ NotifierThreadProc(clientData)
}
if (tsdPtr->pollState & POLL_WANT) {
/*
- * Here we make sure we go through select() with the same
- * mask bits that were present when the thread tried to poll.
+ * Here we make sure we go through select() with the same mask
+ * bits that were present when the thread tried to poll.
*/
tsdPtr->pollState |= POLL_DONE;
@@ -1031,10 +1030,10 @@ NotifierThreadProc(clientData)
tsdPtr->eventReady = 1;
if (tsdPtr->onList) {
/*
- * Remove the ThreadSpecificData structure of this
- * thread from the waiting list. This prevents us from
- * continuously spining on select until the other
- * threads runs and services the file event.
+ * Remove the ThreadSpecificData structure of this thread
+ * from the waiting list. This prevents us from
+ * continuously spining on select until the other threads
+ * runs and services the file event.
*/
if (tsdPtr->prevPtr) {
@@ -1056,8 +1055,8 @@ NotifierThreadProc(clientData)
/*
* Consume the next byte from the notifier pipe if the pipe was
- * readable. Note that there may be multiple bytes pending, but
- * to avoid a race condition we only read one at a time.
+ * readable. Note that there may be multiple bytes pending, but to
+ * avoid a race condition we only read one at a time.
*/
if (FD_ISSET(receivePipe, &readableMask)) {
@@ -1065,9 +1064,9 @@ NotifierThreadProc(clientData)
if ((i == 0) || ((i == 1) && (buf[0] == 'q'))) {
/*
- * Someone closed the write end of the pipe or sent us a
- * Quit message [Bug: 4139] and then closed the write end
- * of the pipe so we need to shut down the notifier thread.
+ * Someone closed the write end of the pipe or sent us a Quit
+ * message [Bug: 4139] and then closed the write end of the
+ * pipe so we need to shut down the notifier thread.
*/
break;
@@ -1088,6 +1087,14 @@ NotifierThreadProc(clientData)
TclpThreadExit (0);
}
-#endif
+#endif /* TCL_THREADS */
#endif /* HAVE_COREFOUNDATION */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/unix/tclUnixPipe.c b/unix/tclUnixPipe.c
index c0dcb46..b19f042 100644
--- a/unix/tclUnixPipe.c
+++ b/unix/tclUnixPipe.c
@@ -1,16 +1,16 @@
-/*
+/*
* tclUnixPipe.c --
*
- * This file implements the UNIX-specific exec pipeline functions,
- * the "pipe" channel driver, and the "pid" Tcl command.
+ * This file implements the UNIX-specific exec pipeline functions, the
+ * "pipe" channel driver, and the "pid" Tcl command.
*
* Copyright (c) 1991-1994 The Regents of the University of California.
* Copyright (c) 1994-1997 Sun Microsystems, Inc.
*
- * See the file "license.terms" for information on usage and redistribution
- * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclUnixPipe.c,v 1.29 2005/06/22 19:48:10 kennykb Exp $
+ * RCS: @(#) $Id: tclUnixPipe.c,v 1.30 2005/07/24 22:56:45 dkf Exp $
*/
#include "tclInt.h"
@@ -20,7 +20,7 @@
#endif
/*
- * The following macros convert between TclFile's and fd's. The conversion
+ * The following macros convert between TclFile's and fd's. The conversion
* simple involves shifting fd's up by one to ensure that no valid fd is ever
* the same as NULL.
*/
@@ -33,16 +33,17 @@
*/
typedef struct PipeState {
- Tcl_Channel channel;/* Channel associated with this file. */
- TclFile inFile; /* Output from pipe. */
- TclFile outFile; /* Input to pipe. */
- TclFile errorFile; /* Error output from pipe. */
- int numPids; /* How many processes are attached to this pipe? */
- Tcl_Pid *pidPtr; /* The process IDs themselves. Allocated by
- * the creator of the pipe. */
- int isNonBlocking; /* Nonzero when the pipe is in nonblocking mode.
- * Used to decide whether to wait for the children
- * at close time. */
+ Tcl_Channel channel; /* Channel associated with this file. */
+ TclFile inFile; /* Output from pipe. */
+ TclFile outFile; /* Input to pipe. */
+ TclFile errorFile; /* Error output from pipe. */
+ int numPids; /* How many processes are attached to this
+ * pipe? */
+ Tcl_Pid *pidPtr; /* The process IDs themselves. Allocated by
+ * the creator of the pipe. */
+ int isNonBlocking; /* Nonzero when the pipe is in nonblocking
+ * mode. Used to decide whether to wait for
+ * the children at close time. */
} PipeState;
/*
@@ -65,8 +66,8 @@ static void RestoreSignals _ANSI_ARGS_((void));
static int SetupStdFile _ANSI_ARGS_((TclFile file, int type));
/*
- * This structure describes the channel type structure for command pipe
- * based IO:
+ * This structure describes the channel type structure for command pipe based
+ * I/O:
*/
static Tcl_ChannelType pipeChannelType = {
@@ -84,8 +85,8 @@ static Tcl_ChannelType pipeChannelType = {
PipeBlockModeProc, /* Set blocking or non-blocking mode.*/
NULL, /* flush proc. */
NULL, /* handler proc. */
- NULL, /* wide seek proc */
- NULL, /* thread action proc */
+ NULL, /* wide seek proc */
+ NULL, /* thread action proc */
};
/*
@@ -111,9 +112,9 @@ TclpMakeFile(channel, direction)
{
ClientData data;
- if (Tcl_GetChannelHandle(channel, direction, (ClientData *) &data)
- == TCL_OK) {
- return MakeFile((int)data);
+ if (Tcl_GetChannelHandle(channel, direction,
+ (ClientData *) &data) == TCL_OK) {
+ return MakeFile((int) data);
} else {
return (TclFile) NULL;
}
@@ -124,7 +125,7 @@ TclpMakeFile(channel, direction)
*
* TclpOpenFile --
*
- * Open a file for use in a pipeline.
+ * Open a file for use in a pipeline.
*
* Results:
* Returns a new TclFile handle or NULL on failure.
@@ -148,11 +149,11 @@ TclpOpenFile(fname, mode)
fd = TclOSopen(native, mode, 0666); /* INTL: Native. */
Tcl_DStringFree(&ds);
if (fd != -1) {
- fcntl(fd, F_SETFD, FD_CLOEXEC);
+ fcntl(fd, F_SETFD, FD_CLOEXEC);
/*
- * If the file is being opened for writing, seek to the end
- * so we can append to any data already in the file.
+ * If the file is being opened for writing, seek to the end so we can
+ * append to any data already in the file.
*/
if (mode & O_WRONLY) {
@@ -160,8 +161,8 @@ TclpOpenFile(fname, mode)
}
/*
- * Increment the fd so it can't be 0, which would conflict with
- * the NULL return for errors.
+ * Increment the fd so it can't be 0, which would conflict with the
+ * NULL return for errors.
*/
return MakeFile(fd);
@@ -174,9 +175,9 @@ TclpOpenFile(fname, mode)
*
* TclpCreateTempFile --
*
- * This function creates a temporary file initialized with an
- * optional string, and returns a file handle with the file pointer
- * at the beginning of the file.
+ * This function creates a temporary file initialized with an optional
+ * string, and returns a file handle with the file pointer at the
+ * beginning of the file.
*
* Results:
* A handle to a file.
@@ -241,7 +242,7 @@ TclpCreateTempFile(contents)
*----------------------------------------------------------------------
*/
-Tcl_Obj*
+Tcl_Obj *
TclpTempFileName()
{
char fileName[L_tmpnam + 9];
@@ -265,7 +266,7 @@ TclpTempFileName()
unlink(fileName); /* INTL: Native. */
result = TclpNativeToNormalized((ClientData) fileName);
- close (fd);
+ close(fd);
return result;
}
@@ -274,23 +275,23 @@ TclpTempFileName()
*
* TclpCreatePipe --
*
- * Creates a pipe - simply calls the pipe() function.
+ * Creates a pipe - simply calls the pipe() function.
*
* Results:
- * Returns 1 on success, 0 on failure.
+ * Returns 1 on success, 0 on failure.
*
* Side effects:
- * Creates a pipe.
+ * Creates a pipe.
*
*----------------------------------------------------------------------
*/
int
TclpCreatePipe(readPipe, writePipe)
- TclFile *readPipe; /* Location to store file handle for
- * read side of pipe. */
- TclFile *writePipe; /* Location to store file handle for
- * write side of pipe. */
+ TclFile *readPipe; /* Location to store file handle for read side
+ * of pipe. */
+ TclFile *writePipe; /* Location to store file handle for write
+ * side of pipe. */
{
int pipeIds[2];
@@ -331,11 +332,11 @@ TclpCloseFile(file)
/*
* Refuse to close the fds for stdin, stdout and stderr.
*/
-
+
if ((fd == 0) || (fd == 1) || (fd == 2)) {
- return 0;
+ return 0;
}
-
+
Tcl_DeleteFileHandler(fd);
return close(fd);
}
@@ -345,28 +346,27 @@ TclpCloseFile(file)
*
* TclpCreateProcess --
*
- * Create a child process that has the specified files as its
- * standard input, output, and error. The child process runs
- * asynchronously and runs with the same environment variables
- * as the creating process.
+ * Create a child process that has the specified files as its standard
+ * input, output, and error. The child process runs asynchronously and
+ * runs with the same environment variables as the creating process.
*
- * The path is searched to find the specified executable.
+ * The path is searched to find the specified executable.
*
* Results:
- * The return value is TCL_ERROR and an error message is left in
- * the interp's result if there was a problem creating the child
- * process. Otherwise, the return value is TCL_OK and *pidPtr is
- * filled with the process id of the child process.
- *
+ * The return value is TCL_ERROR and an error message is left in the
+ * interp's result if there was a problem creating the child process.
+ * Otherwise, the return value is TCL_OK and *pidPtr is filled with the
+ * process id of the child process.
+ *
* Side effects:
* A process is created.
- *
+ *
*---------------------------------------------------------------------------
*/
/* ARGSUSED */
int
-TclpCreateProcess(interp, argc, argv, inputFile, outputFile, errorFile,
+TclpCreateProcess(interp, argc, argv, inputFile, outputFile, errorFile,
pidPtr)
Tcl_Interp *interp; /* Interpreter in which to leave errors that
* occurred when creating the child process.
@@ -376,24 +376,24 @@ TclpCreateProcess(interp, argc, argv, inputFile, outputFile, errorFile,
CONST char **argv; /* Array of argument strings in UTF-8.
* argv[0] contains the name of the executable
* translated using Tcl_TranslateFileName
- * call). Additional arguments have not been
+ * call). Additional arguments have not been
* converted. */
- TclFile inputFile; /* If non-NULL, gives the file to use as
- * input for the child process. If inputFile
- * file is not readable or is NULL, the child
- * will receive no standard input. */
- TclFile outputFile; /* If non-NULL, gives the file that
- * receives output from the child process. If
+ TclFile inputFile; /* If non-NULL, gives the file to use as input
+ * for the child process. If inputFile file is
+ * not readable or is NULL, the child will
+ * receive no standard input. */
+ TclFile outputFile; /* If non-NULL, gives the file that receives
+ * output from the child process. If
* outputFile file is not writeable or is
* NULL, output from the child will be
* discarded. */
- TclFile errorFile; /* If non-NULL, gives the file that
- * receives errors from the child process. If
- * errorFile file is not writeable or is NULL,
- * errors from the child will be discarded.
- * errorFile may be the same as outputFile. */
- Tcl_Pid *pidPtr; /* If this procedure is successful, pidPtr
- * is filled with the process id of the child
+ TclFile errorFile; /* If non-NULL, gives the file that receives
+ * errors from the child process. If errorFile
+ * file is not writeable or is NULL, errors
+ * from the child will be discarded. errorFile
+ * may be the same as outputFile. */
+ Tcl_Pid *pidPtr; /* If this procedure is successful, pidPtr is
+ * filled with the process id of the child
* process. */
{
TclFile errPipeIn, errPipeOut;
@@ -402,14 +402,14 @@ TclpCreateProcess(interp, argc, argv, inputFile, outputFile, errorFile,
Tcl_DString *dsArray;
char **newArgv;
int pid, i;
-
+
errPipeIn = NULL;
errPipeOut = NULL;
pid = -1;
/*
- * Create a pipe that the child can use to return error
- * information if anything goes wrong.
+ * Create a pipe that the child can use to return error information if
+ * anything goes wrong.
*/
if (TclpCreatePipe(&errPipeIn, &errPipeOut) == 0) {
@@ -419,9 +419,10 @@ TclpCreateProcess(interp, argc, argv, inputFile, outputFile, errorFile,
}
/*
- * We need to allocate and convert this before the fork
- * so it is properly deallocated later
+ * We need to allocate and convert this before the fork so it is properly
+ * deallocated later
*/
+
dsArray = (Tcl_DString *) ckalloc(argc * sizeof(Tcl_DString));
newArgv = (char **) ckalloc((argc+1) * sizeof(char *));
newArgv[argc] = NULL;
@@ -442,8 +443,7 @@ TclpCreateProcess(interp, argc, argv, inputFile, outputFile, errorFile,
|| !SetupStdFile(outputFile, TCL_STDOUT)
|| (!joinThisError && !SetupStdFile(errorFile, TCL_STDERR))
|| (joinThisError &&
- ((dup2(1,2) == -1) ||
- (fcntl(2, F_SETFD, 0) != 0)))) {
+ ((dup2(1,2) == -1) || (fcntl(2, F_SETFD, 0) != 0)))) {
sprintf(errSpace,
"%dforked process couldn't set up input/output: ", errno);
write(fd, errSpace, (size_t) strlen(errSpace));
@@ -460,10 +460,11 @@ TclpCreateProcess(interp, argc, argv, inputFile, outputFile, errorFile,
write(fd, errSpace, (size_t) strlen(errSpace));
_exit(1);
}
-
+
/*
* Free the mem we used for the fork
*/
+
for (i = 0; i < argc; i++) {
Tcl_DStringFree(&dsArray[i]);
}
@@ -477,9 +478,9 @@ TclpCreateProcess(interp, argc, argv, inputFile, outputFile, errorFile,
}
/*
- * Read back from the error pipe to see if the child started
- * up OK. The info in the pipe (if any) consists of a decimal
- * errno value followed by an error message.
+ * Read back from the error pipe to see if the child started up OK. The
+ * info in the pipe (if any) consists of a decimal errno value followed by
+ * an error message.
*/
TclpCloseFile(errPipeOut);
@@ -495,23 +496,23 @@ TclpCreateProcess(interp, argc, argv, inputFile, outputFile, errorFile,
(char *) NULL);
goto error;
}
-
+
TclpCloseFile(errPipeIn);
*pidPtr = (Tcl_Pid) pid;
return TCL_OK;
- error:
+ error:
if (pid != -1) {
/*
- * Reap the child process now if an error occurred during its
- * startup. We don't call this with WNOHANG because that can lead to
- * defunct processes on an MP system. We shouldn't have to worry
- * about hanging here, since this is the error case. [Bug: 6148]
+ * Reap the child process now if an error occurred during its startup.
+ * We don't call this with WNOHANG because that can lead to defunct
+ * processes on an MP system. We shouldn't have to worry about hanging
+ * here, since this is the error case. [Bug: 6148]
*/
Tcl_WaitPid((Tcl_Pid) pid, &status, 0);
}
-
+
if (errPipeIn) {
TclpCloseFile(errPipeIn);
}
@@ -526,19 +527,19 @@ TclpCreateProcess(interp, argc, argv, inputFile, outputFile, errorFile,
*
* RestoreSignals --
*
- * This procedure is invoked in a forked child process just before
- * exec-ing a new program to restore all signals to their default
- * settings.
+ * This procedure is invoked in a forked child process just before
+ * exec-ing a new program to restore all signals to their default
+ * settings.
*
* Results:
- * None.
+ * None.
*
* Side effects:
- * Signal settings get changed.
+ * Signal settings get changed.
*
*----------------------------------------------------------------------
*/
-
+
static void
RestoreSignals()
{
@@ -600,10 +601,10 @@ RestoreSignals()
*
* SetupStdFile --
*
- * Set up stdio file handles for the child process, using the
- * current standard channels if no other files are specified.
- * If no standard channel is defined, or if no file is associated
- * with the channel, then the corresponding standard fd is closed.
+ * Set up stdio file handles for the child process, using the current
+ * standard channels if no other files are specified. If no standard
+ * channel is defined, or if no file is associated with the channel, then
+ * the corresponding standard fd is closed.
*
* Results:
* Returns 1 on success, or 0 on failure.
@@ -626,18 +627,18 @@ SetupStdFile(file, type)
* variables. */
switch (type) {
- case TCL_STDIN:
- targetFd = 0;
- direction = TCL_READABLE;
- break;
- case TCL_STDOUT:
- targetFd = 1;
- direction = TCL_WRITABLE;
- break;
- case TCL_STDERR:
- targetFd = 2;
- direction = TCL_WRITABLE;
- break;
+ case TCL_STDIN:
+ targetFd = 0;
+ direction = TCL_READABLE;
+ break;
+ case TCL_STDOUT:
+ targetFd = 1;
+ direction = TCL_WRITABLE;
+ break;
+ case TCL_STDERR:
+ targetFd = 2;
+ direction = TCL_WRITABLE;
+ break;
}
if (!file) {
@@ -653,13 +654,13 @@ SetupStdFile(file, type)
return 0;
}
- /*
- * Must clear the close-on-exec flag for the target FD, since
- * some systems (e.g. Ultrix) do not clear the CLOEXEC flag on
- * the target FD.
- */
-
- fcntl(targetFd, F_SETFD, 0);
+ /*
+ * Must clear the close-on-exec flag for the target FD, since some
+ * systems (e.g. Ultrix) do not clear the CLOEXEC flag on the
+ * target FD.
+ */
+
+ fcntl(targetFd, F_SETFD, 0);
} else {
/*
* Since we aren't dup'ing the file, we need to explicitly clear
@@ -679,9 +680,8 @@ SetupStdFile(file, type)
*
* TclpCreateCommandChannel --
*
- * This function is called by the generic IO level to perform
- * the platform specific channel initialization for a command
- * channel.
+ * This function is called by the generic IO level to perform the
+ * platform specific channel initialization for a command channel.
*
* Results:
* Returns a new channel or NULL on failure.
@@ -699,10 +699,10 @@ TclpCreateCommandChannel(readFile, writeFile, errorFile, numPids, pidPtr)
TclFile errorFile; /* If non-null, gives the file where errors
* can be read. */
int numPids; /* The number of pids in the pid array. */
- Tcl_Pid *pidPtr; /* An array of process identifiers.
- * Allocated by the caller, freed when
- * the channel is closed or the processes
- * are detached (in a background exec). */
+ Tcl_Pid *pidPtr; /* An array of process identifiers. Allocated
+ * by the caller, freed when the channel is
+ * closed or the processes are detached (in a
+ * background exec). */
{
char channelName[16 + TCL_INTEGER_SPACE];
int channelId;
@@ -718,15 +718,14 @@ TclpCreateCommandChannel(readFile, writeFile, errorFile, numPids, pidPtr)
mode = 0;
if (readFile) {
- mode |= TCL_READABLE;
+ mode |= TCL_READABLE;
}
if (writeFile) {
- mode |= TCL_WRITABLE;
+ mode |= TCL_WRITABLE;
}
-
+
/*
- * Use one of the fds associated with the channel as the
- * channel id.
+ * Use one of the fds associated with the channel as the channel id.
*/
if (readFile) {
@@ -740,14 +739,14 @@ TclpCreateCommandChannel(readFile, writeFile, errorFile, numPids, pidPtr)
}
/*
- * For backward compatibility with previous versions of Tcl, we
- * use "file%d" as the base name for pipes even though it would
- * be more natural to use "pipe%d".
+ * For backward compatibility with previous versions of Tcl, we use
+ * "file%d" as the base name for pipes even though it would be more
+ * natural to use "pipe%d".
*/
sprintf(channelName, "file%d", channelId);
statePtr->channel = Tcl_CreateChannel(&pipeChannelType, channelName,
- (ClientData) statePtr, mode);
+ (ClientData) statePtr, mode);
return statePtr->channel;
}
@@ -757,9 +756,9 @@ TclpCreateCommandChannel(readFile, writeFile, errorFile, numPids, pidPtr)
* TclGetAndDetachPids --
*
* This procedure is invoked in the generic implementation of a
- * background "exec" (An exec when invoked with a terminating "&")
- * to store a list of the PIDs for processes in a command pipeline
- * in the interp's result and to detach the processes.
+ * background "exec" (an exec when invoked with a terminating "&") to
+ * store a list of the PIDs for processes in a command pipeline in the
+ * interp's result and to detach the processes.
*
* Results:
* None.
@@ -772,8 +771,8 @@ TclpCreateCommandChannel(readFile, writeFile, errorFile, numPids, pidPtr)
void
TclGetAndDetachPids(interp, chan)
- Tcl_Interp *interp;
- Tcl_Channel chan;
+ Tcl_Interp *interp; /* Interpreter to append the PIDs to. */
+ Tcl_Channel chan; /* Handle for the pipeline. */
{
PipeState *pipePtr;
Tcl_ChannelType *chanTypePtr;
@@ -786,18 +785,18 @@ TclGetAndDetachPids(interp, chan)
chanTypePtr = Tcl_GetChannelType(chan);
if (chanTypePtr != &pipeChannelType) {
- return;
+ return;
}
pipePtr = (PipeState *) Tcl_GetChannelInstanceData(chan);
for (i = 0; i < pipePtr->numPids; i++) {
- TclFormatInt(buf, (long) TclpGetPid(pipePtr->pidPtr[i]));
- Tcl_AppendElement(interp, buf);
- Tcl_DetachPids(1, &(pipePtr->pidPtr[i]));
+ TclFormatInt(buf, (long) TclpGetPid(pipePtr->pidPtr[i]));
+ Tcl_AppendElement(interp, buf);
+ Tcl_DetachPids(1, &(pipePtr->pidPtr[i]));
}
if (pipePtr->numPids > 0) {
- ckfree((char *) pipePtr->pidPtr);
- pipePtr->numPids = 0;
+ ckfree((char *) pipePtr->pidPtr);
+ pipePtr->numPids = 0;
}
}
@@ -806,8 +805,8 @@ TclGetAndDetachPids(interp, chan)
*
* PipeBlockModeProc --
*
- * Helper procedure to set blocking and nonblocking modes on a
- * pipe based channel. Invoked by generic IO level code.
+ * Helper procedure to set blocking and nonblocking modes on a pipe based
+ * channel. Invoked by generic IO level code.
*
* Results:
* 0 if successful, errno when failed.
@@ -821,64 +820,64 @@ TclGetAndDetachPids(interp, chan)
/* ARGSUSED */
static int
PipeBlockModeProc(instanceData, mode)
- ClientData instanceData; /* Pipe state. */
- int mode; /* The mode to set. Can be one of
- * TCL_MODE_BLOCKING or
- * TCL_MODE_NONBLOCKING. */
+ ClientData instanceData; /* Pipe state. */
+ int mode; /* The mode to set. Can be one of
+ * TCL_MODE_BLOCKING or
+ * TCL_MODE_NONBLOCKING. */
{
PipeState *psPtr = (PipeState *) instanceData;
int curStatus;
int fd;
-#ifndef USE_FIONBIO
+#ifndef USE_FIONBIO
if (psPtr->inFile) {
- fd = GetFd(psPtr->inFile);
- curStatus = fcntl(fd, F_GETFL);
- if (mode == TCL_MODE_BLOCKING) {
- curStatus &= (~(O_NONBLOCK));
- } else {
- curStatus |= O_NONBLOCK;
- }
- if (fcntl(fd, F_SETFL, curStatus) < 0) {
- return errno;
- }
+ fd = GetFd(psPtr->inFile);
+ curStatus = fcntl(fd, F_GETFL);
+ if (mode == TCL_MODE_BLOCKING) {
+ curStatus &= (~(O_NONBLOCK));
+ } else {
+ curStatus |= O_NONBLOCK;
+ }
+ if (fcntl(fd, F_SETFL, curStatus) < 0) {
+ return errno;
+ }
}
if (psPtr->outFile) {
- fd = GetFd(psPtr->outFile);
- curStatus = fcntl(fd, F_GETFL);
- if (mode == TCL_MODE_BLOCKING) {
- curStatus &= (~(O_NONBLOCK));
- } else {
- curStatus |= O_NONBLOCK;
- }
- if (fcntl(fd, F_SETFL, curStatus) < 0) {
- return errno;
- }
+ fd = GetFd(psPtr->outFile);
+ curStatus = fcntl(fd, F_GETFL);
+ if (mode == TCL_MODE_BLOCKING) {
+ curStatus &= (~(O_NONBLOCK));
+ } else {
+ curStatus |= O_NONBLOCK;
+ }
+ if (fcntl(fd, F_SETFL, curStatus) < 0) {
+ return errno;
+ }
}
#endif /* !FIONBIO */
#ifdef USE_FIONBIO
if (psPtr->inFile) {
- fd = GetFd(psPtr->inFile);
- if (mode == TCL_MODE_BLOCKING) {
- curStatus = 0;
- } else {
- curStatus = 1;
- }
- if (ioctl(fd, (int) FIONBIO, &curStatus) < 0) {
- return errno;
- }
+ fd = GetFd(psPtr->inFile);
+ if (mode == TCL_MODE_BLOCKING) {
+ curStatus = 0;
+ } else {
+ curStatus = 1;
+ }
+ if (ioctl(fd, (int) FIONBIO, &curStatus) < 0) {
+ return errno;
+ }
}
if (psPtr->outFile != NULL) {
- fd = GetFd(psPtr->outFile);
- if (mode == TCL_MODE_BLOCKING) {
- curStatus = 0;
- } else {
- curStatus = 1;
- }
- if (ioctl(fd, (int) FIONBIO, &curStatus) < 0) {
- return errno;
- }
+ fd = GetFd(psPtr->outFile);
+ if (mode == TCL_MODE_BLOCKING) {
+ curStatus = 0;
+ } else {
+ curStatus = 1;
+ }
+ if (ioctl(fd, (int) FIONBIO, &curStatus) < 0) {
+ return errno;
+ }
}
#endif /* USE_FIONBIO */
@@ -893,8 +892,8 @@ PipeBlockModeProc(instanceData, mode)
* PipeCloseProc --
*
* This procedure is invoked by the generic IO level to perform
- * channel-type-specific cleanup when a command pipeline channel
- * is closed.
+ * channel-type-specific cleanup when a command pipeline channel is
+ * closed.
*
* Results:
* 0 on success, errno otherwise.
@@ -930,42 +929,40 @@ PipeCloseProc(instanceData, interp)
}
if (pipePtr->isNonBlocking || TclInExit()) {
-
/*
- * If the channel is non-blocking or Tcl is being cleaned up, just
- * detach the children PIDs, reap them (important if we are in a
- * dynamic load module), and discard the errorFile.
- */
-
- Tcl_DetachPids(pipePtr->numPids, pipePtr->pidPtr);
- Tcl_ReapDetachedProcs();
-
- if (pipePtr->errorFile) {
+ * If the channel is non-blocking or Tcl is being cleaned up, just
+ * detach the children PIDs, reap them (important if we are in a
+ * dynamic load module), and discard the errorFile.
+ */
+
+ Tcl_DetachPids(pipePtr->numPids, pipePtr->pidPtr);
+ Tcl_ReapDetachedProcs();
+
+ if (pipePtr->errorFile) {
TclpCloseFile(pipePtr->errorFile);
- }
+ }
} else {
-
/*
- * Wrap the error file into a channel and give it to the cleanup
- * routine.
- */
+ * Wrap the error file into a channel and give it to the cleanup
+ * routine.
+ */
- if (pipePtr->errorFile) {
+ if (pipePtr->errorFile) {
errChan = Tcl_MakeFileChannel(
(ClientData) GetFd(pipePtr->errorFile), TCL_READABLE);
- } else {
- errChan = NULL;
- }
- result = TclCleanupChildren(interp, pipePtr->numPids, pipePtr->pidPtr,
- errChan);
+ } else {
+ errChan = NULL;
+ }
+ result = TclCleanupChildren(interp, pipePtr->numPids, pipePtr->pidPtr,
+ errChan);
}
if (pipePtr->numPids != 0) {
- ckfree((char *) pipePtr->pidPtr);
+ ckfree((char *) pipePtr->pidPtr);
}
ckfree((char *) pipePtr);
if (errorCode == 0) {
- return result;
+ return result;
}
return errorCode;
}
@@ -975,8 +972,8 @@ PipeCloseProc(instanceData, interp)
*
* PipeInputProc --
*
- * This procedure is invoked from the generic IO level to read
- * input from a command pipeline based channel.
+ * This procedure is invoked from the generic IO level to read input from
+ * a command pipeline based channel.
*
* Results:
* The number of bytes read is returned or -1 on error. An output
@@ -990,29 +987,28 @@ PipeCloseProc(instanceData, interp)
static int
PipeInputProc(instanceData, buf, toRead, errorCodePtr)
- ClientData instanceData; /* Pipe state. */
- char *buf; /* Where to store data read. */
- int toRead; /* How much space is available
- * in the buffer? */
- int *errorCodePtr; /* Where to store error code. */
+ ClientData instanceData; /* Pipe state. */
+ char *buf; /* Where to store data read. */
+ int toRead; /* How much space is available in the
+ * buffer? */
+ int *errorCodePtr; /* Where to store error code. */
{
PipeState *psPtr = (PipeState *) instanceData;
- int bytesRead; /* How many bytes were actually
- * read from the input device? */
+ int bytesRead; /* How many bytes were actually read from the
+ * input device? */
*errorCodePtr = 0;
-
+
/*
* Assume there is always enough input available. This will block
* appropriately, and read will unblock as soon as a short read is
* possible, if the channel is in blocking mode. If the channel is
- * nonblocking, the read will never block.
- * Some OSes can throw an interrupt error, for which we should
- * immediately retry. [Bug #415131]
+ * nonblocking, the read will never block. Some OSes can throw an
+ * interrupt error, for which we should immediately retry. [Bug #415131]
*/
do {
- bytesRead = read (GetFd(psPtr->inFile), buf, (size_t) toRead);
+ bytesRead = read(GetFd(psPtr->inFile), buf, (size_t) toRead);
} while ((bytesRead < 0) && (errno == EINTR));
if (bytesRead < 0) {
@@ -1028,13 +1024,12 @@ PipeInputProc(instanceData, buf, toRead, errorCodePtr)
*
* PipeOutputProc--
*
- * This procedure is invoked from the generic IO level to write
- * output to a command pipeline based channel.
+ * This procedure is invoked from the generic IO level to write output to
+ * a command pipeline based channel.
*
* Results:
- * The number of bytes written is returned or -1 on error. An
- * output argument contains a POSIX error code if an error occurred,
- * or zero.
+ * The number of bytes written is returned or -1 on error. An output
+ * argument contains a POSIX error code if an error occurred, or zero.
*
* Side effects:
* Writes output on the output device of the channel.
@@ -1044,10 +1039,10 @@ PipeInputProc(instanceData, buf, toRead, errorCodePtr)
static int
PipeOutputProc(instanceData, buf, toWrite, errorCodePtr)
- ClientData instanceData; /* Pipe state. */
- CONST char *buf; /* The data buffer. */
- int toWrite; /* How many bytes to write? */
- int *errorCodePtr; /* Where to store error code. */
+ ClientData instanceData; /* Pipe state. */
+ CONST char *buf; /* The data buffer. */
+ int toWrite; /* How many bytes to write? */
+ int *errorCodePtr; /* Where to store error code. */
{
PipeState *psPtr = (PipeState *) instanceData;
int written;
@@ -1055,8 +1050,8 @@ PipeOutputProc(instanceData, buf, toWrite, errorCodePtr)
*errorCodePtr = 0;
/*
- * Some OSes can throw an interrupt error, for which we should
- * immediately retry. [Bug #415131]
+ * Some OSes can throw an interrupt error, for which we should immediately
+ * retry. [Bug #415131]
*/
do {
@@ -1082,18 +1077,18 @@ PipeOutputProc(instanceData, buf, toWrite, errorCodePtr)
* None.
*
* Side effects:
- * Sets up the notifier so that a future event on the channel will
- * be seen by Tcl.
+ * Sets up the notifier so that a future event on the channel will be
+ * seen by Tcl.
*
*----------------------------------------------------------------------
*/
static void
PipeWatchProc(instanceData, mask)
- ClientData instanceData; /* The pipe state. */
- int mask; /* Events of interest; an OR-ed
- * combination of TCL_READABLE,
- * TCL_WRITABEL and TCL_EXCEPTION. */
+ ClientData instanceData; /* The pipe state. */
+ int mask; /* Events of interest; an OR-ed combination of
+ * TCL_READABLE, TCL_WRITABLE and
+ * TCL_EXCEPTION. */
{
PipeState *psPtr = (PipeState *) instanceData;
int newmask;
@@ -1125,12 +1120,12 @@ PipeWatchProc(instanceData, mask)
*
* PipeGetHandleProc --
*
- * Called from Tcl_GetChannelHandle to retrieve OS handles from
- * inside a command pipeline based channel.
+ * Called from Tcl_GetChannelHandle to retrieve OS handles from inside a
+ * command pipeline based channel.
*
* Results:
- * Returns TCL_OK with the fd in handlePtr, or TCL_ERROR if
- * there is no handle for the specified direction.
+ * Returns TCL_OK with the fd in handlePtr, or TCL_ERROR if there is no
+ * handle for the specified direction.
*
* Side effects:
* None.
@@ -1196,8 +1191,8 @@ Tcl_WaitPid(pid, statPtr, options)
*
* Tcl_PidObjCmd --
*
- * This procedure is invoked to process the "pid" Tcl command.
- * See the user documentation for details on what it does.
+ * This procedure is invoked to process the "pid" Tcl command. See the
+ * user documentation for details on what it does.
*
* Results:
* A standard Tcl result.
@@ -1216,12 +1211,6 @@ Tcl_PidObjCmd(dummy, interp, objc, objv)
int objc; /* Number of arguments. */
Tcl_Obj *CONST *objv; /* Argument strings. */
{
- Tcl_Channel chan;
- Tcl_ChannelType *chanTypePtr;
- PipeState *pipePtr;
- int i;
- Tcl_Obj *resultPtr, *longObjPtr;
-
if (objc > 2) {
Tcl_WrongNumArgs(interp, 1, objv, "?channelId?");
return TCL_ERROR;
@@ -1229,17 +1218,23 @@ Tcl_PidObjCmd(dummy, interp, objc, objv)
if (objc == 1) {
Tcl_SetObjResult(interp, Tcl_NewLongObj((long) getpid()));
} else {
- chan = Tcl_GetChannel(interp, Tcl_GetString(objv[1]), NULL);
- if (chan == (Tcl_Channel) NULL) {
+ Tcl_Channel chan;
+ Tcl_ChannelType *chanTypePtr;
+ PipeState *pipePtr;
+ int i;
+ Tcl_Obj *resultPtr, *longObjPtr;
+
+ chan = Tcl_GetChannel(interp, Tcl_GetString(objv[1]), NULL);
+ if (chan == (Tcl_Channel) NULL) {
return TCL_ERROR;
}
chanTypePtr = Tcl_GetChannelType(chan);
if (chanTypePtr != &pipeChannelType) {
return TCL_OK;
}
- pipePtr = (PipeState *) Tcl_GetChannelInstanceData(chan);
+ pipePtr = (PipeState *) Tcl_GetChannelInstanceData(chan);
resultPtr = Tcl_NewObj();
- for (i = 0; i < pipePtr->numPids; i++) {
+ for (i = 0; i < pipePtr->numPids; i++) {
longObjPtr = Tcl_NewLongObj((long) TclpGetPid(pipePtr->pidPtr[i]));
Tcl_ListObjAppendElement(NULL, resultPtr, longObjPtr);
}
@@ -1258,7 +1253,8 @@ Tcl_PidObjCmd(dummy, interp, objc, objv)
* Results:
* None.
*
- * This procedure carries out no operation on Unix.
+ * Notes:
+ * This procedure carries out no operation on Unix.
*
*----------------------------------------------------------------------
*/
@@ -1267,4 +1263,11 @@ void
TclpFinalizePipes()
{
}
-
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/unix/tclXtNotify.c b/unix/tclXtNotify.c
index 0d13d15..05b854e 100644
--- a/unix/tclXtNotify.c
+++ b/unix/tclXtNotify.c
@@ -1,31 +1,32 @@
-/*
+/*
* tclXtNotify.c --
*
- * This file contains the notifier driver implementation for the
- * Xt intrinsics.
+ * This file contains the notifier driver implementation for the Xt
+ * intrinsics.
*
* Copyright (c) 1997 by Sun Microsystems, Inc.
*
- * See the file "license.terms" for information on usage and redistribution
- * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclXtNotify.c,v 1.6 2004/04/06 22:25:57 dgp Exp $
+ * RCS: @(#) $Id: tclXtNotify.c,v 1.7 2005/07/24 22:56:45 dkf Exp $
*/
#include <X11/Intrinsic.h>
#include "tclInt.h"
/*
- * This structure is used to keep track of the notifier info for a
- * a registered file.
+ * This structure is used to keep track of the notifier info for a a
+ * registered file.
*/
typedef struct FileHandler {
int fd;
- int mask; /* Mask of desired events: TCL_READABLE, etc. */
- int readyMask; /* Events that have been seen since the
- last time FileHandlerEventProc was called
- for this file. */
+ int mask; /* Mask of desired events: TCL_READABLE,
+ * etc. */
+ int readyMask; /* Events that have been seen since the last
+ * time FileHandlerEventProc was called for
+ * this file. */
XtInputId read; /* Xt read callback handle. */
XtInputId write; /* Xt write callback handle. */
XtInputId except; /* Xt exception callback handle. */
@@ -36,33 +37,32 @@ typedef struct FileHandler {
} FileHandler;
/*
- * The following structure is what is added to the Tcl event queue when
- * file handlers are ready to fire.
+ * The following structure is what is added to the Tcl event queue when file
+ * handlers are ready to fire.
*/
typedef struct FileHandlerEvent {
- Tcl_Event header; /* Information that is standard for
- * all events. */
- int fd; /* File descriptor that is ready. Used
- * to find the FileHandler structure for
- * the file (can't point directly to the
- * FileHandler structure because it could
- * go away while the event is queued). */
+ Tcl_Event header; /* Information that is standard for all
+ * events. */
+ int fd; /* File descriptor that is ready. Used to find
+ * the FileHandler structure for the file
+ * (can't point directly to the FileHandler
+ * structure because it could go away while
+ * the event is queued). */
} FileHandlerEvent;
/*
- * The following static structure contains the state information for the
- * Xt based implementation of the Tcl notifier.
+ * The following static structure contains the state information for the Xt
+ * based implementation of the Tcl notifier.
*/
static struct NotifierState {
- XtAppContext appContext; /* The context used by the Xt
- * notifier. Can be set with
- * TclSetAppContext. */
- int appContextCreated; /* Was it created by us? */
- XtIntervalId currentTimeout; /* Handle of current timer. */
- FileHandler *firstFileHandlerPtr; /* Pointer to head of file handler
- * list. */
+ XtAppContext appContext; /* The context used by the Xt notifier. Can be
+ * set with TclSetAppContext. */
+ int appContextCreated; /* Was it created by us? */
+ XtIntervalId currentTimeout;/* Handle of current timer. */
+ FileHandler *firstFileHandlerPtr;
+ /* Pointer to head of file handler list. */
} notifier;
/*
@@ -84,7 +84,7 @@ static void NotifierExitHandler _ANSI_ARGS_((
ClientData clientData));
static void TimerProc _ANSI_ARGS_((caddr_t clientData,
XtIntervalId *id));
-static void CreateFileHandler _ANSI_ARGS_((int fd, int mask,
+static void CreateFileHandler _ANSI_ARGS_((int fd, int mask,
Tcl_FileProc * proc, ClientData clientData));
static void DeleteFileHandler _ANSI_ARGS_((int fd));
static void SetTimer _ANSI_ARGS_((Tcl_Time * timePtr));
@@ -107,18 +107,18 @@ EXTERN XtAppContext TclSetAppContext _ANSI_ARGS_((XtAppContext ctx));
* None.
*
* Side effects:
- * Sets the application context used by the notifier. Panics if
- * the context is already set when called.
+ * Sets the application context used by the notifier. Panics if the
+ * context is already set when called.
*
*----------------------------------------------------------------------
*/
XtAppContext
TclSetAppContext(appContext)
- XtAppContext appContext;
+ XtAppContext appContext;
{
if (!initialized) {
- InitNotifier();
+ InitNotifier();
}
/*
@@ -126,46 +126,41 @@ TclSetAppContext(appContext)
* new context. If so, we panic because we try to prevent switching
* contexts by mistake. Otherwise, we return the one we have.
*/
-
- if (notifier.appContext != NULL) {
- if (appContext != NULL) {
+ if (notifier.appContext != NULL) {
+ if (appContext != NULL) {
/*
- * We already have a context. We do not allow switching contexts
- * after initialization, so we panic.
- */
-
- Tcl_Panic("TclSetAppContext: multiple application contexts");
+ * We already have a context. We do not allow switching contexts
+ * after initialization, so we panic.
+ */
- }
+ Tcl_Panic("TclSetAppContext: multiple application contexts");
+ }
} else {
+ /*
+ * If we get here we have not yet gotten a context, so either create
+ * one or use the one supplied by our caller.
+ */
- /*
- * If we get here we have not yet gotten a context, so either create
- * one or use the one supplied by our caller.
- */
-
- if (appContext == NULL) {
-
+ if (appContext == NULL) {
/*
- * We must create a new context and tell our caller what it is, so
- * she can use it too.
- */
-
- notifier.appContext = XtCreateApplicationContext();
- notifier.appContextCreated = 1;
- } else {
+ * We must create a new context and tell our caller what it is, so
+ * she can use it too.
+ */
+ notifier.appContext = XtCreateApplicationContext();
+ notifier.appContextCreated = 1;
+ } else {
/*
- * Otherwise we remember the context that our caller gave us
- * and use it.
- */
-
- notifier.appContextCreated = 0;
- notifier.appContext = appContext;
- }
+ * Otherwise we remember the context that our caller gave us and
+ * use it.
+ */
+
+ notifier.appContextCreated = 0;
+ notifier.appContext = appContext;
+ }
}
-
+
return notifier.appContext;
}
@@ -189,14 +184,15 @@ void
InitNotifier()
{
Tcl_NotifierProcs notifier;
+
/*
- * Only reinitialize if we are not in exit handling. The notifier
- * can get reinitialized after its own exit handler has run, because
- * of exit handlers for the I/O and timer sub-systems (order dependency).
+ * Only reinitialize if we are not in exit handling. The notifier can get
+ * reinitialized after its own exit handler has run, because of exit
+ * handlers for the I/O and timer sub-systems (order dependency).
*/
if (TclInExit()) {
- return;
+ return;
}
notifier.createFileHandlerProc = CreateFileHandler;
@@ -209,7 +205,7 @@ InitNotifier()
* DO NOT create the application context yet; doing so would prevent
* external applications from setting it for us to their own ones.
*/
-
+
initialized = 1;
memset(&notifier, 0, sizeof(notifier));
Tcl_CreateExitHandler(NotifierExitHandler, NULL);
@@ -220,8 +216,8 @@ InitNotifier()
*
* NotifierExitHandler --
*
- * This function is called to cleanup the notifier state before
- * Tcl is unloaded.
+ * This function is called to cleanup the notifier state before Tcl is
+ * unloaded.
*
* Results:
* None.
@@ -237,15 +233,15 @@ NotifierExitHandler(
ClientData clientData) /* Not used. */
{
if (notifier.currentTimeout != 0) {
- XtRemoveTimeOut(notifier.currentTimeout);
+ XtRemoveTimeOut(notifier.currentTimeout);
}
for (; notifier.firstFileHandlerPtr != NULL; ) {
- Tcl_DeleteFileHandler(notifier.firstFileHandlerPtr->fd);
+ Tcl_DeleteFileHandler(notifier.firstFileHandlerPtr->fd);
}
if (notifier.appContextCreated) {
- XtDestroyApplicationContext(notifier.appContext);
- notifier.appContextCreated = 0;
- notifier.appContext = NULL;
+ XtDestroyApplicationContext(notifier.appContext);
+ notifier.appContextCreated = 0;
+ notifier.appContext = NULL;
}
initialized = 0;
}
@@ -282,9 +278,8 @@ SetTimer(timePtr)
}
if (timePtr) {
timeout = timePtr->sec * 1000 + timePtr->usec / 1000;
- notifier.currentTimeout =
- XtAppAddTimeOut(notifier.appContext, (unsigned long) timeout,
- TimerProc, NULL);
+ notifier.currentTimeout = XtAppAddTimeOut(notifier.appContext,
+ (unsigned long) timeout, TimerProc, NULL);
} else {
notifier.currentTimeout = 0;
}
@@ -295,14 +290,13 @@ SetTimer(timePtr)
*
* TimerProc --
*
- * This procedure is the XtTimerCallbackProc used to handle
- * timeouts.
+ * This procedure is the XtTimerCallbackProc used to handle timeouts.
*
* Results:
* None.
*
* Side effects:
- * Processes all queued events.
+ * Processes all queued events.
*
*----------------------------------------------------------------------
*/
@@ -331,8 +325,8 @@ TimerProc(data, id)
* None.
*
* Side effects:
- * Creates a new file handler structure and registers one or more
- * input procedures with Xt.
+ * Creates a new file handler structure and registers one or more input
+ * procedures with Xt.
*
*----------------------------------------------------------------------
*/
@@ -341,11 +335,11 @@ static void
CreateFileHandler(fd, mask, proc, clientData)
int fd; /* Handle of stream to watch. */
int mask; /* OR'ed combination of TCL_READABLE,
- * TCL_WRITABLE, and TCL_EXCEPTION:
- * indicates conditions under which
- * proc should be called. */
- Tcl_FileProc *proc; /* Procedure to call for each
- * selected event. */
+ * TCL_WRITABLE, and TCL_EXCEPTION: indicates
+ * conditions under which proc should be
+ * called. */
+ Tcl_FileProc *proc; /* Procedure to call for each selected
+ * event. */
ClientData clientData; /* Arbitrary data to pass to proc. */
{
FileHandler *filePtr;
@@ -382,9 +376,8 @@ CreateFileHandler(fd, mask, proc, clientData)
if (mask & TCL_READABLE) {
if (!(filePtr->mask & TCL_READABLE)) {
- filePtr->read =
- XtAppAddInput(notifier.appContext, fd, XtInputReadMask,
- FileProc, filePtr);
+ filePtr->read = XtAppAddInput(notifier.appContext, fd,
+ XtInputReadMask, FileProc, filePtr);
}
} else {
if (filePtr->mask & TCL_READABLE) {
@@ -393,9 +386,8 @@ CreateFileHandler(fd, mask, proc, clientData)
}
if (mask & TCL_WRITABLE) {
if (!(filePtr->mask & TCL_WRITABLE)) {
- filePtr->write =
- XtAppAddInput(notifier.appContext, fd, XtInputWriteMask,
- FileProc, filePtr);
+ filePtr->write = XtAppAddInput(notifier.appContext, fd,
+ XtInputWriteMask, FileProc, filePtr);
}
} else {
if (filePtr->mask & TCL_WRITABLE) {
@@ -404,9 +396,8 @@ CreateFileHandler(fd, mask, proc, clientData)
}
if (mask & TCL_EXCEPTION) {
if (!(filePtr->mask & TCL_EXCEPTION)) {
- filePtr->except =
- XtAppAddInput(notifier.appContext, fd, XtInputExceptMask,
- FileProc, filePtr);
+ filePtr->except = XtAppAddInput(notifier.appContext, fd,
+ XtInputExceptMask, FileProc, filePtr);
}
} else {
if (filePtr->mask & TCL_EXCEPTION) {
@@ -421,8 +412,7 @@ CreateFileHandler(fd, mask, proc, clientData)
*
* DeleteFileHandler --
*
- * Cancel a previously-arranged callback arrangement for
- * a file.
+ * Cancel a previously-arranged callback arrangement for a file.
*
* Results:
* None.
@@ -435,8 +425,8 @@ CreateFileHandler(fd, mask, proc, clientData)
static void
DeleteFileHandler(fd)
- int fd; /* Stream id for which to remove
- * callback procedure. */
+ int fd; /* Stream id for which to remove callback
+ * procedure. */
{
FileHandler *filePtr, *prevPtr;
@@ -447,8 +437,7 @@ DeleteFileHandler(fd)
TclSetAppContext(NULL);
/*
- * Find the entry for the given file (and return if there
- * isn't one).
+ * Find the entry for the given file (and return if there isn't one).
*/
for (prevPtr = NULL, filePtr = notifier.firstFileHandlerPtr; ;
@@ -494,8 +483,7 @@ DeleteFileHandler(fd)
* None.
*
* Side effects:
- * Makes an entry on the Tcl event queue if the event is
- * interesting.
+ * Makes an entry on the Tcl event queue if the event is interesting.
*
*----------------------------------------------------------------------
*/
@@ -529,7 +517,7 @@ FileProc(clientData, fd, id)
if (!(filePtr->mask & mask) || (filePtr->readyMask & mask)) {
return;
}
-
+
/*
* This is an interesting event, so put it onto the event queue.
*/
@@ -552,16 +540,16 @@ FileProc(clientData, fd, id)
*
* FileHandlerEventProc --
*
- * This procedure is called by Tcl_ServiceEvent when a file event
- * reaches the front of the event queue. This procedure is
- * responsible for actually handling the event by invoking the
- * callback for the file handler.
+ * This procedure is called by Tcl_ServiceEvent when a file event reaches
+ * the front of the event queue. This procedure is responsible for
+ * actually handling the event by invoking the callback for the file
+ * handler.
*
* Results:
- * Returns 1 if the event was handled, meaning it should be removed
- * from the queue. Returns 0 if the event was not handled, meaning
- * it should stay on the queue. The only time the event isn't
- * handled is if the TCL_FILE_EVENTS flag bit isn't set.
+ * Returns 1 if the event was handled, meaning it should be removed from
+ * the queue. Returns 0 if the event was not handled, meaning it should
+ * stay on the queue. The only time the event isn't handled is if the
+ * TCL_FILE_EVENTS flag bit isn't set.
*
* Side effects:
* Whatever the file handler's callback procedure does.
@@ -572,8 +560,8 @@ FileProc(clientData, fd, id)
static int
FileHandlerEventProc(evPtr, flags)
Tcl_Event *evPtr; /* Event to service. */
- int flags; /* Flags that indicate what events to
- * handle, such as TCL_FILE_EVENTS. */
+ int flags; /* Flags that indicate what events to handle,
+ * such as TCL_FILE_EVENTS. */
{
FileHandler *filePtr;
FileHandlerEvent *fileEvPtr = (FileHandlerEvent *) evPtr;
@@ -585,9 +573,9 @@ FileHandlerEventProc(evPtr, flags)
/*
* Search through the file handlers to find the one whose handle matches
- * the event. We do this rather than keeping a pointer to the file
- * handler directly in the event, so that the handler can be deleted
- * while the event is queued without leaving a dangling pointer.
+ * the event. We do this rather than keeping a pointer to the file handler
+ * directly in the event, so that the handler can be deleted while the
+ * event is queued without leaving a dangling pointer.
*/
for (filePtr = notifier.firstFileHandlerPtr; filePtr != NULL;
@@ -598,14 +586,14 @@ FileHandlerEventProc(evPtr, flags)
/*
* The code is tricky for two reasons:
- * 1. The file handler's desired events could have changed
- * since the time when the event was queued, so AND the
- * ready mask with the desired mask.
- * 2. The file could have been closed and re-opened since
- * the time when the event was queued. This is why the
- * ready mask is stored in the file handler rather than
- * the queued event: it will be zeroed when a new
- * file handler is created for the newly opened file.
+ * 1. The file handler's desired events could have changed since the
+ * time when the event was queued, so AND the ready mask with the
+ * desired mask.
+ * 2. The file could have been closed and re-opened since the time
+ * when the event was queued. This is why the ready mask is stored
+ * in the file handler rather than the queued event: it will be
+ * zeroed when a new file handler is created for the newly opened
+ * file.
*/
mask = filePtr->readyMask & filePtr->mask;
@@ -623,14 +611,14 @@ FileHandlerEventProc(evPtr, flags)
*
* WaitForEvent --
*
- * This function is called by Tcl_DoOneEvent to wait for new
- * events on the message queue. If the block time is 0, then
- * Tcl_WaitForEvent just polls without blocking.
+ * This function is called by Tcl_DoOneEvent to wait for new events on
+ * the message queue. If the block time is 0, then Tcl_WaitForEvent just
+ * polls without blocking.
*
* Results:
- * Returns 1 if an event was found, else 0. This ensures that
- * Tcl_DoOneEvent will return 1, even if the event is handled
- * by non-Tcl code.
+ * Returns 1 if an event was found, else 0. This ensures that
+ * Tcl_DoOneEvent will return 1, even if the event is handled by non-Tcl
+ * code.
*
* Side effects:
* Queues file events that are detected by the select.
@@ -651,18 +639,27 @@ WaitForEvent(
TclSetAppContext(NULL);
if (timePtr) {
- timeout = timePtr->sec * 1000 + timePtr->usec / 1000;
- if (timeout == 0) {
- if (XtAppPending(notifier.appContext)) {
- goto process;
- } else {
- return 0;
- }
- } else {
- Tcl_SetTimer(timePtr);
- }
+ timeout = timePtr->sec * 1000 + timePtr->usec / 1000;
+ if (timeout == 0) {
+ if (XtAppPending(notifier.appContext)) {
+ goto process;
+ } else {
+ return 0;
+ }
+ } else {
+ Tcl_SetTimer(timePtr);
+ }
}
-process:
+
+ process:
XtAppProcessEvent(notifier.appContext, XtIMAll);
return 1;
}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */