@@ -1262,6 +1262,91 @@ static bool n_tty_receive_char_flow_ctrl(struct tty_struct *tty, unsigned char c
12621262 return true;
12631263}
12641264
1265+ static bool n_tty_receive_char_canon (struct tty_struct * tty , u8 c )
1266+ {
1267+ struct n_tty_data * ldata = tty -> disc_data ;
1268+
1269+ if (c == ERASE_CHAR (tty ) || c == KILL_CHAR (tty ) ||
1270+ (c == WERASE_CHAR (tty ) && L_IEXTEN (tty ))) {
1271+ eraser (c , tty );
1272+ commit_echoes (tty );
1273+
1274+ return true;
1275+ }
1276+
1277+ if (c == LNEXT_CHAR (tty ) && L_IEXTEN (tty )) {
1278+ ldata -> lnext = 1 ;
1279+ if (L_ECHO (tty )) {
1280+ finish_erasing (ldata );
1281+ if (L_ECHOCTL (tty )) {
1282+ echo_char_raw ('^' , ldata );
1283+ echo_char_raw ('\b' , ldata );
1284+ commit_echoes (tty );
1285+ }
1286+ }
1287+
1288+ return true;
1289+ }
1290+
1291+ if (c == REPRINT_CHAR (tty ) && L_ECHO (tty ) && L_IEXTEN (tty )) {
1292+ size_t tail = ldata -> canon_head ;
1293+
1294+ finish_erasing (ldata );
1295+ echo_char (c , tty );
1296+ echo_char_raw ('\n' , ldata );
1297+ while (MASK (tail ) != MASK (ldata -> read_head )) {
1298+ echo_char (read_buf (ldata , tail ), tty );
1299+ tail ++ ;
1300+ }
1301+ commit_echoes (tty );
1302+
1303+ return true;
1304+ }
1305+
1306+ if (c == '\n' ) {
1307+ if (L_ECHO (tty ) || L_ECHONL (tty )) {
1308+ echo_char_raw ('\n' , ldata );
1309+ commit_echoes (tty );
1310+ }
1311+ goto handle_newline ;
1312+ }
1313+
1314+ if (c == EOF_CHAR (tty )) {
1315+ c = __DISABLED_CHAR ;
1316+ goto handle_newline ;
1317+ }
1318+
1319+ if ((c == EOL_CHAR (tty )) ||
1320+ (c == EOL2_CHAR (tty ) && L_IEXTEN (tty ))) {
1321+ /*
1322+ * XXX are EOL_CHAR and EOL2_CHAR echoed?!?
1323+ */
1324+ if (L_ECHO (tty )) {
1325+ /* Record the column of first canon char. */
1326+ if (ldata -> canon_head == ldata -> read_head )
1327+ echo_set_canon_col (ldata );
1328+ echo_char (c , tty );
1329+ commit_echoes (tty );
1330+ }
1331+ /*
1332+ * XXX does PARMRK doubling happen for
1333+ * EOL_CHAR and EOL2_CHAR?
1334+ */
1335+ if (c == (unsigned char ) '\377' && I_PARMRK (tty ))
1336+ put_tty_queue (c , ldata );
1337+
1338+ handle_newline :
1339+ set_bit (MASK (ldata -> read_head ), ldata -> read_flags );
1340+ put_tty_queue (c , ldata );
1341+ smp_store_release (& ldata -> canon_head , ldata -> read_head );
1342+ kill_fasync (& tty -> fasync , SIGIO , POLL_IN );
1343+ wake_up_interruptible_poll (& tty -> read_wait , EPOLLIN | EPOLLRDNORM );
1344+ return true;
1345+ }
1346+
1347+ return false;
1348+ }
1349+
12651350static void n_tty_receive_char_special (struct tty_struct * tty , unsigned char c ,
12661351 bool lookahead_done )
12671352{
@@ -1296,77 +1381,8 @@ static void n_tty_receive_char_special(struct tty_struct *tty, unsigned char c,
12961381 } else if (c == '\n' && I_INLCR (tty ))
12971382 c = '\r' ;
12981383
1299- if (ldata -> icanon ) {
1300- if (c == ERASE_CHAR (tty ) || c == KILL_CHAR (tty ) ||
1301- (c == WERASE_CHAR (tty ) && L_IEXTEN (tty ))) {
1302- eraser (c , tty );
1303- commit_echoes (tty );
1304- return ;
1305- }
1306- if (c == LNEXT_CHAR (tty ) && L_IEXTEN (tty )) {
1307- ldata -> lnext = 1 ;
1308- if (L_ECHO (tty )) {
1309- finish_erasing (ldata );
1310- if (L_ECHOCTL (tty )) {
1311- echo_char_raw ('^' , ldata );
1312- echo_char_raw ('\b' , ldata );
1313- commit_echoes (tty );
1314- }
1315- }
1316- return ;
1317- }
1318- if (c == REPRINT_CHAR (tty ) && L_ECHO (tty ) && L_IEXTEN (tty )) {
1319- size_t tail = ldata -> canon_head ;
1320-
1321- finish_erasing (ldata );
1322- echo_char (c , tty );
1323- echo_char_raw ('\n' , ldata );
1324- while (MASK (tail ) != MASK (ldata -> read_head )) {
1325- echo_char (read_buf (ldata , tail ), tty );
1326- tail ++ ;
1327- }
1328- commit_echoes (tty );
1329- return ;
1330- }
1331- if (c == '\n' ) {
1332- if (L_ECHO (tty ) || L_ECHONL (tty )) {
1333- echo_char_raw ('\n' , ldata );
1334- commit_echoes (tty );
1335- }
1336- goto handle_newline ;
1337- }
1338- if (c == EOF_CHAR (tty )) {
1339- c = __DISABLED_CHAR ;
1340- goto handle_newline ;
1341- }
1342- if ((c == EOL_CHAR (tty )) ||
1343- (c == EOL2_CHAR (tty ) && L_IEXTEN (tty ))) {
1344- /*
1345- * XXX are EOL_CHAR and EOL2_CHAR echoed?!?
1346- */
1347- if (L_ECHO (tty )) {
1348- /* Record the column of first canon char. */
1349- if (ldata -> canon_head == ldata -> read_head )
1350- echo_set_canon_col (ldata );
1351- echo_char (c , tty );
1352- commit_echoes (tty );
1353- }
1354- /*
1355- * XXX does PARMRK doubling happen for
1356- * EOL_CHAR and EOL2_CHAR?
1357- */
1358- if (c == (unsigned char ) '\377' && I_PARMRK (tty ))
1359- put_tty_queue (c , ldata );
1360-
1361- handle_newline :
1362- set_bit (MASK (ldata -> read_head ), ldata -> read_flags );
1363- put_tty_queue (c , ldata );
1364- smp_store_release (& ldata -> canon_head , ldata -> read_head );
1365- kill_fasync (& tty -> fasync , SIGIO , POLL_IN );
1366- wake_up_interruptible_poll (& tty -> read_wait , EPOLLIN | EPOLLRDNORM );
1367- return ;
1368- }
1369- }
1384+ if (ldata -> icanon && n_tty_receive_char_canon (tty , c ))
1385+ return ;
13701386
13711387 if (L_ECHO (tty )) {
13721388 finish_erasing (ldata );
0 commit comments