自从 80 年代我在大学里第一次开始使用 BSD 状态字符 ^T 以来,我已经非常习惯它了。它不是起源于 BSD,而是来自更古老的操作系统。它仍然适用于现代 BSD 系统,包括 Darwin。这是 MacOS 上的一个示例,我在 grep 中按了三次 ^T,然后才按了 ^D:
darwin% stty all
speed 38400 baud; 93 rows; 124 columns;
lflags: icanon isig iexten echo echoe echok echoke -echonl echoctl
-echoprt -altwerase -noflsh -tostop -flusho pendin -nokerninfo
-extproc
iflags: -istrip icrnl -inlcr -igncr ixon -ixoff ixany imaxbel -iutf8
-ignbrk brkint -inpck -ignpar -parmrk
oflags: opost onlcr -oxtabs -onocr -onlret
cflags: cread cs8 -parenb -parodd hupcl -clocal -cstopb -crtscts -dsrflow
-dtrflow -mdmbuf
discard dsusp eof eol eol2 erase intr kill lnext
^O ^Y ^D <undef> <undef> ^H ^C ^U ^V
min quit reprint start status stop susp time werase
1 ^\ ^R ^Q ^T ^S ^Z 0 ^W
darwin% grep foo
load: 0.05 cmd: grep 7227 waiting 0.00u 0.00s
load: 0.05 cmd: grep 7227 waiting 0.00u 0.00s
load: 0.05 cmd: grep 7227 waiting 0.00u 0.00s
OpenBSD 上的情况也一样,甚至更好,因为我得到了等待通道
openbsd% stty all
speed 38400 baud; 93 rows; 124 columns;
lflags: icanon isig iexten echo echoe -echok echoke -echonl echoctl
-echoprt -altwerase -noflsh -tostop -flusho pendin -nokerninfo
-extproc -xcase
iflags: -istrip icrnl -inlcr -igncr -iuclc ixon -ixoff ixany imaxbel
-ignbrk brkint -inpck -ignpar -parmrk
oflags: opost onlcr -ocrnl -onocr -onlret -olcuc oxtabs -onoeot
cflags: cread cs8 -parenb -parodd hupcl -clocal -cstopb -crtscts -mdmbuf
discard dsusp eof eol eol2 erase intr kill lnext
^O ^Y ^D <undef> <undef> ^H ^C ^U ^V
min quit reprint start status stop susp time werase
1 ^\ ^R ^Q ^T ^S ^Z 0 ^W
openbsd% grep foo
load: 0.67 cmd: grep 3759 [ttyin] 0.00u 0.02s 0% 190k
load: 0.67 cmd: grep 3759 [ttyin] 0.00u 0.02s 0% 190k
load: 0.67 cmd: grep 3759 [ttyin] 0.00u 0.02s 0% 190k
正如您所看到的,当程序似乎出现问题时,它对于了解程序正在做什么非常有用。请注意,在 OpenBSD 上,它不仅显示等待通道,还显示进程内存和 CPU 百分比。
我的问题是:有什么方法可以在 Linux 上实现它吗?
但是,它在 Linux 上不起作用,那么有什么方法可以让它工作吗?有人已经这样做了吗?数组中似乎有足够的空间c_ch[]
,因为 Linux 似乎在那里有很多未使用的插槽。
这是 Linux/usr/include/bits/termios.h
文件:
#define NCCS 32
struct termios
{
tcflag_t c_iflag; /* input mode flags */
tcflag_t c_oflag; /* output mode flags */
tcflag_t c_cflag; /* control mode flags */
tcflag_t c_lflag; /* local mode flags */
cc_t c_line; /* line discipline */
cc_t c_cc[NCCS]; /* control characters */
speed_t c_ispeed; /* input speed */
speed_t c_ospeed; /* output speed */
#define _HAVE_STRUCT_TERMIOS_C_ISPEED 1
#define _HAVE_STRUCT_TERMIOS_C_OSPEED 1
};
/* c_cc characters */
#define VINTR 0
#define VQUIT 1
#define VERASE 2
#define VKILL 3
#define VEOF 4
#define VTIME 5
#define VMIN 6
#define VSWTC 7
#define VSTART 8
#define VSTOP 9
#define VSUSP 10
#define VEOL 11
#define VREPRINT 12
#define VDISCARD 13
#define VWERASE 14
#define VLNEXT 15
#define VEOL2 16
看起来 Linuxc_cc[]
阵列中的 32 个插槽中已定义了 17 个。这些真的可以使用吗?我想知道为什么它们没有被标记为备用。
在 OpenBSD 上,/use/include/sys/termios.h
其中包含这些内容:
/*
* Special Control Characters
*
* Index into c_cc[] character array.
*
* Name Subscript Enabled by
*/
#define VEOF 0 /* ICANON */
#define VEOL 1 /* ICANON */
#if __BSD_VISIBLE
#define VEOL2 2 /* ICANON */
#endif
#define VERASE 3 /* ICANON */
#if __BSD_VISIBLE
#define VWERASE 4 /* ICANON */
#endif
#define VKILL 5 /* ICANON */
#if __BSD_VISIBLE
#define VREPRINT 6 /* ICANON */
#endif
/* 7 spare 1 */
#define VINTR 8 /* ISIG */
#define VQUIT 9 /* ISIG */
#define VSUSP 10 /* ISIG */
#if __BSD_VISIBLE
#define VDSUSP 11 /* ISIG */
#endif
#define VSTART 12 /* IXON, IXOFF */
#define VSTOP 13 /* IXON, IXOFF */
#if __BSD_VISIBLE
#define VLNEXT 14 /* IEXTEN */
#define VDISCARD 15 /* IEXTEN */
#endif
#define VMIN 16 /* !ICANON */
#define VTIME 17 /* !ICANON */
#if __BSD_VISIBLE
#define VSTATUS 18 /* ICANON */
/* 19 spare 2 */
#endif
#define NCCS 20
我很好奇为什么 Darwin 下有这么多备用,而 OpenBSD 下只有两个备用。但即便如此,这看起来应该是可能的,所以我无法想象没有人曾经破解过他们的内核(如 stty(1) 等)来支持它。
在我开始动手之前,有没有什么可行的实施方案可以指点一下?