📄 tclunixchan.c
字号:
"bad value for -xchar: should be a list of two elements", (char *) NULL); } return TCL_ERROR; } SETIOSTATE(fsPtr->fd, &iostate); return TCL_OK; } /* * Option -timeout msec */ if ((len > 2) && (strncmp(optionName, "-timeout", len) == 0)) { int msec; GETIOSTATE(fsPtr->fd, &iostate); if (Tcl_GetInt(interp, value, &msec) != TCL_OK) { return TCL_ERROR; } iostate.c_cc[VMIN] = 0; iostate.c_cc[VTIME] = (msec == 0) ? 0 : (msec < 100) ? 1 : (msec+50)/100; SETIOSTATE(fsPtr->fd, &iostate); return TCL_OK; } /* * Option -ttycontrol {DTR 1 RTS 0 BREAK 0} */ if ((len > 4) && (strncmp(optionName, "-ttycontrol", len) == 0)) { if (Tcl_SplitList(interp, value, &argc, &argv) == TCL_ERROR) { return TCL_ERROR; } if ((argc % 2) == 1) { if (interp) { Tcl_AppendResult(interp, "bad value for -ttycontrol: should be a list of", "signal,value pairs", (char *) NULL); } return TCL_ERROR; } GETCONTROL(fsPtr->fd, &control); while (argc > 1) { if (Tcl_GetBoolean(interp, argv[1], &flag) == TCL_ERROR) { return TCL_ERROR; } if (strncasecmp(argv[0], "DTR", strlen(argv[0])) == 0) {#ifdef TIOCM_DTR if (flag) { control |= TIOCM_DTR; } else { control &= ~TIOCM_DTR; }#else /* !TIOCM_DTR */ UNSUPPORTED_OPTION("-ttycontrol DTR"); return TCL_ERROR;#endif /* TIOCM_DTR */ } else if (strncasecmp(argv[0], "RTS", strlen(argv[0])) == 0) {#ifdef TIOCM_RTS if (flag) { control |= TIOCM_RTS; } else { control &= ~TIOCM_RTS; }#else /* !TIOCM_RTS*/ UNSUPPORTED_OPTION("-ttycontrol RTS"); return TCL_ERROR;#endif /* TIOCM_RTS*/ } else if (strncasecmp(argv[0], "BREAK", strlen(argv[0])) == 0) {#ifdef SETBREAK SETBREAK(fsPtr->fd, flag);#else /* !SETBREAK */ UNSUPPORTED_OPTION("-ttycontrol BREAK"); return TCL_ERROR;#endif /* SETBREAK */ } else { if (interp) { Tcl_AppendResult(interp, "bad signal for -ttycontrol: must be ", "DTR, RTS or BREAK", (char *) NULL); } return TCL_ERROR; } argc -= 2, argv += 2; } /* while (argc > 1) */ SETCONTROL(fsPtr->fd, &control); return TCL_OK; } return Tcl_BadChannelOption(interp, optionName, "mode handshake timeout ttycontrol xchar ");#else /* !USE_TERMIOS */ return Tcl_BadChannelOption(interp, optionName, "mode");#endif /* USE_TERMIOS */}/* *---------------------------------------------------------------------- * * TtyGetOptionProc -- * * Gets a mode associated with an IO channel. If the optionName arg * is non NULL, retrieves the value of that option. If the optionName * arg is NULL, retrieves a list of alternating option names and * values for the given channel. * * Results: * A standard Tcl result. Also sets the supplied DString to the * string value of the option(s) returned. * * Side effects: * The string returned by this function is in static storage and * may be reused at any time subsequent to the call. * Sets Error message if needed (by calling Tcl_BadChannelOption). * *---------------------------------------------------------------------- */static int TtyGetOptionProc(instanceData, interp, optionName, dsPtr) ClientData instanceData; /* File state. */ Tcl_Interp *interp; /* For error reporting - can be NULL. */ CONST char *optionName; /* Option to get. */ Tcl_DString *dsPtr; /* Where to store value(s). */{ FileState *fsPtr = (FileState *) instanceData; unsigned int len; char buf[3 * TCL_INTEGER_SPACE + 16]; TtyAttrs tty; int valid = 0; /* flag if valid option parsed */ if (optionName == NULL) { len = 0; } else { len = strlen(optionName); } if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-mode"); } if (len==0 || (len>2 && strncmp(optionName, "-mode", len)==0)) { valid = 1; TtyGetAttributes(fsPtr->fd, &tty); sprintf(buf, "%d,%c,%d,%d", tty.baud, tty.parity, tty.data, tty.stop); Tcl_DStringAppendElement(dsPtr, buf); }#ifdef USE_TERMIOS /* * get option -xchar */ if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-xchar"); Tcl_DStringStartSublist(dsPtr); } if (len==0 || (len>1 && strncmp(optionName, "-xchar", len)==0)) { IOSTATE iostate; valid = 1; GETIOSTATE(fsPtr->fd, &iostate); sprintf(buf, "%c", iostate.c_cc[VSTART]); Tcl_DStringAppendElement(dsPtr, buf); sprintf(buf, "%c", iostate.c_cc[VSTOP]); Tcl_DStringAppendElement(dsPtr, buf); } if (len == 0) { Tcl_DStringEndSublist(dsPtr); } /* * get option -queue * option is readonly and returned by [fconfigure chan -queue] * but not returned by unnamed [fconfigure chan] */ if ((len > 1) && (strncmp(optionName, "-queue", len) == 0)) { int inQueue=0, outQueue=0; int inBuffered, outBuffered; valid = 1;#ifdef GETREADQUEUE GETREADQUEUE(fsPtr->fd, inQueue);#endif /* GETREADQUEUE */#ifdef GETWRITEQUEUE GETWRITEQUEUE(fsPtr->fd, outQueue);#endif /* GETWRITEQUEUE */ inBuffered = Tcl_InputBuffered(fsPtr->channel); outBuffered = Tcl_OutputBuffered(fsPtr->channel); sprintf(buf, "%d", inBuffered+inQueue); Tcl_DStringAppendElement(dsPtr, buf); sprintf(buf, "%d", outBuffered+outQueue); Tcl_DStringAppendElement(dsPtr, buf); } /* * get option -ttystatus * option is readonly and returned by [fconfigure chan -ttystatus] * but not returned by unnamed [fconfigure chan] */ if ((len > 4) && (strncmp(optionName, "-ttystatus", len) == 0)) { int status; valid = 1; GETCONTROL(fsPtr->fd, &status); TtyModemStatusStr(status, dsPtr); }#endif /* USE_TERMIOS */ if (valid) { return TCL_OK; } else { return Tcl_BadChannelOption(interp, optionName,#ifdef USE_TERMIOS "mode queue ttystatus xchar");#else /* !USE_TERMIOS */ "mode");#endif /* USE_TERMIOS */ }}#undef DIRECT_BAUD#ifdef B4800# if (B4800 == 4800)# define DIRECT_BAUD# endif /* B4800 == 4800 */#endif /* B4800 */#ifdef DIRECT_BAUD# define TtyGetSpeed(baud) ((unsigned) (baud))# define TtyGetBaud(speed) ((int) (speed))#else /* !DIRECT_BAUD */static struct {int baud; unsigned long speed;} speeds[] = {#ifdef B0 {0, B0},#endif#ifdef B50 {50, B50},#endif#ifdef B75 {75, B75},#endif#ifdef B110 {110, B110},#endif#ifdef B134 {134, B134},#endif#ifdef B150 {150, B150},#endif#ifdef B200 {200, B200},#endif#ifdef B300 {300, B300},#endif#ifdef B600 {600, B600},#endif#ifdef B1200 {1200, B1200},#endif#ifdef B1800 {1800, B1800},#endif#ifdef B2400 {2400, B2400},#endif#ifdef B4800 {4800, B4800},#endif#ifdef B9600 {9600, B9600},#endif#ifdef B14400 {14400, B14400},#endif#ifdef B19200 {19200, B19200},#endif#ifdef EXTA {19200, EXTA},#endif#ifdef B28800 {28800, B28800},#endif#ifdef B38400 {38400, B38400},#endif#ifdef EXTB {38400, EXTB},#endif#ifdef B57600 {57600, B57600},#endif#ifdef _B57600 {57600, _B57600},#endif#ifdef B76800 {76800, B76800},#endif#ifdef B115200 {115200, B115200},#endif#ifdef _B115200 {115200, _B115200},#endif#ifdef B153600 {153600, B153600},#endif#ifdef B230400 {230400, B230400},#endif#ifdef B307200 {307200, B307200},#endif#ifdef B460800 {460800, B460800},#endif {-1, 0}};/* *--------------------------------------------------------------------------- * * TtyGetSpeed -- * * Given a baud rate, get the mask value that should be stored in * the termios, termio, or sgttyb structure in order to select that * baud rate. * * Results: * As above. * * Side effects: * None. * *--------------------------------------------------------------------------- */static unsigned longTtyGetSpeed(baud) int baud; /* The baud rate to look up. */{ int bestIdx, bestDiff, i, diff; bestIdx = 0; bestDiff = 1000000; /* * If the baud rate does not correspond to one of the known mask values, * choose the mask value whose baud rate is closest to the specified * baud rate. */ for (i = 0; speeds[i].baud >= 0; i++) { diff = speeds[i].baud - baud; if (diff < 0) { diff = -diff; } if (diff < bestDiff) { bestIdx = i; bestDiff = diff; } } return speeds[bestIdx].speed;}/* *--------------------------------------------------------------------------- * * TtyGetBaud -- * * Given a speed mask value from a termios, termio, or sgttyb * structure, get the baus rate that corresponds to that mask value. * * Results: * As above. If the mask value was not recognized, 0 is returned. * * Side effects: * None. * *--------------------------------------------------------------------------- */static intTtyGetBaud(speed) unsigned long speed; /* Speed mask value to look up. */{ int i; for (i = 0; speeds[i].baud >= 0; i++) { if (speeds[i].speed == speed) { return speeds[i].baud; } } return 0;}#endif /* !DIRECT_BAUD *//* *--------------------------------------------------------------------------- * * TtyGetAttributes -- * * Get the current attributes of the specified serial device. * * Results: * None. * * Side effects: * None. * *--------------------------------------------------------------------------- */static voidTtyGetAttributes(fd, ttyPtr) int fd; /* Open file descriptor for serial port to * be queried. */ TtyAttrs *ttyPtr; /* Buffer filled with serial port * attributes. */{ IOSTATE iostate; int baud, parity, data, stop; GETIOSTATE(fd, &iostate);#ifdef USE_TERMIOS baud = TtyGetBaud(cfgetospeed(&iostate)); parity = 'n';#ifdef PAREXT switch ((int) (iostate.c_cflag & (PARENB | PARODD | PAREXT))) { case PARENB : parity = 'e'; break; case PARENB | PARODD : parity = 'o'; break; case PARENB | PAREXT : parity = 's'; break; case PARENB | PARODD | PAREXT : parity = 'm'; break; }#else /* !PAREXT */ switch ((int) (iostate.c_cflag & (PARENB | PARODD))) { case PARENB : parity = 'e'; break; case PARENB | PARODD : parity = 'o'; break; }#endif /* !PAREXT */ data = iostate.c_cflag & CSIZE; data = (data == CS5) ? 5 : (data == CS6) ? 6 : (data == CS7) ? 7 : 8; stop = (iostate.c_cflag & CSTOPB) ? 2 : 1;#endif /* USE_TERMIOS */#ifdef USE_TERMIO baud = TtyGetBaud(iostate.c_cflag & CBAUD); parity = 'n'; switch (iostate.c_cflag & (PARENB | PARODD | PAREXT)) { case PARENB : parity = 'e'; break; case PARENB | PARODD : parity = 'o'; break; case PARENB | PAREXT : parity = 's'; break; case PARENB | PARODD | PAREXT : parity = 'm'; break; } data = iostate.c_cflag & CSIZE; data = (data == CS5) ? 5 : (data == CS6) ? 6 : (data == CS7) ? 7 : 8; stop = (iostate.c_cflag & CSTOPB) ? 2 : 1;#endif /* USE_TERMIO */#ifdef USE_SGTTY baud = TtyGetBaud(iostate.sg_ospeed); parity = 'n'; if (iostate.sg_flags & EVENP) { parity = 'e'; } else if (iostate.sg_flags & ODDP) { parity = 'o'; } data = (iostate.sg_flags & (EVENP | ODDP)) ? 7 : 8; stop = 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -