Exemplo n.º 1
0
void
InitNotifier(void)
{
    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).
     */

    if (TclInExit()) {
	return;
    }

    notifier.createFileHandlerProc = CreateFileHandler;
    notifier.deleteFileHandlerProc = DeleteFileHandler;
    notifier.setTimerProc = SetTimer;
    notifier.waitForEventProc = WaitForEvent;
    Tcl_SetNotifier(&notifier);

    /*
     * 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);
}
Exemplo n.º 2
0
	/* ARGSUSED */
static int
PipeCloseProc(
    ClientData instanceData,	/* The pipe to close. */
    Tcl_Interp *interp)		/* For error reporting. */
{
    PipeState *pipePtr;
    Tcl_Channel errChan;
    int errorCode, result;

    errorCode = 0;
    result = 0;
    pipePtr = (PipeState *) instanceData;
    if (pipePtr->inFile) {
	if (TclpCloseFile(pipePtr->inFile) < 0) {
	    errorCode = errno;
	}
    }
    if (pipePtr->outFile) {
	if ((TclpCloseFile(pipePtr->outFile) < 0) && (errorCode == 0)) {
	    errorCode = errno;
	}
    }

    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) {
	    TclpCloseFile(pipePtr->errorFile);
	}
    } else {
	/*
	 * Wrap the error file into a channel and give it to the cleanup
	 * routine.
	 */

	if (pipePtr->errorFile) {
	    errChan = Tcl_MakeFileChannel(
		(ClientData) INT2PTR(GetFd(pipePtr->errorFile)), TCL_READABLE);
	} else {
	    errChan = NULL;
	}
	result = TclCleanupChildren(interp, pipePtr->numPids, pipePtr->pidPtr,
		errChan);
    }

    if (pipePtr->numPids != 0) {
	ckfree((char *) pipePtr->pidPtr);
    }
    ckfree((char *) pipePtr);
    if (errorCode == 0) {
	return result;
    }
    return errorCode;
}
Exemplo n.º 3
0
static int
PipeClose2Proc(
    ClientData instanceData,	/* The pipe to close. */
    Tcl_Interp *interp,		/* For error reporting. */
    int flags)			/* Flags that indicate which side to close. */
{
    PipeState *pipePtr = instanceData;
    Tcl_Channel errChan;
    int errorCode, result;

    errorCode = 0;
    result = 0;

    if (((!flags) || (flags & TCL_CLOSE_READ)) && (pipePtr->inFile != NULL)) {
        if (TclpCloseFile(pipePtr->inFile) < 0) {
            errorCode = errno;
        } else {
            pipePtr->inFile = NULL;
        }
    }
    if (((!flags) || (flags & TCL_CLOSE_WRITE)) && (pipePtr->outFile != NULL)
            && (errorCode == 0)) {
        if (TclpCloseFile(pipePtr->outFile) < 0) {
            errorCode = errno;
        } else {
            pipePtr->outFile = NULL;
        }
    }

    /*
     * If half-closing, stop here.
     */

    if (flags) {
        return errorCode;
    }

    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) {
            TclpCloseFile(pipePtr->errorFile);
        }
    } else {
        /*
         * Wrap the error file into a channel and give it to the cleanup
         * routine.
         */

        if (pipePtr->errorFile) {
            errChan = Tcl_MakeFileChannel(
                          INT2PTR(GetFd(pipePtr->errorFile)),
                          TCL_READABLE);
        } else {
            errChan = NULL;
        }
        result = TclCleanupChildren(interp, pipePtr->numPids, pipePtr->pidPtr,
                                    errChan);
    }

    if (pipePtr->numPids != 0) {
        ckfree(pipePtr->pidPtr);
    }
    ckfree(pipePtr);
    if (errorCode == 0) {
        return result;
    }
    return errorCode;
}