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

📄 tclunixchan.c

📁 tcl是工具命令语言
💻 C
📖 第 1 页 / 共 5 页
字号:
#endif /* USE_SGTTY */    ttyPtr->baud    = baud;    ttyPtr->parity  = parity;    ttyPtr->data    = data;    ttyPtr->stop    = stop;}/* *--------------------------------------------------------------------------- * * TtySetAttributes -- * *	Set the current attributes of the specified serial device.  * * Results: *	None. * * Side effects: *	None. * *--------------------------------------------------------------------------- */static voidTtySetAttributes(fd, ttyPtr)    int fd;			/* Open file descriptor for serial port to				 * be modified. */    TtyAttrs *ttyPtr;		/* Buffer containing new attributes for				 * serial port. */{    IOSTATE iostate;#ifdef USE_TERMIOS    int parity, data, flag;    GETIOSTATE(fd, &iostate);    cfsetospeed(&iostate, TtyGetSpeed(ttyPtr->baud));    cfsetispeed(&iostate, TtyGetSpeed(ttyPtr->baud));    flag = 0;    parity = ttyPtr->parity;    if (parity != 'n') {	flag |= PARENB;#ifdef PAREXT	iostate.c_cflag &= ~PAREXT;	if ((parity == 'm') || (parity == 's')) {	    flag |= PAREXT;	}#endif /* PAREXT */	if ((parity == 'm') || (parity == 'o')) {	    flag |= PARODD;	}    }    data = ttyPtr->data;    flag |= (data == 5) ? CS5 : (data == 6) ? CS6 : (data == 7) ? CS7 : CS8;    if (ttyPtr->stop == 2) {	flag |= CSTOPB;    }    iostate.c_cflag &= ~(PARENB | PARODD | CSIZE | CSTOPB);    iostate.c_cflag |= flag;#endif	/* USE_TERMIOS */#ifdef USE_TERMIO    int parity, data, flag;    GETIOSTATE(fd, &iostate);    iostate.c_cflag &= ~CBAUD;    iostate.c_cflag |= TtyGetSpeed(ttyPtr->baud);    flag = 0;    parity = ttyPtr->parity;    if (parity != 'n') {	flag |= PARENB;	if ((parity == 'm') || (parity == 's')) {	    flag |= PAREXT;	}	if ((parity == 'm') || (parity == 'o')) {	    flag |= PARODD;	}    }    data = ttyPtr->data;    flag |= (data == 5) ? CS5 : (data == 6) ? CS6 : (data == 7) ? CS7 : CS8;    if (ttyPtr->stop == 2) {	flag |= CSTOPB;    }    iostate.c_cflag &= ~(PARENB | PARODD | PAREXT | CSIZE | CSTOPB);    iostate.c_cflag |= flag;#endif	/* USE_TERMIO */#ifdef USE_SGTTY    int parity;    GETIOSTATE(fd, &iostate);    iostate.sg_ospeed = TtyGetSpeed(ttyPtr->baud);    iostate.sg_ispeed = TtyGetSpeed(ttyPtr->baud);    parity = ttyPtr->parity;    if (parity == 'e') {	iostate.sg_flags &= ~ODDP;	iostate.sg_flags |= EVENP;    } else if (parity == 'o') {	iostate.sg_flags &= ~EVENP;	iostate.sg_flags |= ODDP;    }#endif	/* USE_SGTTY */    SETIOSTATE(fd, &iostate);}/* *--------------------------------------------------------------------------- * * TtyParseMode -- * *	Parse the "-mode" argument to the fconfigure command.  The argument *	is of the form baud,parity,data,stop. * * Results: *	The return value is TCL_OK if the argument was successfully *	parsed, TCL_ERROR otherwise.  If TCL_ERROR is returned, an *	error message is left in the interp's result (if interp is non-NULL). * * Side effects: *	None. * *--------------------------------------------------------------------------- */static intTtyParseMode(interp, mode, speedPtr, parityPtr, dataPtr, stopPtr)    Tcl_Interp *interp;		/* If non-NULL, interp for error return. */    CONST char *mode;		/* Mode string to be parsed. */    int *speedPtr;		/* Filled with baud rate from mode string. */    int *parityPtr;		/* Filled with parity from mode string. */    int *dataPtr;		/* Filled with data bits from mode string. */    int *stopPtr;		/* Filled with stop bits from mode string. */{    int i, end;    char parity;    static char *bad = "bad value for -mode";    i = sscanf(mode, "%d,%c,%d,%d%n", speedPtr, &parity, dataPtr,	    stopPtr, &end);    if ((i != 4) || (mode[end] != '\0')) {	if (interp != NULL) {	    Tcl_AppendResult(interp, bad, ": should be baud,parity,data,stop",		    NULL);	}	return TCL_ERROR;    }    /*     * Only allow setting mark/space parity on platforms that support it     * Make sure to allow for the case where strchr is a macro.     * [Bug: 5089]     */    if (#if defined(PAREXT) || defined(USE_TERMIO)	strchr("noems", parity) == NULL#else	strchr("noe", parity) == NULL#endif /* PAREXT|USE_TERMIO */	) {	if (interp != NULL) {	    Tcl_AppendResult(interp, bad,#if defined(PAREXT) || defined(USE_TERMIO)		    " parity: should be n, o, e, m, or s",#else		    " parity: should be n, o, or e",#endif /* PAREXT|USE_TERMIO */		    NULL);	}	return TCL_ERROR;    }    *parityPtr = parity;    if ((*dataPtr < 5) || (*dataPtr > 8)) {	if (interp != NULL) {	    Tcl_AppendResult(interp, bad, " data: should be 5, 6, 7, or 8",		    NULL);	}	return TCL_ERROR;    }    if ((*stopPtr < 0) || (*stopPtr > 2)) {	if (interp != NULL) {	    Tcl_AppendResult(interp, bad, " stop: should be 1 or 2", NULL);	}	return TCL_ERROR;    }    return TCL_OK;}/* *--------------------------------------------------------------------------- * * TtyInit -- * *	Given file descriptor that refers to a serial port,  *	initialize the serial port to a set of sane values so that *	Tcl can talk to a device located on the serial port. *	Note that no initialization happens if the initialize flag *	is not set; this is necessary for the correct handling of *	UNIX console TTYs at startup. * * Results: *	A pointer to a FileState suitable for use with Tcl_CreateChannel *	and the ttyChannelType structure. * * Side effects: *	Serial device initialized to non-blocking raw mode, similar to *	sockets (if initialize flag is non-zero.)  All other modes can *	be simulated on top of this in Tcl. * *--------------------------------------------------------------------------- */static FileState *TtyInit(fd, initialize)    int fd;			/* Open file descriptor for serial port to				 * be initialized. */    int initialize;{    TtyState *ttyPtr;    ttyPtr = (TtyState *) ckalloc((unsigned) sizeof(TtyState));    GETIOSTATE(fd, &ttyPtr->savedState);    ttyPtr->stateUpdated = 0;    if (initialize) {	IOSTATE iostate = ttyPtr->savedState;#if defined(USE_TERMIOS) || defined(USE_TERMIO)	if (iostate.c_iflag != IGNBRK ||		iostate.c_oflag != 0 ||		iostate.c_lflag != 0 ||		iostate.c_cflag & CREAD ||		iostate.c_cc[VMIN] != 1 ||		iostate.c_cc[VTIME] != 0) {	    ttyPtr->stateUpdated = 1;	}	iostate.c_iflag = IGNBRK;	iostate.c_oflag = 0;	iostate.c_lflag = 0;	iostate.c_cflag |= CREAD;	iostate.c_cc[VMIN] = 1;	iostate.c_cc[VTIME] = 0;#endif	/* USE_TERMIOS|USE_TERMIO */#ifdef USE_SGTTY	if ((iostate.sg_flags & (EVENP | ODDP)) ||		!(iostate.sg_flags & RAW)) {	    ttyPtr->stateUpdated = 1;	}	iostate.sg_flags &= (EVENP | ODDP);	iostate.sg_flags |= RAW;#endif	/* USE_SGTTY */	/*	 * Only update if we're changing anything to avoid possible	 * blocking.	 */	if (ttyPtr->stateUpdated) {	    SETIOSTATE(fd, &iostate);	}    }    return &ttyPtr->fs;}#endif	/* SUPPORTS_TTY *//* *---------------------------------------------------------------------- * * TclpOpenFileChannel -- * *	Open an file based channel on Unix systems. * * Results: *	The new channel or NULL. If NULL, the output argument *	errorCodePtr is set to a POSIX error and an error message is *	left in the interp's result if interp is not NULL. * * Side effects: *	May open the channel and may cause creation of a file on the *	file system. * *---------------------------------------------------------------------- */Tcl_ChannelTclpOpenFileChannel(interp, pathPtr, mode, permissions)    Tcl_Interp *interp;			/* Interpreter for error reporting;					 * can be NULL. */    Tcl_Obj *pathPtr;			/* Name of file to open. */    int mode;				/* POSIX open mode. */    int permissions;			/* If the open involves creating a					 * file, with what modes to create					 * it? */{    int fd, channelPermissions;    FileState *fsPtr;    CONST char *native, *translation;    char channelName[16 + TCL_INTEGER_SPACE];    Tcl_ChannelType *channelTypePtr;#ifdef SUPPORTS_TTY    int ctl_tty;#endif /* SUPPORTS_TTY */#ifdef DEPRECATED    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);#endif /* DEPRECATED */    switch (mode & (O_RDONLY | O_WRONLY | O_RDWR)) {	case O_RDONLY:	    channelPermissions = TCL_READABLE;	    break;	case O_WRONLY:	    channelPermissions = TCL_WRITABLE;	    break;	case O_RDWR:	    channelPermissions = (TCL_READABLE | TCL_WRITABLE);	    break;	default:	    /*	     * This may occurr if modeString was "", for example.	     */	    panic("TclpOpenFileChannel: invalid mode value");	    return NULL;    }    native = Tcl_FSGetNativePath(pathPtr);    if (native == NULL) {	return NULL;    }    fd = TclOSopen(native, mode, permissions);#ifdef SUPPORTS_TTY    ctl_tty = (strcmp (native, "/dev/tty") == 0);#endif /* SUPPORTS_TTY */    if (fd < 0) {	if (interp != (Tcl_Interp *) NULL) {	    Tcl_AppendResult(interp, "couldn't open \"", 		    Tcl_GetString(pathPtr), "\": ",		    Tcl_PosixError(interp), (char *) NULL);	}	return NULL;    }    /*     * Set close-on-exec flag on the fd so that child processes will not     * inherit this fd.     */    fcntl(fd, F_SETFD, FD_CLOEXEC);    sprintf(channelName, "file%d", fd);#ifdef SUPPORTS_TTY    if (!ctl_tty && isatty(fd)) {	/*	 * Initialize the serial port to a set of sane parameters.	 * Especially important if the remote device is set to echo and	 * the serial port driver was also set to echo -- as soon as a char	 * were sent to the serial port, the remote device would echo it,	 * then the serial driver would echo it back to the device, etc.	 */	translation = "auto crlf";	channelTypePtr = &ttyChannelType;	fsPtr = TtyInit(fd, 1);    } else #endif	/* SUPPORTS_TTY */    {	translation = NULL;	channelTypePtr = &fileChannelType;	fsPtr = (FileState *) ckalloc((unsigned) sizeof(FileState));    }#ifdef DEPRECATED    if (channelTypePtr == &fileChannelType) {        fsPtr->nextPtr = tsdPtr->firstFilePtr;        tsdPtr->firstFilePtr = fsPtr;    }#endif /* DEPRECATED */    fsPtr->validMask = channelPermissions | TCL_EXCEPTION;    fsPtr->fd = fd;    fsPtr->channel = Tcl_CreateChannel(channelTypePtr, channelName,	    (ClientData) fsPtr, channelPermissions);    if (translation != NULL) {	/*	 * Gotcha.  Most modems need a "\r" at the end of the command	 * sequence.  If you just send "at\n", the modem will not respond	 * with "OK" because it never got a "\r" to actually invoke the	 * command.  So, by default, newlines are translated to "\r\n" on	 * output to avoid "bug" reports that the serial port isn't working.	 */	if (Tcl_SetChannelOption(interp, fsPtr->channel, "-translation",		translation) != TCL_OK) {	    Tcl_Close(NULL, fsPtr->channel);	    return NULL;	}    }    return fsPtr->channel;}/* *---------------------------------------------------------------------- * * Tcl_MakeFileChannel -- * *	Makes a Tcl_Channel from an existing OS level file handle. * * Results: *	The Tcl_Channel created around the preexisting OS level file handle. * * Side effects: *	None. * *---------------------------------------------------------------------- */Tcl_ChannelTcl_MakeFileChannel(handle, mode)    ClientData handle;		/* OS level handle. */    int mode;			/* ORed combination of TCL_READABLE and				 * TCL_WRITABLE to indicate file mode. */{    FileState *fsPtr;    char channelName[16 + TCL_INTEGER_SPACE];    int fd = (int) handle;    Tcl_ChannelType *channelTypePtr;#ifdef DEPRECATED    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);#endif /* DEPRECATED */    int socketType = 0;    socklen_t argLength = sizeof(int);    if (mode == 0) {	return NULL;    }    /*     * Look to see if a channel with this fd and the same mode already exists.     * If the fd is used, but the mode doesn't match, return NULL.     */#ifdef DEPRECATED    for (fsPtr = tsdPtr->firstFilePtr; fsPtr != NULL; fsPtr = fsPtr->nextPtr) {	if (fsPtr->fd == fd) {	    return ((mode|TCL_EXCEPTION) == fsPtr->validMask) ?		    fsPtr->channel : NULL;	}    }#endif /* DEPRECATED */#ifdef SUPPORTS_TTY    if (isatty(fd)) {	fsPtr = TtyInit(fd, 0);	channelTypePtr = &ttyChannelType;	sprintf(channelName, "serial%d", fd);    } else#endif /* SUPPORTS_TTY */    if (getsockopt(fd, SOL_SOCKET, SO_TYPE, (VOID *)&socketType,		   &argLength) == 0  &&	 socketType == SOCK_STREAM) {	return MakeTcpClientChannelMode((ClientData) fd, mode);    } else {	channelTypePtr = &fileChannelType;	fsPtr = (FileState *) ckalloc((unsigned) sizeof(FileState));	sprintf(channelName, "file%d", fd);    }#ifdef DEPRECATED    if (channelTypePtr == &fileChannelType) {        fsPtr->nextPtr = tsdPtr->firstFilePtr;        tsdPtr->firstFilePtr = fsPtr;    }#endif /* DEPRECATED */    fsPtr->fd = fd;

⌨️ 快捷键说明

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