📄 65.html
字号:
<a name='L281'><i><font color='green'>// 如果该字符是键盘中断符(^C),则向当前进程发送键盘中断信号,并继续处理下一字符。</font></i>
<a name='L282'> <b>if</b> (c == <a href='../S/38.html#L56' title='Defined at 56 in include/linux/tty.h.'>INTR_CHAR</a> (<a href='../S/7.html#L44' title='Defined at 44 in fs/char_dev.c.'>tty</a>))
<a name='L283'> <font color='red'>{</font>
<a name='L284'> <a href='../S/65.html#L135' title='Defined at 135 in kernel/chr_drv/tty_io.c.'>tty_intr</a> (<a href='../S/7.html#L44' title='Defined at 44 in fs/char_dev.c.'>tty</a>, <a href='../S/65.html#L26' title='Defined at 26 in kernel/chr_drv/tty_io.c.'>INTMASK</a>);
<a name='L285'> <b>continue</b>;
<a name='L286'> <font color='red'>}</font>
<a name='L287'><i><font color='green'>// 如果该字符是键盘中断符(^\),则向当前进程发送键盘退出信号,并继续处理下一字符。</font></i>
<a name='L288'> <b>if</b> (c == <a href='../S/38.html#L57' title='Defined at 57 in include/linux/tty.h.'>QUIT_CHAR</a> (<a href='../S/7.html#L44' title='Defined at 44 in fs/char_dev.c.'>tty</a>))
<a name='L289'> <font color='red'>{</font>
<a name='L290'> <a href='../S/65.html#L135' title='Defined at 135 in kernel/chr_drv/tty_io.c.'>tty_intr</a> (<a href='../S/7.html#L44' title='Defined at 44 in fs/char_dev.c.'>tty</a>, <a href='../S/65.html#L27' title='Defined at 27 in kernel/chr_drv/tty_io.c.'>QUITMASK</a>);
<a name='L291'> <b>continue</b>;
<a name='L292'> <font color='red'>}</font>
<a name='L293'> <font color='red'>}</font>
<a name='L294'><i><font color='green'>// 如果该字符是换行符NL(10),或者是文件结束符EOF(^D),辅助缓冲队列字符数加1。[??]</font></i>
<a name='L295'> <b>if</b> (c == 10 || c == <a href='../S/38.html#L60' title='Defined at 60 in include/linux/tty.h.'>EOF_CHAR</a> (<a href='../S/7.html#L44' title='Defined at 44 in fs/char_dev.c.'>tty</a>))
<a name='L296'> <a href='../S/7.html#L44' title='Defined at 44 in fs/char_dev.c.'>tty</a>->secondary.data++;
<a name='L297'><i><font color='green'>// 如果本地模式标志集中回显标志ECHO 置位,那么,如果字符是换行符NL(10),则将换行符NL(10)</font></i>
<a name='L298'><i><font color='green'>// 和回车符CR(13)放入tty 写队列缓冲区中;如果字符是控制字符(字符值<32)并且回显控制字符标志</font></i>
<a name='L299'><i><font color='green'>// ECHOCTL 置位,则将字符'^'和字符c+64 放入tty 写队列中(也即会显示^C、^H 等);否则将该字符</font></i>
<a name='L300'><i><font color='green'>// 直接放入tty 写缓冲队列中。最后调用该tty 的写操作函数。</font></i>
<a name='L301'> <b>if</b> (<a href='../S/65.html#L43' title='Defined at 43 in kernel/chr_drv/tty_io.c.'>L_ECHO</a> (<a href='../S/7.html#L44' title='Defined at 44 in fs/char_dev.c.'>tty</a>))
<a name='L302'> <font color='red'>{</font>
<a name='L303'> <b>if</b> (c == 10)
<a name='L304'> <font color='red'>{</font>
<a name='L305'> <a href='../S/38.html#L52' title='Defined at 52 in include/linux/tty.h.'>PUTCH</a> (10, <a href='../S/7.html#L44' title='Defined at 44 in fs/char_dev.c.'>tty</a>->write_q);
<a name='L306'> <a href='../S/38.html#L52' title='Defined at 52 in include/linux/tty.h.'>PUTCH</a> (13, <a href='../S/7.html#L44' title='Defined at 44 in fs/char_dev.c.'>tty</a>->write_q);
<a name='L307'> <font color='red'>}</font>
<a name='L308'> <b>else</b> <b>if</b> (c < 32)
<a name='L309'> <font color='red'>{</font>
<a name='L310'> <b>if</b> (<a href='../S/65.html#L46' title='Defined at 46 in kernel/chr_drv/tty_io.c.'>L_ECHOCTL</a> (<a href='../S/7.html#L44' title='Defined at 44 in fs/char_dev.c.'>tty</a>))
<a name='L311'> <font color='red'>{</font>
<a name='L312'> <a href='../S/38.html#L52' title='Defined at 52 in include/linux/tty.h.'>PUTCH</a> ('^', <a href='../S/7.html#L44' title='Defined at 44 in fs/char_dev.c.'>tty</a>->write_q);
<a name='L313'> <a href='../S/38.html#L52' title='Defined at 52 in include/linux/tty.h.'>PUTCH</a> (c + 64, <a href='../S/7.html#L44' title='Defined at 44 in fs/char_dev.c.'>tty</a>->write_q);
<a name='L314'> <font color='red'>}</font>
<a name='L315'> <font color='red'>}</font>
<a name='L316'> <b>else</b>
<a name='L317'> <a href='../S/38.html#L52' title='Defined at 52 in include/linux/tty.h.'>PUTCH</a> (c, <a href='../S/7.html#L44' title='Defined at 44 in fs/char_dev.c.'>tty</a>->write_q);
<a name='L318'> <a href='../S/7.html#L44' title='Defined at 44 in fs/char_dev.c.'>tty</a>->write (<a href='../S/7.html#L44' title='Defined at 44 in fs/char_dev.c.'>tty</a>);
<a name='L319'> <font color='red'>}</font>
<a name='L320'><i><font color='green'>// 将该字符放入辅助队列中。</font></i>
<a name='L321'> <a href='../S/38.html#L52' title='Defined at 52 in include/linux/tty.h.'>PUTCH</a> (c, <a href='../S/7.html#L44' title='Defined at 44 in fs/char_dev.c.'>tty</a>->secondary);
<a name='L322'> <font color='red'>}</font>
<a name='L323'><i><font color='green'>// 唤醒等待该辅助缓冲队列的进程(如果有的话)。</font></i>
<a name='L324'> <a href='../S/74.html#L272' title='Defined at 272 in kernel/sched.c.'>wake_up</a> (&<a href='../S/7.html#L44' title='Defined at 44 in fs/char_dev.c.'>tty</a>->secondary.proc_list);
<a name='L325'><font color='red'>}</font>
<a name='L326'>
<a name='L327'><i><font color='green'>//// tty 读函数。</font></i>
<a name='L328'><i><font color='green'>// 参数:channel - 子设备号;buf - 缓冲区指针;nr - 欲读字节数。</font></i>
<a name='L329'><i><font color='green'>// 返回已读字节数。</font></i>
<a name='L330'><b>int</b>
<a name='L331'><a href='../R/714.html' title='Multiple refered from 2 places.'>tty_read</a> (<b>unsigned</b> channel, <b>char</b> *buf, <b>int</b> nr)
<a name='L332'><font color='red'>{</font>
<a name='L333'> <b>struct</b> tty_struct *<a href='../S/7.html#L44' title='Defined at 44 in fs/char_dev.c.'>tty</a>;
<a name='L334'> <b>char</b> c, *b = <a href='../D/716.html' title='Multiple defined in 16 places.'>buf</a>;
<a name='L335'> <b>int</b> minimum, time, flag = 0;
<a name='L336'> <b>long</b> oldalarm;
<a name='L337'>
<a name='L338'><i><font color='green'>// 本版本linux 内核的终端只有3 个子设备,分别是控制台(0)、串口终端1(1)和串口终端2(2)。</font></i>
<a name='L339'><i><font color='green'>// 所以任何大于2 的子设备号都是非法的。写的字节数当然也不能小于0 的。</font></i>
<a name='L340'> <b>if</b> (channel > 2 || nr < 0)
<a name='L341'> <b>return</b> -1;
<a name='L342'><i><font color='green'>// tty 指针指向子设备号对应ttb_table 表中的tty 结构。</font></i>
<a name='L343'> <a href='../S/7.html#L44' title='Defined at 44 in fs/char_dev.c.'>tty</a> = &tty_table[channel];
<a name='L344'><i><font color='green'>// 下面首先保存进程原定时值,然后根据控制字符VTIME 和VMIN 设置读字符操作的超时定时值。</font></i>
<a name='L345'><i><font color='green'>// 在非规范模式下,这两个值是超时定时值。MIN 表示为了满足读操作,需要读取的最少字符数。</font></i>
<a name='L346'><i><font color='green'>// TIME 是一个十分之一秒计数的计时值。</font></i>
<a name='L347'><i><font color='green'>// 首先取进程中的(报警)定时值(滴答数)。</font></i>
<a name='L348'> oldalarm = current->alarm;
<a name='L349'><i><font color='green'>// 并设置读操作超时定时值time 和需要最少读取的字符个数minimum。</font></i>
<a name='L350'> time = 10L * <a href='../S/7.html#L44' title='Defined at 44 in fs/char_dev.c.'>tty</a>->termios.c_cc[<a href='../S/48.html#L118' title='Defined at 118 in include/termios.h.'>VTIME</a>];
<a name='L351'> minimum = <a href='../S/7.html#L44' title='Defined at 44 in fs/char_dev.c.'>tty</a>->termios.c_cc[<a href='../S/48.html#L119' title='Defined at 119 in include/termios.h.'>VMIN</a>];
<a name='L352'><i><font color='green'>// 如果设置了读超时定时值time 但没有设置最少读取个数minimum,那么在读到至少一个字符或者</font></i>
<a name='L353'><i><font color='green'>// 定时超时后读操作将立刻返回。所以这里置minimum=1。</font></i>
<a name='L354'> <b>if</b> (time && !minimum)
<a name='L355'> <font color='red'>{</font>
<a name='L356'> minimum = 1;
<a name='L357'><i><font color='green'>// 如果进程原定时值是0 或者time+当前系统时间值小于进程原定时值的话,则置重新设置进程定时</font></i>
<a name='L358'><i><font color='green'>// 值为time+当前系统时间,并置flag 标志。</font></i>
<a name='L359'> <b>if</b> (flag = (!oldalarm || time + jiffies < oldalarm))
<a name='L360'> current->alarm = time + jiffies;
<a name='L361'> <font color='red'>}</font>
<a name='L362'><i><font color='green'>// 如果设置的最少读取字符数>欲读的字符数,则令其等于此次欲读取的字符数。</font></i>
<a name='L363'> <b>if</b> (minimum > nr)
<a name='L364'> minimum = nr;
<a name='L365'><i><font color='green'>// 当欲读的字节数>0,则循环执行以下操作。</font></i>
<a name='L366'> <b>while</b> (nr > 0)
<a name='L367'> <font color='red'>{</font>
<a name='L368'><i><font color='green'>// 如果flag 不为0(即进程原定时值是0 或者time+当前系统时间值小于进程原定时值)并且进程有定</font></i>
<a name='L369'><i><font color='green'>// 时信号SIGALRM,则复位进程的定时信号并中断循环。</font></i>
<a name='L370'> <b>if</b> (flag && (current->signal & <a href='../S/65.html#L24' title='Defined at 24 in kernel/chr_drv/tty_io.c.'>ALRMMASK</a>))
<a name='L371'> <font color='red'>{</font>
<a name='L372'> current->signal &= ~<a href='../S/65.html#L24' title='Defined at 24 in kernel/chr_drv/tty_io.c.'>ALRMMASK</a>;
<a name='L373'> <b>break</b>;
<a name='L374'> <font color='red'>}</font>
<a name='L375'><i><font color='green'>// 如果当前进程有信号要处理,则退出,返回0。</font></i>
<a name='L376'> <b>if</b> (current->signal)
<a name='L377'> <b>break</b>;
<a name='L378'><i><font color='green'>// 如果辅助缓冲队列(规范模式队列)为空,或者设置了规范模式标志并且辅助队列中字符数为0 以及</font></i>
<a name='L379'><i><font color='green'>// 辅助模式缓冲队列空闲空间>20,则进入可中断睡眠状态,返回后继续处理。</font></i>
<a name='L380'> <b>if</b> (<a href='../S/38.html#L39' title='Defined at 39 in include/linux/tty.h.'>EMPTY</a> (<a href='../S/7.html#L44' title='Defined at 44 in fs/char_dev.c.'>tty</a>->secondary) || (<a href='../S/65.html#L41' title='Defined at 41 in kernel/chr_drv/tty_io.c.'>L_CANON</a> (<a href='../S/7.html#L44' title='Defined at 44 in fs/char_dev.c.'>tty</a>) &&
<a name='L381'> !<a href='../S/7.html#L44' title='Defined at 44 in fs/char_dev.c.'>tty</a>->secondary.data
<a name='L382'> && <a href='../D/215.html' title='Multiple defined in 2 places.'>LEFT</a> (<a href='../S/7.html#L44' title='Defined at 44 in fs/char_dev.c.'>tty</a>->secondary) > 20))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -