⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tclunixchan.c

📁 tcl是工具命令语言
💻 C
📖 第 1 页 / 共 5 页
字号:
 *	or zero. * * Side effects: *	Writes output on the output device of the channel. * *---------------------------------------------------------------------- */static intFileOutputProc(instanceData, buf, toWrite, errorCodePtr)    ClientData instanceData;		/* File state. */    CONST char *buf;			/* The data buffer. */    int toWrite;			/* How many bytes to write? */    int *errorCodePtr;			/* Where to store error code. */{    FileState *fsPtr = (FileState *) instanceData;    int written;    *errorCodePtr = 0;    if (toWrite == 0) {	/*	 * SF Tcl Bug 465765.	 * Do not try to write nothing into a file. STREAM based	 * implementations will considers this as EOF (if there is a	 * pipe behind the file).	 */	return 0;    }    written = write(fsPtr->fd, buf, (size_t) toWrite);    if (written > -1) {	return written;    }    *errorCodePtr = errno;    return -1;}/* *---------------------------------------------------------------------- * * FileCloseProc -- * *	This procedure is called from the generic IO level to perform *	channel-type-specific cleanup when a file based channel is closed. * * Results: *	0 if successful, errno if failed. * * Side effects: *	Closes the device of the channel. * *---------------------------------------------------------------------- */static intFileCloseProc(instanceData, interp)    ClientData instanceData;	/* File state. */    Tcl_Interp *interp;		/* For error reporting - unused. */{    FileState *fsPtr = (FileState *) instanceData;    int errorCode = 0;#ifdef DEPRECATED    FileState **nextPtrPtr;    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);#endif /* DEPRECATED */    Tcl_DeleteFileHandler(fsPtr->fd);    /*     * Do not close standard channels while in thread-exit.     */    if (!TclInThreadExit()	    || ((fsPtr->fd != 0) && (fsPtr->fd != 1) && (fsPtr->fd != 2))) {	if (close(fsPtr->fd) < 0) {	    errorCode = errno;	}    }    ckfree((char *) fsPtr);    return errorCode;}/* *---------------------------------------------------------------------- * * FileSeekProc -- * *	This procedure is called by the generic IO level to move the *	access point in a file based channel. * * Results: *	-1 if failed, the new position if successful. An output *	argument contains the POSIX error code if an error occurred, *	or zero. * * Side effects: *	Moves the location at which the channel will be accessed in *	future operations. * *---------------------------------------------------------------------- */static intFileSeekProc(instanceData, offset, mode, errorCodePtr)    ClientData instanceData;	/* File state. */    long offset;		/* Offset to seek to. */    int mode;			/* Relative to where should we seek? Can be				 * one of SEEK_START, SEEK_SET or SEEK_END. */    int *errorCodePtr;		/* To store error code. */{    FileState *fsPtr = (FileState *) instanceData;    Tcl_WideInt oldLoc, newLoc;    /*     * Save our current place in case we need to roll-back the seek.     */    oldLoc = TclOSseek(fsPtr->fd, (Tcl_SeekOffset) 0, SEEK_CUR);    if (oldLoc == Tcl_LongAsWide(-1)) {	/*	 * Bad things are happening.  Error out...	 */	*errorCodePtr = errno;	return -1;    }     newLoc = TclOSseek(fsPtr->fd, (Tcl_SeekOffset) offset, mode);     /*     * Check for expressability in our return type, and roll-back otherwise.     */    if (newLoc > Tcl_LongAsWide(INT_MAX)) {	*errorCodePtr = EOVERFLOW;	TclOSseek(fsPtr->fd, (Tcl_SeekOffset) oldLoc, SEEK_SET);	return -1;    } else {	*errorCodePtr = (newLoc == Tcl_LongAsWide(-1)) ? errno : 0;    }    return (int) Tcl_WideAsLong(newLoc);}/* *---------------------------------------------------------------------- * * FileWideSeekProc -- * *	This procedure is called by the generic IO level to move the *	access point in a file based channel, with offsets expressed *	as wide integers. * * Results: *	-1 if failed, the new position if successful. An output *	argument contains the POSIX error code if an error occurred, *	or zero. * * Side effects: *	Moves the location at which the channel will be accessed in *	future operations. * *---------------------------------------------------------------------- */static Tcl_WideIntFileWideSeekProc(instanceData, offset, mode, errorCodePtr)    ClientData instanceData;	/* File state. */    Tcl_WideInt offset;		/* Offset to seek to. */    int mode;			/* Relative to where should we seek? Can be				 * one of SEEK_START, SEEK_CUR or SEEK_END. */    int *errorCodePtr;		/* To store error code. */{    FileState *fsPtr = (FileState *) instanceData;    Tcl_WideInt newLoc;    newLoc = TclOSseek(fsPtr->fd, (Tcl_SeekOffset) offset, mode);    *errorCodePtr = (newLoc == -1) ? errno : 0;    return newLoc;}/* *---------------------------------------------------------------------- * * FileWatchProc -- * *	Initialize the notifier to watch the fd from this channel. * * Results: *	None. * * Side effects: *	Sets up the notifier so that a future event on the channel will *	be seen by Tcl. * *---------------------------------------------------------------------- */static voidFileWatchProc(instanceData, mask)    ClientData instanceData;		/* The file state. */    int mask;				/* Events of interest; an OR-ed					 * combination of TCL_READABLE,					 * TCL_WRITABLE and TCL_EXCEPTION. */{    FileState *fsPtr = (FileState *) instanceData;    /*     * Make sure we only register for events that are valid on this file.     * Note that we are passing Tcl_NotifyChannel directly to     * Tcl_CreateFileHandler with the channel pointer as the client data.     */    mask &= fsPtr->validMask;    if (mask) {	Tcl_CreateFileHandler(fsPtr->fd, mask,		(Tcl_FileProc *) Tcl_NotifyChannel,		(ClientData) fsPtr->channel);    } else {	Tcl_DeleteFileHandler(fsPtr->fd);    }}/* *---------------------------------------------------------------------- * * FileGetHandleProc -- * *	Called from Tcl_GetChannelHandle to retrieve OS handles from *	a file based channel. * * Results: *	Returns TCL_OK with the fd in handlePtr, or TCL_ERROR if *	there is no handle for the specified direction.  * * Side effects: *	None. * *---------------------------------------------------------------------- */static intFileGetHandleProc(instanceData, direction, handlePtr)    ClientData instanceData;	/* The file state. */    int direction;		/* TCL_READABLE or TCL_WRITABLE */    ClientData *handlePtr;	/* Where to store the handle.  */{    FileState *fsPtr = (FileState *) instanceData;    if (direction & fsPtr->validMask) {	*handlePtr = (ClientData) fsPtr->fd;	return TCL_OK;    } else {	return TCL_ERROR;    }}#ifdef SUPPORTS_TTY /* *---------------------------------------------------------------------- * * TtyCloseProc -- * *	This procedure is called from the generic IO level to perform *	channel-type-specific cleanup when a tty based channel is closed. * * Results: *	0 if successful, errno if failed. * * Side effects: *	Closes the device of the channel. * *---------------------------------------------------------------------- */static intTtyCloseProc(instanceData, interp)    ClientData instanceData;	/* Tty state. */    Tcl_Interp *interp;		/* For error reporting - unused. */{#if BAD_TIP35_FLUSH    TtyState *ttyPtr = (TtyState *) instanceData;#endif /* BAD_TIP35_FLUSH */#ifdef TTYFLUSH    TTYFLUSH(ttyPtr->fs.fd);#endif /* TTYFLUSH */#if 0    /*     * TIP#35 agreed to remove the unsave so that TCL could be used as a      * simple stty.      * It would be cleaner to remove all the stuff related to      *	  TtyState.stateUpdated     *	  TtyState.savedState     * Then the structure TtyState would be the same as FileState.     * IMO this cleanup could better be done for the final 8.4 release     * after nobody complained about the missing unsave. -- schroedter     */    if (ttyPtr->stateUpdated) {	SETIOSTATE(ttyPtr->fs.fd, &ttyPtr->savedState);    }#endif    return FileCloseProc(instanceData, interp);}/* *---------------------------------------------------------------------- * * TtyOutputProc-- * *	This procedure is invoked from the generic IO level to write *	output to a TTY 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. * * Side effects: *	Writes output on the output device of the channel *	if the channel is not designated to be closed. * *---------------------------------------------------------------------- */#if BAD_TIP35_FLUSHstatic intTtyOutputProc(instanceData, buf, toWrite, errorCodePtr)    ClientData instanceData;		/* File state. */    CONST char *buf;			/* The data buffer. */    int toWrite;			/* How many bytes to write? */    int *errorCodePtr;			/* Where to store error code. */{    if (TclInExit()) {	/*	 * Do not write data during Tcl exit.	 * Serial port may block preventing Tcl from exit.	 */	return toWrite;    } else {	return FileOutputProc(instanceData, buf, toWrite, errorCodePtr);    }}#endif /* BAD_TIP35_FLUSH */#ifdef USE_TERMIOS/* *---------------------------------------------------------------------- * * TtyModemStatusStr -- * *  Converts a RS232 modem status list of readable flags * *---------------------------------------------------------------------- */static voidTtyModemStatusStr(status, dsPtr)    int status;		   /* RS232 modem status */    Tcl_DString *dsPtr;	   /* Where to store string */{#ifdef TIOCM_CTS    Tcl_DStringAppendElement(dsPtr, "CTS");    Tcl_DStringAppendElement(dsPtr, (status & TIOCM_CTS) ? "1" : "0");#endif /* TIOCM_CTS */#ifdef TIOCM_DSR    Tcl_DStringAppendElement(dsPtr, "DSR");    Tcl_DStringAppendElement(dsPtr, (status & TIOCM_DSR) ? "1" : "0");#endif /* TIOCM_DSR */#ifdef TIOCM_RNG    Tcl_DStringAppendElement(dsPtr, "RING");    Tcl_DStringAppendElement(dsPtr, (status & TIOCM_RNG) ? "1" : "0");#endif /* TIOCM_RNG */#ifdef TIOCM_CD    Tcl_DStringAppendElement(dsPtr, "DCD");    Tcl_DStringAppendElement(dsPtr, (status & TIOCM_CD) ? "1" : "0");#endif /* TIOCM_CD */}#endif /* USE_TERMIOS *//* *---------------------------------------------------------------------- * * TtySetOptionProc -- * *	Sets an option on a channel. * * Results: *	A standard Tcl result. Also sets the interp's result on error if *	interp is not NULL. * * Side effects: *	May modify an option on a device. *	Sets Error message if needed (by calling Tcl_BadChannelOption). * *---------------------------------------------------------------------- */static int		TtySetOptionProc(instanceData, interp, optionName, value)    ClientData instanceData;	/* File state. */    Tcl_Interp *interp;		/* For error reporting - can be NULL. */    CONST char *optionName;	/* Which option to set? */    CONST char *value;		/* New value for option. */{    FileState *fsPtr = (FileState *) instanceData;    unsigned int len, vlen;    TtyAttrs tty;#ifdef USE_TERMIOS    int flag, control, argc;    CONST char **argv;    IOSTATE iostate;#endif /* USE_TERMIOS */    len = strlen(optionName);    vlen = strlen(value);    /*     * Option -mode baud,parity,databits,stopbits     */    if ((len > 2) && (strncmp(optionName, "-mode", len) == 0)) {	if (TtyParseMode(interp, value, &tty.baud, &tty.parity, &tty.data,		&tty.stop) != TCL_OK) {	    return TCL_ERROR;	}	/*	 * system calls results should be checked there. -- dl	 */	TtySetAttributes(fsPtr->fd, &tty);	((TtyState *) fsPtr)->stateUpdated = 1;	return TCL_OK;    }#ifdef USE_TERMIOS    /*     * Option -handshake none|xonxoff|rtscts|dtrdsr     */    if ((len > 1) && (strncmp(optionName, "-handshake", len) == 0)) {	/*	 * Reset all handshake options	 * DTR and RTS are ON by default	 */	GETIOSTATE(fsPtr->fd, &iostate);	iostate.c_iflag &= ~(IXON | IXOFF | IXANY);#ifdef CRTSCTS	iostate.c_cflag &= ~CRTSCTS;#endif /* CRTSCTS */	if (strncasecmp(value, "NONE", vlen) == 0) {	    /* leave all handshake options disabled */	} else if (strncasecmp(value, "XONXOFF", vlen) == 0) {	    iostate.c_iflag |= (IXON | IXOFF | IXANY);	} else if (strncasecmp(value, "RTSCTS", vlen) == 0) {#ifdef CRTSCTS	    iostate.c_cflag |= CRTSCTS;#else /* !CRTSTS */	    UNSUPPORTED_OPTION("-handshake RTSCTS");	    return TCL_ERROR;#endif /* CRTSCTS */	} else if (strncasecmp(value, "DTRDSR", vlen) == 0) {	    UNSUPPORTED_OPTION("-handshake DTRDSR");	    return TCL_ERROR;	} else {	    if (interp) {		Tcl_AppendResult(interp, "bad value for -handshake: ",			"must be one of xonxoff, rtscts, dtrdsr or none",			(char *) NULL);	    }	    return TCL_ERROR;	}	SETIOSTATE(fsPtr->fd, &iostate);	return TCL_OK;    }    /*     * Option -xchar {\x11 \x13}     */    if ((len > 1) && (strncmp(optionName, "-xchar", len) == 0)) {	GETIOSTATE(fsPtr->fd, &iostate);	if (Tcl_SplitList(interp, value, &argc, &argv) == TCL_ERROR) {	    return TCL_ERROR;	}	if (argc == 2) {	    iostate.c_cc[VSTART] = argv[0][0];	    iostate.c_cc[VSTOP]	 = argv[1][0];	} else {	    if (interp) {		Tcl_AppendResult(interp,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -