|
Packit |
a69f91 |
/*
|
|
Packit |
a69f91 |
* tclUnixNotify.c --
|
|
Packit |
a69f91 |
*
|
|
Packit |
a69f91 |
* This file contains Unix-specific procedures for the notifier,
|
|
Packit |
a69f91 |
* which is the lowest-level part of the Tcl event loop. This file
|
|
Packit |
a69f91 |
* works together with ../generic/tclNotify.c.
|
|
Packit |
a69f91 |
*
|
|
Packit |
a69f91 |
* Copyright (c) 1995 Sun Microsystems, Inc.
|
|
Packit |
a69f91 |
*
|
|
Packit |
a69f91 |
* See the file "license.terms" for information on usage and redistribution
|
|
Packit |
a69f91 |
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
|
|
Packit |
a69f91 |
*/
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
static char sccsid[] = "@(#) tclUnixNotify.c 1.27 96/01/19 10:30:23";
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
#include "tclInt.h"
|
|
Packit |
a69f91 |
#include "tclPort.h"
|
|
Packit |
a69f91 |
#include <signal.h>
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
/*
|
|
Packit |
a69f91 |
* The information below is used to provide read, write, and
|
|
Packit |
a69f91 |
* exception masks to select during calls to Tcl_DoOneEvent.
|
|
Packit |
a69f91 |
*/
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
static fd_mask checkMasks[3*MASK_SIZE];
|
|
Packit |
a69f91 |
/* This array is used to build up the masks
|
|
Packit |
a69f91 |
* to be used in the next call to select.
|
|
Packit |
a69f91 |
* Bits are set in response to calls to
|
|
Packit |
a69f91 |
* Tcl_WatchFile. */
|
|
Packit |
a69f91 |
static fd_mask readyMasks[3*MASK_SIZE];
|
|
Packit |
a69f91 |
/* This array reflects the readable/writable
|
|
Packit |
a69f91 |
* conditions that were found to exist by the
|
|
Packit |
a69f91 |
* last call to select. */
|
|
Packit |
a69f91 |
static int numFdBits; /* Number of valid bits in checkMasks
|
|
Packit |
a69f91 |
* (one more than highest fd for which
|
|
Packit |
a69f91 |
* Tcl_WatchFile has been called). */
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
/*
|
|
Packit |
a69f91 |
*----------------------------------------------------------------------
|
|
Packit |
a69f91 |
*
|
|
Packit |
a69f91 |
* Tcl_WatchFile --
|
|
Packit |
a69f91 |
*
|
|
Packit |
a69f91 |
* Arrange for Tcl_DoOneEvent to include this file in the masks
|
|
Packit |
a69f91 |
* for the next call to select. This procedure is invoked by
|
|
Packit |
a69f91 |
* event sources, which are in turn invoked by Tcl_DoOneEvent
|
|
Packit |
a69f91 |
* before it invokes select.
|
|
Packit |
a69f91 |
*
|
|
Packit |
a69f91 |
* Results:
|
|
Packit |
a69f91 |
* None.
|
|
Packit |
a69f91 |
*
|
|
Packit |
a69f91 |
* Side effects:
|
|
Packit |
a69f91 |
*
|
|
Packit |
a69f91 |
* The notifier will generate a file event when the I/O channel
|
|
Packit |
a69f91 |
* given by fd next becomes ready in the way indicated by mask.
|
|
Packit |
a69f91 |
* If fd is already registered then the old mask will be replaced
|
|
Packit |
a69f91 |
* with the new one. Once the event is sent, the notifier will
|
|
Packit |
a69f91 |
* not send any more events about the fd until the next call to
|
|
Packit |
a69f91 |
* Tcl_NotifyFile.
|
|
Packit |
a69f91 |
*
|
|
Packit |
a69f91 |
*----------------------------------------------------------------------
|
|
Packit |
a69f91 |
*/
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
void
|
|
Packit |
a69f91 |
Tcl_WatchFile(file, mask)
|
|
Packit |
a69f91 |
Tcl_File file; /* Generic file handle for a stream. */
|
|
Packit |
a69f91 |
int mask; /* OR'ed combination of TCL_READABLE,
|
|
Packit |
a69f91 |
* TCL_WRITABLE, and TCL_EXCEPTION:
|
|
Packit |
a69f91 |
* indicates conditions to wait for
|
|
Packit |
a69f91 |
* in select. */
|
|
Packit |
a69f91 |
{
|
|
Packit |
a69f91 |
int fd, type, index;
|
|
Packit |
a69f91 |
fd_mask bit;
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
fd = (int) Tcl_GetFileInfo(file, &type);
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
if (type != TCL_UNIX_FD) {
|
|
Packit |
a69f91 |
panic("Tcl_WatchFile: unexpected file type");
|
|
Packit |
a69f91 |
}
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
if (fd >= FD_SETSIZE) {
|
|
Packit |
a69f91 |
panic("Tcl_WatchFile can't handle file id %d", fd);
|
|
Packit |
a69f91 |
}
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
index = fd/(NBBY*sizeof(fd_mask));
|
|
Packit |
a69f91 |
bit = 1 << (fd%(NBBY*sizeof(fd_mask)));
|
|
Packit |
a69f91 |
if (mask & TCL_READABLE) {
|
|
Packit |
a69f91 |
checkMasks[index] |= bit;
|
|
Packit |
a69f91 |
}
|
|
Packit |
a69f91 |
if (mask & TCL_WRITABLE) {
|
|
Packit |
a69f91 |
(checkMasks+MASK_SIZE)[index] |= bit;
|
|
Packit |
a69f91 |
}
|
|
Packit |
a69f91 |
if (mask & TCL_EXCEPTION) {
|
|
Packit |
a69f91 |
(checkMasks+2*(MASK_SIZE))[index] |= bit;
|
|
Packit |
a69f91 |
}
|
|
Packit |
a69f91 |
if (numFdBits <= fd) {
|
|
Packit |
a69f91 |
numFdBits = fd+1;
|
|
Packit |
a69f91 |
}
|
|
Packit |
a69f91 |
}
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
/*
|
|
Packit |
a69f91 |
*----------------------------------------------------------------------
|
|
Packit |
a69f91 |
*
|
|
Packit |
a69f91 |
* Tcl_FileReady --
|
|
Packit |
a69f91 |
*
|
|
Packit |
a69f91 |
* Indicates what conditions (readable, writable, etc.) were
|
|
Packit |
a69f91 |
* present on a file the last time the notifier invoked select.
|
|
Packit |
a69f91 |
* This procedure is typically invoked by event sources to see
|
|
Packit |
a69f91 |
* if they should queue events.
|
|
Packit |
a69f91 |
*
|
|
Packit |
a69f91 |
* Results:
|
|
Packit |
a69f91 |
* The return value is 0 if none of the conditions specified by mask
|
|
Packit |
a69f91 |
* was true for fd the last time the system checked. If any of the
|
|
Packit |
a69f91 |
* conditions were true, then the return value is a mask of those
|
|
Packit |
a69f91 |
* that were true.
|
|
Packit |
a69f91 |
*
|
|
Packit |
a69f91 |
* Side effects:
|
|
Packit |
a69f91 |
* None.
|
|
Packit |
a69f91 |
*
|
|
Packit |
a69f91 |
*----------------------------------------------------------------------
|
|
Packit |
a69f91 |
*/
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
int
|
|
Packit |
a69f91 |
Tcl_FileReady(file, mask)
|
|
Packit |
a69f91 |
Tcl_File file; /* Generic file handle for a stream. */
|
|
Packit |
a69f91 |
int mask; /* OR'ed combination of TCL_READABLE,
|
|
Packit |
a69f91 |
* TCL_WRITABLE, and TCL_EXCEPTION:
|
|
Packit |
a69f91 |
* indicates conditions caller cares about. */
|
|
Packit |
a69f91 |
{
|
|
Packit |
a69f91 |
int index, result, type, fd;
|
|
Packit |
a69f91 |
fd_mask bit;
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
fd = (int) Tcl_GetFileInfo(file, &type);
|
|
Packit |
a69f91 |
if (type != TCL_UNIX_FD) {
|
|
Packit |
a69f91 |
panic("Tcl_FileReady: unexpected file type");
|
|
Packit |
a69f91 |
}
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
index = fd/(NBBY*sizeof(fd_mask));
|
|
Packit |
a69f91 |
bit = 1 << (fd%(NBBY*sizeof(fd_mask)));
|
|
Packit |
a69f91 |
result = 0;
|
|
Packit |
a69f91 |
if ((mask & TCL_READABLE) && (readyMasks[index] & bit)) {
|
|
Packit |
a69f91 |
result |= TCL_READABLE;
|
|
Packit |
a69f91 |
}
|
|
Packit |
a69f91 |
if ((mask & TCL_WRITABLE) && ((readyMasks+MASK_SIZE)[index] & bit)) {
|
|
Packit |
a69f91 |
result |= TCL_WRITABLE;
|
|
Packit |
a69f91 |
}
|
|
Packit |
a69f91 |
if ((mask & TCL_EXCEPTION) && ((readyMasks+(2*MASK_SIZE))[index] & bit)) {
|
|
Packit |
a69f91 |
result |= TCL_EXCEPTION;
|
|
Packit |
a69f91 |
}
|
|
Packit |
a69f91 |
return result;
|
|
Packit |
a69f91 |
}
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
/*
|
|
Packit |
a69f91 |
*----------------------------------------------------------------------
|
|
Packit |
a69f91 |
*
|
|
Packit |
a69f91 |
* Tcl_WaitForEvent --
|
|
Packit |
a69f91 |
*
|
|
Packit |
a69f91 |
* This procedure does the lowest level wait for events in a
|
|
Packit |
a69f91 |
* platform-specific manner. It uses information provided by
|
|
Packit |
a69f91 |
* previous calls to Tcl_WatchFile, plus the timePtr argument,
|
|
Packit |
a69f91 |
* to determine what to wait for and how long to wait.
|
|
Packit |
a69f91 |
*
|
|
Packit |
a69f91 |
* Results:
|
|
Packit |
a69f91 |
* None.
|
|
Packit |
a69f91 |
*
|
|
Packit |
a69f91 |
* Side effects:
|
|
Packit |
a69f91 |
* May put the process to sleep for a while, depending on timePtr.
|
|
Packit |
a69f91 |
* When this procedure returns, an event of interest to the application
|
|
Packit |
a69f91 |
* has probably, but not necessarily, occurred.
|
|
Packit |
a69f91 |
*
|
|
Packit |
a69f91 |
*----------------------------------------------------------------------
|
|
Packit |
a69f91 |
*/
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
void
|
|
Packit |
a69f91 |
Tcl_WaitForEvent(timePtr)
|
|
Packit |
a69f91 |
Tcl_Time *timePtr; /* Specifies the maximum amount of time
|
|
Packit |
a69f91 |
* that this procedure should block before
|
|
Packit |
a69f91 |
* returning. The time is given as an
|
|
Packit |
a69f91 |
* interval, not an absolute wakeup time.
|
|
Packit |
a69f91 |
* NULL means block forever. */
|
|
Packit |
a69f91 |
{
|
|
Packit |
a69f91 |
struct timeval timeout, *timeoutPtr;
|
|
Packit |
a69f91 |
int numFound;
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
memcpy((VOID *) readyMasks, (VOID *) checkMasks,
|
|
Packit |
a69f91 |
3*MASK_SIZE*sizeof(fd_mask));
|
|
Packit |
a69f91 |
if (timePtr == NULL) {
|
|
Packit |
a69f91 |
timeoutPtr = NULL;
|
|
Packit |
a69f91 |
} else {
|
|
Packit |
a69f91 |
timeoutPtr = &timeout;
|
|
Packit |
a69f91 |
timeout.tv_sec = timePtr->sec;
|
|
Packit |
a69f91 |
timeout.tv_usec = timePtr->usec;
|
|
Packit |
a69f91 |
}
|
|
Packit |
a69f91 |
numFound = select(numFdBits, (SELECT_MASK *) &readyMasks[0],
|
|
Packit |
a69f91 |
(SELECT_MASK *) &readyMasks[MASK_SIZE],
|
|
Packit |
a69f91 |
(SELECT_MASK *) &readyMasks[2*MASK_SIZE], timeoutPtr);
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
/*
|
|
Packit |
a69f91 |
* Some systems don't clear the masks after an error, so
|
|
Packit |
a69f91 |
* we have to do it here.
|
|
Packit |
a69f91 |
*/
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
if (numFound == -1) {
|
|
Packit |
a69f91 |
memset((VOID *) readyMasks, 0, 3*MASK_SIZE*sizeof(fd_mask));
|
|
Packit |
a69f91 |
}
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
/*
|
|
Packit |
a69f91 |
* Reset the check masks in preparation for the next call to
|
|
Packit |
a69f91 |
* select.
|
|
Packit |
a69f91 |
*/
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
numFdBits = 0;
|
|
Packit |
a69f91 |
memset((VOID *) checkMasks, 0, 3*MASK_SIZE*sizeof(fd_mask));
|
|
Packit |
a69f91 |
}
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
/*
|
|
Packit |
a69f91 |
*----------------------------------------------------------------------
|
|
Packit |
a69f91 |
*
|
|
Packit |
a69f91 |
* Tcl_Sleep --
|
|
Packit |
a69f91 |
*
|
|
Packit |
a69f91 |
* Delay execution for the specified number of milliseconds.
|
|
Packit |
a69f91 |
*
|
|
Packit |
a69f91 |
* Results:
|
|
Packit |
a69f91 |
* None.
|
|
Packit |
a69f91 |
*
|
|
Packit |
a69f91 |
* Side effects:
|
|
Packit |
a69f91 |
* Time passes.
|
|
Packit |
a69f91 |
*
|
|
Packit |
a69f91 |
*----------------------------------------------------------------------
|
|
Packit |
a69f91 |
*/
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
void
|
|
Packit |
a69f91 |
Tcl_Sleep(ms)
|
|
Packit |
a69f91 |
int ms; /* Number of milliseconds to sleep. */
|
|
Packit |
a69f91 |
{
|
|
Packit |
a69f91 |
static struct timeval delay;
|
|
Packit |
a69f91 |
Tcl_Time before, after;
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
/*
|
|
Packit |
a69f91 |
* The only trick here is that select appears to return early
|
|
Packit |
a69f91 |
* under some conditions, so we have to check to make sure that
|
|
Packit |
a69f91 |
* the right amount of time really has elapsed. If it's too
|
|
Packit |
a69f91 |
* early, go back to sleep again.
|
|
Packit |
a69f91 |
*/
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
TclGetTime(&before);
|
|
Packit |
a69f91 |
after = before;
|
|
Packit |
a69f91 |
after.sec += ms/1000;
|
|
Packit |
a69f91 |
after.usec += (ms%1000)*1000;
|
|
Packit |
a69f91 |
if (after.usec > 1000000) {
|
|
Packit |
a69f91 |
after.usec -= 1000000;
|
|
Packit |
a69f91 |
after.sec += 1;
|
|
Packit |
a69f91 |
}
|
|
Packit |
a69f91 |
while (1) {
|
|
Packit |
a69f91 |
delay.tv_sec = after.sec - before.sec;
|
|
Packit |
a69f91 |
delay.tv_usec = after.usec - before.usec;
|
|
Packit |
a69f91 |
if (delay.tv_usec < 0) {
|
|
Packit |
a69f91 |
delay.tv_usec += 1000000;
|
|
Packit |
a69f91 |
delay.tv_sec -= 1;
|
|
Packit |
a69f91 |
}
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
/*
|
|
Packit |
a69f91 |
* Special note: must convert delay.tv_sec to int before comparing
|
|
Packit |
a69f91 |
* to zero, since delay.tv_usec is unsigned on some platforms.
|
|
Packit |
a69f91 |
*/
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
if ((((int) delay.tv_sec) < 0)
|
|
Packit |
a69f91 |
|| ((delay.tv_usec == 0) && (delay.tv_sec == 0))) {
|
|
Packit |
a69f91 |
break;
|
|
Packit |
a69f91 |
}
|
|
Packit |
a69f91 |
(void) select(0, (SELECT_MASK *) 0, (SELECT_MASK *) 0,
|
|
Packit |
a69f91 |
(SELECT_MASK *) 0, &delay);
|
|
Packit |
a69f91 |
TclGetTime(&before);
|
|
Packit |
a69f91 |
}
|
|
Packit |
a69f91 |
}
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
#if 0 /* WHOLE FILE */
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
/* interact (with only one process) - give user keyboard control
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
Written by: Don Libes, NIST, 2/6/90
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
Design and implementation of this program was paid for by U.S. tax
|
|
Packit |
a69f91 |
dollars. Therefore it is public domain. However, the author and NIST
|
|
Packit |
a69f91 |
would appreciate credit if this program or parts of it are used.
|
|
Packit |
a69f91 |
*/
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
/* This file exists for deficient versions of UNIX that lack select,
|
|
Packit |
a69f91 |
poll, or some other multiplexing hook. Instead, this code uses two
|
|
Packit |
a69f91 |
processes per spawned process. One sends characters from the spawnee
|
|
Packit |
a69f91 |
to the spawner; a second send chars the other way.
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
This will work on any UNIX system. The only sacrifice is that it
|
|
Packit |
a69f91 |
doesn't support multiple processes. Eventually, it should catch
|
|
Packit |
a69f91 |
SIGCHLD on dead processes and do the right thing. But it is pretty
|
|
Packit |
a69f91 |
gruesome to imagine so many processes to do all this. If you change
|
|
Packit |
a69f91 |
it successfully, please mail back the changes to me. - Don
|
|
Packit |
a69f91 |
*/
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
#include "expect_cf.h"
|
|
Packit |
a69f91 |
#include <stdio.h>
|
|
Packit |
a69f91 |
#include <sys/types.h>
|
|
Packit |
a69f91 |
#include <sys/time.h>
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
#ifdef HAVE_SYS_WAIT_H
|
|
Packit |
a69f91 |
#include <sys/wait.h>
|
|
Packit |
a69f91 |
#endif
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
#include "tcl.h"
|
|
Packit |
a69f91 |
#include "exp_prog.h"
|
|
Packit |
a69f91 |
#include "exp_command.h" /* for struct ExpState defs */
|
|
Packit |
a69f91 |
#include "exp_event.h"
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
/*ARGSUSED*/
|
|
Packit |
a69f91 |
void
|
|
Packit |
a69f91 |
exp_arm_background_channelhandler(esPtr)
|
|
Packit |
a69f91 |
ExpState *esPtr;
|
|
Packit |
a69f91 |
{
|
|
Packit |
a69f91 |
}
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
/*ARGSUSED*/
|
|
Packit |
a69f91 |
void
|
|
Packit |
a69f91 |
exp_disarm_background_channelhandler(esPtr)
|
|
Packit |
a69f91 |
ExpState *esPtr;
|
|
Packit |
a69f91 |
{
|
|
Packit |
a69f91 |
}
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
/*ARGSUSED*/
|
|
Packit |
a69f91 |
void
|
|
Packit |
a69f91 |
exp_disarm_background_channelhandler_force(esPtr)
|
|
Packit |
a69f91 |
ExpState *esPtr;
|
|
Packit |
a69f91 |
{
|
|
Packit |
a69f91 |
}
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
/*ARGSUSED*/
|
|
Packit |
a69f91 |
void
|
|
Packit |
a69f91 |
exp_unblock_background_channelhandler(esPtr)
|
|
Packit |
a69f91 |
ExpState *esPtr;
|
|
Packit |
a69f91 |
{
|
|
Packit |
a69f91 |
}
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
/*ARGSUSED*/
|
|
Packit |
a69f91 |
void
|
|
Packit |
a69f91 |
exp_block_background_channelhandler(esPtr)
|
|
Packit |
a69f91 |
ExpState *esPtr;
|
|
Packit |
a69f91 |
{
|
|
Packit |
a69f91 |
}
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
/*ARGSUSED*/
|
|
Packit |
a69f91 |
void
|
|
Packit |
a69f91 |
exp_event_disarm(fd)
|
|
Packit |
a69f91 |
int fd;
|
|
Packit |
a69f91 |
{
|
|
Packit |
a69f91 |
}
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
/* returns status, one of EOF, TIMEOUT, ERROR or DATA */
|
|
Packit |
a69f91 |
/*ARGSUSED*/
|
|
Packit |
a69f91 |
int
|
|
Packit |
a69f91 |
exp_get_next_event(interp,esPtrs, n,esPtrOut,timeout,key)
|
|
Packit |
a69f91 |
Tcl_Interp *interp;
|
|
Packit |
a69f91 |
ExpState (*esPtrs)[];
|
|
Packit |
a69f91 |
int n; /* # of esPtrs */
|
|
Packit |
a69f91 |
ExpState **esPtrOut; /* 1st event master, not set if none */
|
|
Packit |
a69f91 |
int timeout; /* seconds */
|
|
Packit |
a69f91 |
int key;
|
|
Packit |
a69f91 |
{
|
|
Packit |
a69f91 |
ExpState *esPtr;
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
if (n > 1) {
|
|
Packit |
a69f91 |
exp_error(interp,"expect not compiled with multiprocess support");
|
|
Packit |
a69f91 |
/* select a different INTERACT_TYPE in Makefile */
|
|
Packit |
a69f91 |
return(TCL_ERROR);
|
|
Packit |
a69f91 |
}
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
esPtr = *esPtrOut = esPtrs[0];
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
if (esPtr->key != key) {
|
|
Packit |
a69f91 |
esPtr->key = key;
|
|
Packit |
a69f91 |
esPtr->force_read = FALSE;
|
|
Packit |
a69f91 |
return(EXP_DATA_OLD);
|
|
Packit |
a69f91 |
} else if ((!esPtr->force_read) && (esPtr->size != 0)) {
|
|
Packit |
a69f91 |
return(EXP_DATA_OLD);
|
|
Packit |
a69f91 |
}
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
return(EXP_DATA_NEW);
|
|
Packit |
a69f91 |
}
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
/*ARGSUSED*/
|
|
Packit |
a69f91 |
int
|
|
Packit |
a69f91 |
exp_get_next_event_info(interp,esPtr,ready_mask)
|
|
Packit |
a69f91 |
Tcl_Interp *interp;
|
|
Packit |
a69f91 |
ExpState *esPtr;
|
|
Packit |
a69f91 |
int ready_mask;
|
|
Packit |
a69f91 |
{
|
|
Packit |
a69f91 |
}
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
/* There is no portable way to do sub-second sleeps on such a system, so */
|
|
Packit |
a69f91 |
/* do the next best thing (without a busy loop) and fake it: sleep the right */
|
|
Packit |
a69f91 |
/* amount of time over the long run. Note that while "subtotal" isn't */
|
|
Packit |
a69f91 |
/* reinitialized, it really doesn't matter for such a gross hack as random */
|
|
Packit |
a69f91 |
/* scheduling pauses will easily introduce occasional one second delays. */
|
|
Packit |
a69f91 |
int /* returns TCL_XXX */
|
|
Packit |
a69f91 |
exp_dsleep(interp,sec)
|
|
Packit |
a69f91 |
Tcl_Interp *interp;
|
|
Packit |
a69f91 |
double sec;
|
|
Packit |
a69f91 |
{
|
|
Packit |
a69f91 |
static double subtotal = 0;
|
|
Packit |
a69f91 |
int seconds;
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
subtotal += sec;
|
|
Packit |
a69f91 |
if (subtotal < 1) return TCL_OK;
|
|
Packit |
a69f91 |
seconds = subtotal;
|
|
Packit |
a69f91 |
subtotal -= seconds;
|
|
Packit |
a69f91 |
restart:
|
|
Packit |
a69f91 |
if (Tcl_AsyncReady()) {
|
|
Packit |
a69f91 |
int rc = Tcl_AsyncInvoke(interp,TCL_OK);
|
|
Packit |
a69f91 |
if (rc != TCL_OK) return(rc);
|
|
Packit |
a69f91 |
}
|
|
Packit |
a69f91 |
sleep(seconds);
|
|
Packit |
a69f91 |
return TCL_OK;
|
|
Packit |
a69f91 |
}
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
#if 0
|
|
Packit |
a69f91 |
/* There is no portable way to do sub-second sleeps on such a system, so */
|
|
Packit |
a69f91 |
/* do the next best thing (without a busy loop) and fake it: sleep the right */
|
|
Packit |
a69f91 |
/* amount of time over the long run. Note that while "subtotal" isn't */
|
|
Packit |
a69f91 |
/* reinitialized, it really doesn't matter for such a gross hack as random */
|
|
Packit |
a69f91 |
/* scheduling pauses will easily introduce occasional one second delays. */
|
|
Packit |
a69f91 |
int /* returns TCL_XXX */
|
|
Packit |
a69f91 |
exp_usleep(interp,usec)
|
|
Packit |
a69f91 |
Tcl_Interp *interp;
|
|
Packit |
a69f91 |
long usec; /* microseconds */
|
|
Packit |
a69f91 |
{
|
|
Packit |
a69f91 |
static subtotal = 0;
|
|
Packit |
a69f91 |
int seconds;
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
subtotal += usec;
|
|
Packit |
a69f91 |
if (subtotal < 1000000) return TCL_OK;
|
|
Packit |
a69f91 |
seconds = subtotal/1000000;
|
|
Packit |
a69f91 |
subtotal = subtotal%1000000;
|
|
Packit |
a69f91 |
restart:
|
|
Packit |
a69f91 |
if (Tcl_AsyncReady()) {
|
|
Packit |
a69f91 |
int rc = Tcl_AsyncInvoke(interp,TCL_OK);
|
|
Packit |
a69f91 |
if (rc != TCL_OK) return(exp_tcl2_returnvalue(rc));
|
|
Packit |
a69f91 |
}
|
|
Packit |
a69f91 |
sleep(seconds);
|
|
Packit |
a69f91 |
return TCL_OK;
|
|
Packit |
a69f91 |
}
|
|
Packit |
a69f91 |
#endif /*0*/
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
/* set things up for later calls to event handler */
|
|
Packit |
a69f91 |
void
|
|
Packit |
a69f91 |
exp_init_event()
|
|
Packit |
a69f91 |
{
|
|
Packit |
a69f91 |
exp_event_exit = 0;
|
|
Packit |
a69f91 |
}
|
|
Packit |
a69f91 |
|
|
Packit |
a69f91 |
#endif /* WHOLE FILE! */
|