📄 tty.c
字号:
if (s -> sep) free (s -> sep); s -> sep = sep ? strdup (sep) : NULL; s -> data = data; } s -> suspend = False; }}voidtty_suspend_callback (void *sp, Bool susp){ serial *s = (serial *) sp; MCHK (s); if (s) if (s -> suspend = susp) if (s -> line) s -> line -> len = 0;}/*}}}*//*{{{ sending */inttty_send (void *sp, char *str, int len){ serial *s = (serial *) sp; int n, sent; MCHK (s); if ((! s) || (s -> fd < 0) || (! str)) return -1; V (2, ("[Send] %s", mkprint (str, len))); sent = 0; while (len > 0) if ((n = write (s -> fd, str, len)) > 0) { str += n; sent += n; len -= n; } else if (! n) break; else if (errno == EIO) { if (! tty_reopen (s, 0)) break; } else if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) msleep (200); else if (errno != EINTR) break; V (2, ("\n")); return sent;}inttty_send_string (void *sp, char *str){ return str ? tty_send (sp, str, strlen (str)) : -1;}/*}}}*//*{{{ expecting */static voidaddline (serial *s, char ch){ if (s -> callback && s -> sep && (! s -> suspend) && ch) { if (! s -> line) s -> line = snew (NULL, 32); else if (s -> line -> len + 1 >= s -> line -> size) if (! sexpand (s -> line, s -> line -> size * 2)) return; if (strchr (s -> sep, ch)) { (*s -> callback) ((void *) s, s -> line, (char_t) ch, s -> data); s -> line -> len = 0; } else s -> line -> str[s -> line -> len++] = (char_t) ch; }}static intdo_expect (serial *s, int tout, expect *base){ int ret; int msec; int n; expect *run; char ch; if ((! s) || (s -> fd < 0)) return -1; V (2, ("[Expect] ")); for (run = base; run; run = run -> next) run -> pos = 0; msec = (tout > 0) ? tout * 1000 : 0; ret = 0; while (! ret) if ((n = data_ready (s -> fd, & msec)) > 0) { while ((n = read (s -> fd, & ch, 1)) == 1) { addline (s, ch); V (3, ("%s", mkprint (& ch, 1))); for (run = base; run; run = run -> next) if (run -> str[run -> pos] == ch) { run -> pos++; if (run -> pos == run -> len) { ret = run -> idx; break; } } else run -> pos = 0; if (ret) break; } if (n < 0) if (errno == EIO) tty_reopen (s, 0); } else if (! n) break; if (verbose > 1) if (run) printf (" got %s", mkprint (run -> str, run -> len)); else printf (" timeout"); V (2, ("\n")); return ret;}inttty_expect (void *sp, int tout, ...){ va_list par; int ret; char *ptr; expect *base, *prev, *tmp; int idx; va_start (par, tout); MCHK ((serial *) sp); ret = 0; base = NULL; prev = NULL; idx = 1; while (ptr = va_arg (par, char *)) if (tmp = (expect *) malloc (sizeof (expect))) { tmp -> idx = idx++; tmp -> str = ptr; tmp -> pos = 0; tmp -> len = va_arg (par, int); tmp -> next = NULL; if (prev) prev -> next = tmp; else base = tmp; prev = tmp; } else break; if (! ptr) ret = do_expect ((serial *) sp, tout, base); else ret = -1; while (base) { tmp = base; base = base -> next; free (tmp); } va_end (par); return ret;}inttty_expect_list (void *sp, int tout, char **strs, int *lens){ int n; int ret; expect *base, *prev, *tmp; MCHK ((serial *) sp); base = NULL; prev = NULL; for (n = 0; strs[n]; ++n) if (tmp = (expect *) malloc (sizeof (expect))) { tmp -> idx = n + 1; tmp -> str = strs[n]; tmp -> pos = 0; tmp -> len = lens[n]; tmp -> next = NULL; if (prev) prev -> next = tmp; else base = tmp; prev = tmp; } else break; if (strs[n]) ret = -1; else ret = do_expect ((serial *) sp, tout, base); while (base) { tmp = base; base = base -> next; free (tmp); } return ret;}inttty_expect_string (void *sp, int tout, char *str){ expect tmp; MCHK ((serial *) sp); if (! str) return -1; tmp.idx = 1; tmp.str = str; tmp.pos = 0; tmp.len = strlen (str); tmp.next = NULL; return do_expect ((serial *) sp, tout, & tmp);}/*}}}*//*{{{ send/expect */static inttonum (char ch){ switch (ch) { default: case '0': return 0; case '1': return 1; case '2': return 2; case '3': return 3; case '4': return 4; case '5': return 5; case '6': return 6; case '7': return 7; case '8': return 8; case '9': return 9; }}static char *expand (char *str, char **opts, int ocnt){ char *ret; int len, siz; int idx, olen; ret = NULL; len = 0; siz = 0; while (*str) { if (len >= siz) { siz += (siz ? siz : 32); if (! (ret = Realloc (ret, siz + 2))) break; } if (*str == '\\') { ++str; if (*str) { switch (*str) { case 'a': ret[len++] = '\a'; break; case 'b': ret[len++] = '\b'; break; case 'f': ret[len++] = '\f'; break; case 'l': ret[len++] = '\012'; break; case 'n': ret[len++] = '\n'; break; case 'r': ret[len++] = '\r'; break; case 's': ret[len++] = ' '; break; case 't': ret[len++] = '\t'; break; default: ret[len++] = *str; break; } ++str; } } else if (*str == '^') { ++str; if (*str) { if (*str == '?') ret[len++] = '\x7f'; else ret[len++] = *str & 0x1f; ++str; } } else if (*str == '%') { ++str; idx = 0; while (isdigit (*str)) { idx *= 10; idx += tonum (*str++); } if ((idx >= 0) && (idx < ocnt)) { olen = strlen (opts[idx]); if (len + olen >= siz) { siz = len + olen + 64; if (! (ret = Realloc (ret, siz + 2))) break; } strcpy (ret + len, opts[idx]); len += olen; } } else if ((*str == '\'') || (*str == '"')) ++str; else ret[len++] = *str++; } if (ret) ret[len] = '\0'; return ret;}static inthandle_command (void *sp, char *str){ serial *s = (serial *) sp; char *p1; int mult; int ret; ret = 0; V (2, ("[Cmd")); for (p1 = str; *p1; ) { if (isdigit (*p1)) { mult = 0; while (isdigit (*p1)) { mult *= 10; mult += tonum (*p1++); } } else mult = 1; if (*p1) switch (*p1++) { case 'd': V (2, (" Dzz %d", mult)); sleep (mult); break; case 'D': V (2, (" Mdzz %d", mult)); msleep (mult); break; case 'b': if (s && (s -> fd != -1)) { V (2, (" Brk %d", mult)); tcsendbreak (s -> fd, mult); } break; case 'h': if (s && (s -> fd != -1)) { V (2, (" Hup")); tty_hangup (sp, mult * 500); } break; case 'o': if (s && (s -> fd != -1)) { V (2, (" Drain")); tcdrain (s -> fd); } break; case '<': if (s && (s -> fd != -1)) { V (2, (" Iflush")); tcflush (s -> fd, TCIFLUSH); } break; case '>': if (s && (s -> fd != -1)) { V (2, (" Oflush")); tcflush (s -> fd, TCOFLUSH); } break; case 'f': V (2, (" fail")); ret = -1; break; case 's': V (2, (" success")); ret = 1; break; } } V (2, ("]\n")); return ret;}static intexpect_expr (void *sp, int deftout, char *line){ int ret; char **ex; int cnt, siz; int n, m, tout, slen; char *ptr; char *p1, *p2; char **list; int *len; MCHK ((serial *) sp); ex = NULL; cnt = 0; siz = 0; for (ptr = line; *ptr; ) { if (cnt >= siz) { siz += 4; if (! (ex = (char **) Realloc (ex, (siz + 1) * sizeof (char *)))) break; } ex[cnt++] = ptr; while (*ptr && (*ptr != '-')) ++ptr; if (*ptr) *ptr++ = '\0'; } if (! ex) return -1; ret = 0; for (n = 0; n < cnt; ++n) { ptr = ex[n]; if (isdigit (*ptr)) { tout = 0; while (isdigit (*ptr)) { tout *= 10; tout += tonum (*ptr++); } } else tout = deftout; p1 = ptr; for (siz = 1, p2 = p1; p2; p2 = strchr (p2, '|')) ++siz, ++p2; if ((list = (char **) malloc ((siz + 1) * sizeof (char *))) && (len = (int *) malloc ((siz + 1) * sizeof (int)))) { for (n = 0, p1 = ptr; p1; ++n) { p2 = p1; if (p1 = strchr (p1, '|')) *p1++ = '\0'; list[n] = p2; len[n] = strlen (p2); } list[n] = NULL; len[n] = 0; if (tty_expect_list (sp, tout, list, len) != 1) ret = -1; free (list); free (len); } else { ret = -1; break; } if ((ret < 0) && (n + 1 < cnt)) { ++n; ptr = ex[n]; ret = 0; if (*ptr == '!') { if (m = handle_command (sp, ptr + 1)) { if (m < 0) ret = -1; break; } } else { slen = strlen (ptr); if (tty_send (sp, ptr, slen) != slen) { ret = -1; break; } } } else n = cnt; } if (ex) free (ex); return ret;}inttty_send_expect (void *sp, int deftout, char *str, char **opts){ serial *s = (serial *) sp; int ret; int ocnt; char *sav, *ptr, *line; int n; char quote; Bool esc; MCHK (s); ret = -1; if (opts) for (ocnt = 0; opts[ocnt]; ++ocnt) ; else ocnt = 0; if (str = strdup (str)) { ret = 0; for (ptr = str; *ptr && (! ret); ) { sav = ptr; esc = False; quote = '\0'; while (*ptr) { if (esc) esc = False; else if (*ptr == '\\') esc = True; else if (quote) { if (*ptr == quote) quote = '\0'; } else if ((*ptr == '\'') || (*ptr == '"')) quote = *ptr; else if (isspace (*ptr)) break; ++ptr; } if (*ptr) { *ptr++ = '\0'; while (isspace (*ptr)) ++ptr; } if (line = expand (sav, opts, ocnt)) { if (line[0] == '<') { if (expect_expr (sp, deftout, line + 1) < 0) ret = -1; } else if (line[0] == '!') { if ((n = handle_command (sp, line + 1)) < 0) ret = -1; else if (n > 0) while (*ptr) ++ptr; } else { n = strlen (line); if (tty_send (sp, line, n) != n) ret = -1; } free (line); } else ret = -1; } free (str); } return ret;}/*}}}*//*{{{ draining */voidtty_mdrain (void *sp, int msecs){ serial *s = (serial *) sp; int n, m; char ch; MCHK (s); if (s && (s -> fd != -1)) { V (2, ("[Drain] ")); if (msecs < 0) msecs = 0; do { if ((n = data_ready (s -> fd, & msecs)) > 0) { while ((m = read (s -> fd, & ch, 1)) == 1) { addline (s, ch); V (2, ("%s", mkprint (& ch, 1))); } if (m < 0) if (errno == EIO) tty_reopen (s, 0); } } while (n != 0); V (2, ("\n")); }}voidtty_drain (void *sp, int secs){ tty_mdrain (sp, secs * 1000);}/*}}}*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -