📄 65.html
字号:
<a name='L383'> <font color='red'>{</font>
<a name='L384'> <a href='../S/65.html#L153' title='Defined at 153 in kernel/chr_drv/tty_io.c.'>sleep_if_empty</a> (&<a href='../S/7.html#L44' title='Defined at 44 in fs/char_dev.c.'>tty</a>->secondary);
<a name='L385'> <b>continue</b>;
<a name='L386'> <font color='red'>}</font>
<a name='L387'><i><font color='green'>// 执行以下操作,直到nr=0 或者辅助缓冲队列为空。</font></i>
<a name='L388'> <b>do</b>
<a name='L389'> <font color='red'>{</font>
<a name='L390'><i><font color='green'>// 取辅助缓冲队列字符c。</font></i>
<a name='L391'> <a href='../S/38.html#L49' title='Defined at 49 in include/linux/tty.h.'>GETCH</a> (<a href='../S/7.html#L44' title='Defined at 44 in fs/char_dev.c.'>tty</a>->secondary, c);
<a name='L392'><i><font color='green'>// 如果该字符是文件结束符(^D)或者是换行符NL(10),则辅助缓冲队列字符数减1。</font></i>
<a name='L393'> <b>if</b> (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>) || c == 10)
<a name='L394'> <a href='../S/7.html#L44' title='Defined at 44 in fs/char_dev.c.'>tty</a>->secondary.data--;
<a name='L395'><i><font color='green'>// 如果该字符是文件结束符(^D)并且规范模式标志置位,则返回已读字符数,并退出。</font></i>
<a name='L396'> <b>if</b> (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 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='L397'> <b>return</b> (b - <a href='../D/716.html' title='Multiple defined in 16 places.'>buf</a>);
<a name='L398'><i><font color='green'>// 否则将该字符放入用户数据段缓冲区buf 中,欲读字符数减1,如果欲读字符数已为0,则中断循环。</font></i>
<a name='L399'> <b>else</b>
<a name='L400'> <font color='red'>{</font>
<a name='L401'> <a href='../S/24.html#L44' title='Defined at 44 in include/asm/segment.h.'>put_fs_byte</a> (c, b++);
<a name='L402'> <b>if</b> (!--nr)
<a name='L403'> <b>break</b>;
<a name='L404'> <font color='red'>}</font>
<a name='L405'> <font color='red'>}</font>
<a name='L406'> <b>while</b> (nr > 0 && !<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 name='L407'><i><font color='green'>// 如果超时定时值time 不为0 并且规范模式标志没有置位(非规范模式),那么:</font></i>
<a name='L408'> <b>if</b> (time && !<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='L409'><i><font color='green'>// 如果进程原定时值是0 或者time+当前系统时间值小于进程原定时值的话,则置重新设置进程定时值</font></i>
<a name='L410'><i><font color='green'>// 为time+当前系统时间,并置flag 标志。否则让进程的定时值等于进程原定时值。</font></i>
<a name='L411'> <b>if</b> (flag = (!oldalarm || time + jiffies < oldalarm))
<a name='L412'> current->alarm = time + jiffies;
<a name='L413'> <b>else</b>
<a name='L414'> current->alarm = oldalarm;
<a name='L415'><i><font color='green'>// 如果规范模式标志置位,那么若没有读到1 个字符则中断循环。否则若已读取数大于或等于最少要</font></i>
<a name='L416'><i><font color='green'>// 求读取的字符数,则也中断循环。</font></i>
<a name='L417'> <b>if</b> (<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='L418'> <font color='red'>{</font>
<a name='L419'> <b>if</b> (b - <a href='../D/716.html' title='Multiple defined in 16 places.'>buf</a>)
<a name='L420'> <b>break</b>;
<a name='L421'> <font color='red'>}</font>
<a name='L422'> <b>else</b> <b>if</b> (b - <a href='../D/716.html' title='Multiple defined in 16 places.'>buf</a> >= minimum)
<a name='L423'> <b>break</b>;
<a name='L424'> <font color='red'>}</font>
<a name='L425'><i><font color='green'>// 让进程的定时值等于进程原定时值。</font></i>
<a name='L426'> current->alarm = oldalarm;
<a name='L427'><i><font color='green'>// 如果进程有信号并且没有读取任何字符,则返回出错号(超时)。</font></i>
<a name='L428'> <b>if</b> (current->signal && !(b - <a href='../D/716.html' title='Multiple defined in 16 places.'>buf</a>))
<a name='L429'> <b>return</b> -<a href='../S/28.html#L33' title='Defined at 33 in include/errno.h.'>EINTR</a>;
<a name='L430'> <b>return</b> (b - <a href='../D/716.html' title='Multiple defined in 16 places.'>buf</a>); <i><font color='green'>// 返回已读取的字符数。</font></i>
<a name='L431'><font color='red'>}</font>
<a name='L432'>
<a name='L433'><i><font color='green'>//// tty 写函数。</font></i>
<a name='L434'><i><font color='green'>// 参数:channel - 子设备号;buf - 缓冲区指针;nr - 写字节数。</font></i>
<a name='L435'><i><font color='green'>// 返回已写字节数。</font></i>
<a name='L436'><b>int</b>
<a name='L437'><a href='../R/715.html' title='Multiple refered from 4 places.'>tty_write</a> (<b>unsigned</b> channel, <b>char</b> *buf, <b>int</b> nr)
<a name='L438'><font color='red'>{</font>
<a name='L439'> <b>static</b> cr_flag = 0;
<a name='L440'> <b>struct</b> tty_struct *<a href='../S/7.html#L44' title='Defined at 44 in fs/char_dev.c.'>tty</a>;
<a name='L441'> <b>char</b> c, *b = <a href='../D/716.html' title='Multiple defined in 16 places.'>buf</a>;
<a name='L442'>
<a name='L443'><i><font color='green'>// 本版本linux 内核的终端只有3 个子设备,分别是控制台(0)、串口终端1(1)和串口终端2(2)。</font></i>
<a name='L444'><i><font color='green'>// 所以任何大于2 的子设备号都是非法的。写的字节数当然也不能小于0 的。</font></i>
<a name='L445'> <b>if</b> (channel > 2 || nr < 0)
<a name='L446'> <b>return</b> -1;
<a name='L447'><i><font color='green'>// tty 指针指向子设备号对应ttb_table 表中的tty 结构。</font></i>
<a name='L448'> <a href='../S/7.html#L44' title='Defined at 44 in fs/char_dev.c.'>tty</a> = channel + tty_table;
<a name='L449'><i><font color='green'>// 字符设备是一个一个字符进行处理的,所以这里对于nr 大于0 时对每个字符进行循环处理。</font></i>
<a name='L450'> <b>while</b> (nr > 0)
<a name='L451'> <font color='red'>{</font>
<a name='L452'><i><font color='green'>// 如果此时tty 的写队列已满,则当前进程进入可中断的睡眠状态。</font></i>
<a name='L453'> <a href='../S/65.html#L167' title='Defined at 167 in kernel/chr_drv/tty_io.c.'>sleep_if_full</a> (&<a href='../S/7.html#L44' title='Defined at 44 in fs/char_dev.c.'>tty</a>->write_q);
<a name='L454'><i><font color='green'>// 如果当前进程有信号要处理,则退出,返回0。</font></i>
<a name='L455'> <b>if</b> (current->signal)
<a name='L456'> <b>break</b>;
<a name='L457'><i><font color='green'>// 当要写的字节数>0 并且tty 的写队列不满时,循环执行以下操作。</font></i>
<a name='L458'> <b>while</b> (nr > 0 && !<a href='../S/38.html#L45' title='Defined at 45 in include/linux/tty.h.'>FULL</a> (<a href='../S/7.html#L44' title='Defined at 44 in fs/char_dev.c.'>tty</a>->write_q))
<a name='L459'> <font color='red'>{</font>
<a name='L460'><i><font color='green'>// 从用户数据段内存中取一字节c。</font></i>
<a name='L461'> c = <a href='../D/821.html' title='Multiple defined in 2 places.'>get_fs_byte</a> (b);
<a name='L462'><i><font color='green'>// 如果终端输出模式标志集中的执行输出处理标志OPOST 置位,则执行下列输出时处理过程。</font></i>
<a name='L463'> <b>if</b> (<a href='../S/65.html#L56' title='Defined at 56 in kernel/chr_drv/tty_io.c.'>O_POST</a> (<a href='../S/7.html#L44' title='Defined at 44 in fs/char_dev.c.'>tty</a>))
<a name='L464'> <font color='red'>{</font>
<a name='L465'><i><font color='green'>// 如果该字符是回车符'\r'(CR,13)并且回车符转换行符标志OCRNL 置位,则将该字符换成换行符</font></i>
<a name='L466'><i><font color='green'>// '\n'(NL,10);否则如果该字符是换行符'\n'(NL,10)并且换行转回车功能标志ONLRET 置位的话,</font></i>
<a name='L467'><i><font color='green'>// 则将该字符换成回车符'\r'(CR,13)。</font></i>
<a name='L468'> <b>if</b> (c == '\r' && <a href='../S/65.html#L58' title='Defined at 58 in kernel/chr_drv/tty_io.c.'>O_CRNL</a> (<a href='../S/7.html#L44' title='Defined at 44 in fs/char_dev.c.'>tty</a>))
<a name='L469'> c = '\n';
<a name='L470'> <b>else</b> <b>if</b> (c == '\n' && <a href='../S/65.html#L59' title='Defined at 59 in kernel/chr_drv/tty_io.c.'>O_NLRET</a> (<a href='../S/7.html#L44' title='Defined at 44 in fs/char_dev.c.'>tty</a>))
<a name='L471'> c = '\r';
<a name='L472'><i><font color='green'>// 如果该字符是换行符'\n'并且回车标志cr_flag 没有置位,换行转回车-换行标志ONLCR 置位的话,</font></i>
<a name='L473'><i><font color='green'>// 则将cr_flag 置位,并将一回车符放入写队列中。然后继续处理下一个字符。</font></i>
<a name='L474'> <b>if</b> (c == '\n' && !cr_flag && <a href='../S/65.html#L57' title='Defined at 57 in kernel/chr_drv/tty_io.c.'>O_NLCR</a> (<a href='../S/7.html#L44' title='Defined at 44 in fs/char_dev.c.'>tty</a>))
<a name='L475'> <font color='red'>{</font>
<a name='L476'> cr_flag = 1;
<a name='L477'> <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='L478'> <b>continue</b>;
<a name='L479'> <font color='red'>}</font>
<a name='L480'><i><font color='green'>// 如果小写转大写标志OLCUC 置位的话,就将该字符转成大写字符。</font></i>
<a name='L481'> <b>if</b> (<a href='../S/65.html#L60' title='Defined at 60 in kernel/chr_
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -