From: tholo Date: Mon, 16 Dec 1996 20:04:39 +0000 (+0000) Subject: Implement more tty flags for better portability from other systems: X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=fc61cb1e0c1068a7cff15260713ce68d40cd9068;p=openbsd Implement more tty flags for better portability from other systems: XCASE - canonical input/output processing IUCLC - translate uppercase to lowercase on input OLCUC - translate lowercase to uppercase on output OCRNL - translate carriage return to newline on output ONOCR - do not output carriage return at column 0 ONLRET - newline performs carriage return function In addition the tty compatibility interface supports LCASE properly. Look at termios(4) for a more complete description of the above flags. --- diff --git a/bin/stty/key.c b/bin/stty/key.c index 1ab7f305fbc..4b9f40f94ce 100644 --- a/bin/stty/key.c +++ b/bin/stty/key.c @@ -1,4 +1,4 @@ -/* $OpenBSD: key.c,v 1.4 1996/08/02 12:10:21 deraadt Exp $ */ +/* $OpenBSD: key.c,v 1.5 1996/12/16 20:04:39 tholo Exp $ */ /* $NetBSD: key.c,v 1.11 1995/09/07 06:57:11 jtc Exp $ */ /*- @@ -38,7 +38,7 @@ #if 0 static char sccsid[] = "@(#)key.c 8.4 (Berkeley) 2/20/95"; #else -static char rcsid[] = "$OpenBSD: key.c,v 1.4 1996/08/02 12:10:21 deraadt Exp $"; +static char rcsid[] = "$OpenBSD: key.c,v 1.5 1996/12/16 20:04:39 tholo Exp $"; #endif #endif /* not lint */ @@ -61,6 +61,7 @@ void f_dec __P((struct info *)); void f_everything __P((struct info *)); void f_extproc __P((struct info *)); void f_ispeed __P((struct info *)); +void f_lcase __P((struct info *)); void f_nl __P((struct info *)); void f_ospeed __P((struct info *)); void f_raw __P((struct info *)); @@ -89,6 +90,7 @@ static struct key { { "everything", f_everything, 0 }, { "extproc", f_extproc, F_OFFOK }, { "ispeed", f_ispeed, F_NEEDARG }, + { "lcase", f_lcase, 0 }, { "new", f_tty, 0 }, { "nl", f_nl, F_OFFOK }, { "old", f_tty, 0 }, @@ -220,6 +222,22 @@ f_ispeed(ip) ip->set = 1; } +void +f_lcase(ip) + struct info *ip; +{ + if (ip->off) { + ip.t_iflag &= ~IUCLC; + ip.t_oflag &= ~OLCUC; + ip.t_lflag &= ~XCASE; + } else { + ip.t_iflag |= IUCLC; + ip.t_oflag |= OLCUC; + ip.t_lflag |= XCASE; + } + ip->set = 1; +} + void f_nl(ip) struct info *ip; diff --git a/bin/stty/modes.c b/bin/stty/modes.c index 1c4cc17428d..4807ac5e00e 100644 --- a/bin/stty/modes.c +++ b/bin/stty/modes.c @@ -1,4 +1,4 @@ -/* $OpenBSD: modes.c,v 1.3 1996/06/23 14:21:51 deraadt Exp $ */ +/* $OpenBSD: modes.c,v 1.4 1996/12/16 20:04:41 tholo Exp $ */ /* $NetBSD: modes.c,v 1.9 1996/05/07 18:20:09 jtc Exp $ */ /*- @@ -38,7 +38,7 @@ #if 0 static char sccsid[] = "@(#)modes.c 8.3 (Berkeley) 4/2/94"; #else -static char rcsid[] = "$OpenBSD: modes.c,v 1.3 1996/06/23 14:21:51 deraadt Exp $"; +static char rcsid[] = "$OpenBSD: modes.c,v 1.4 1996/12/16 20:04:41 tholo Exp $"; #endif #endif /* not lint */ @@ -110,6 +110,8 @@ const struct modes imodes[] = { { "-igncr", 0, IGNCR }, { "icrnl", ICRNL, 0 }, { "-icrnl", 0, ICRNL }, + { "iuclc", IUCLC, 0 }, + { "-iuclc", 0, IUCLC }, { "ixon", IXON, 0 }, { "-ixon", 0, IXON }, { "flow", IXON, 0 }, @@ -176,6 +178,8 @@ const struct modes lmodes[] = { { "-nokerninfo",0, NOKERNINFO }, { "kerninfo", 0, NOKERNINFO }, { "-kerninfo", NOKERNINFO, 0 }, + { "xcase", XCASE, 0 }, + { "-xcase", 0, XCASE }, { NULL }, }; @@ -184,8 +188,16 @@ const struct modes omodes[] = { { "-opost", 0, OPOST }, { "litout", 0, OPOST }, { "-litout", OPOST, 0 }, + { "ocrnl", OCRNL, 0 }, + { "-ocrnl", 0, OCRNL }, + { "olcuc", OLCUC, 0 }, + { "-olcuc", 0, OLCUC }, { "onlcr", ONLCR, 0 }, { "-onlcr", 0, ONLCR }, + { "onlret", ONLRET, 0 }, + { "-onlret", 0, ONLRET }, + { "onocr", ONOCR, 0 }, + { "-onocr", 0, ONOCR }, { "tabs", 0, OXTABS }, /* "preserve" tabs */ { "-tabs", OXTABS, 0 }, { "oxtabs", OXTABS, 0 }, diff --git a/bin/stty/stty.1 b/bin/stty/stty.1 index 1c643d434ee..6ed86180a62 100644 --- a/bin/stty/stty.1 +++ b/bin/stty/stty.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: stty.1,v 1.4 1996/12/10 09:06:01 deraadt Exp $ +.\" $OpenBSD: stty.1,v 1.5 1996/12/16 20:04:42 tholo Exp $ .\" $NetBSD: stty.1,v 1.10 1995/09/07 06:57:14 jtc Exp $ .\" .\" Copyright (c) 1990, 1993, 1994 @@ -189,6 +189,9 @@ Map (do not map) to .Dv NL on input. +.It Cm iuclc Pq Fl iuclc +Translate (do not translate) upper case to lower case +on input. .It Cm ixon Pq Fl ixon Enable (disable) .Dv START/STOP @@ -241,6 +244,14 @@ Map (do not map) to .Dv CR-NL on output. +.It Cm ocrnl Pq Fl ocrnl +Translate (do not translate) carriage return to newline on output. +.It Cm onocr Pq Fl onocr +Carriage return is output (is not output) at column 0. +.It Cm onlret Pq Fl onlret +Newline performs (does not perform) carriage return on output. +.It Cm olcuc Pq Fl olcuc +Translate (do not translate) lower case to upper case on output. .It Cm oxtabs Pq Fl oxtabs Expand (do not expand) tabs to spaces on output. .El @@ -351,6 +362,12 @@ Indicates output is (is not) being discarded. Indicates input is (is not) pending after a switch from non-canonical to canonical mode and will be re-input when a read becomes pending or more input arrives. +.It Cm xcase Pq Fl xcase +Upper and lower case is (is not) handled canonically on input and output +with +.Cm iuclc +and +.Cm olcuc . .El .Ss Control Characters: .Bl -tag -width Fl @@ -553,6 +570,12 @@ Same as .It Cm prterase Pq Fl prterase Same as .Cm echoprt . +.It Cm lcase Pq Fl lcase +Same as +.Cm iuclc , +.Cm olcuc +and +.Cm xcase . .It Cm litout Pq Fl litout The converse of .Cm opost . diff --git a/libexec/getty/subr.c b/libexec/getty/subr.c index f2c8dc5c0e7..14ed2aa2079 100644 --- a/libexec/getty/subr.c +++ b/libexec/getty/subr.c @@ -33,7 +33,7 @@ #ifndef lint /*static char sccsid[] = "from: @(#)subr.c 8.1 (Berkeley) 6/4/93";*/ -static char rcsid[] = "$Id: subr.c,v 1.5 1996/12/16 17:14:03 deraadt Exp $"; +static char rcsid[] = "$Id: subr.c,v 1.6 1996/12/16 20:04:45 tholo Exp $"; #endif /* not lint */ /* @@ -388,15 +388,27 @@ register long flags; SET(oflag, OXTABS); else CLR(oflag, OXTABS); + if (ISSET(flags, LCASE)) + SET(iflag, IUCLC); + SET(oflag, OLCUC); + SET(lflag, XCASE); + } + else { + CLR(iflag, IUCLC); + CLR(oflag, OLCUC); + CLR(lflag, XCASE); + } if (ISSET(flags, RAW)) { iflag &= IXOFF; - CLR(lflag, ISIG|ICANON|IEXTEN); + CLR(lflag, ISIG|ICANON|IEXTEN|XCASE); CLR(cflag, PARENB); } else { SET(iflag, BRKINT|IXON|IMAXBEL); SET(lflag, ISIG|IEXTEN); + if (ISSET(iflag, IUCLC) && ISSET(oflag, OLCUC)) + SET(lflag, XCASE); if (ISSET(flags, CBREAK)) CLR(lflag, ICANON); else diff --git a/share/man/man4/termios.4 b/share/man/man4/termios.4 index 8af099752a8..ed6ee4cd24f 100644 --- a/share/man/man4/termios.4 +++ b/share/man/man4/termios.4 @@ -793,6 +793,8 @@ following masks: /* any char will restart after stop */ .It Dv IMAXBEL /* ring bell on input queue full */ +.It Dv IUCLC +/* translate upper case to lower case */ .El .Pp In the context of asynchronous serial data transmission, a break @@ -960,6 +962,11 @@ is set and the input queue is full, subsequent input shall cause an character to be transmitted to the output queue. .Pp +If +.Dv IUCLC +is set, characters will be translated from upper to lower case on +input. +.Pp The initial input control value after open() is implementation defined. .Ss Output Modes Values of the @@ -981,6 +988,14 @@ and are composed of the following masks: .Dv EOT Ns 's .Ql \&^D on output) */ +.It Dv OCRNL +/* map CR to NL */ +.It Dv OLCUC +/* translate lower case to upper case */ +.It Dv ONOCR +/* No CR output at column 0 */ +.It Dv ONLRET +/* NL performs CR function */ .El .Pp If @@ -1003,6 +1018,23 @@ is set, .Tn ASCII .Dv EOT NS 's are discarded on output. +.Pp +If +.Dv OCRNL +is set, carriage returns are translated to newlines. +.Pp +If +.Dv OLCUC +is set, lower case is translated to upper case on output. +.Pp +If +.Dv ONOCR +is set, no CR character is output when at column 0. +.Pp +If +.Dv ONLRET +is set, NL also performs CR on output, and reset current +column to 0. .Ss Control Modes Values of the .Fa c_cflag @@ -1181,6 +1213,8 @@ and /* XXX retype pending input (state) */ .It Dv NOFLSH /* don't flush after interrupt */ +.It Dv XCASE +/* canonical upper/lower case */ .El .Pp If @@ -1336,6 +1370,26 @@ characters are not be done. .Pp If +.Dv XCASE +and +.Dv ICANON +is set, an upper case character is preserved on input if prefixed by +a \\ character. In addition, this prefix is added to upper case +characters on output. +.Pp +In addition, the following special character translations are in effect: +.Pp +.Bl -column "for:" "use:" -offset indent -compact +.It Em "for: use:" +.It Dv ` Ta \&\e' +.It Dv | Ta \&\e! +.It Dv ~ Ta \&\e^ +.It Dv { Ta \&\e( +.It Dv } Ta \&\e) +.It Dv \&\e Ta \&\e\e +.El +.Pp +If .Dv TOSTOP is set, the signal .Dv SIGTTOU diff --git a/sys/compat/common/tty_43.c b/sys/compat/common/tty_43.c index fd60b69c74d..765a63a236d 100644 --- a/sys/compat/common/tty_43.c +++ b/sys/compat/common/tty_43.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tty_43.c,v 1.4 1996/05/23 08:32:23 deraadt Exp $ */ +/* $OpenBSD: tty_43.c,v 1.5 1996/12/16 20:04:52 tholo Exp $ */ /* $NetBSD: tty_43.c,v 1.5 1996/05/20 14:29:17 mark Exp $ */ /*- @@ -307,6 +307,8 @@ ttcompatgetflags(tp) SET(flags, MDMBUF); if (!ISSET(cflag, HUPCL)) SET(flags, NOHANG); + if (ISSET(cflag, XCASE) && ISSET(iflag, IUCLC) && ISSET(oflag, OLCUC)) + SET(flags, LCASE); if (ISSET(oflag, OXTABS)) SET(flags, XTABS); if (ISSET(lflag, ECHOE)) @@ -355,10 +357,20 @@ ttcompatsetflags(tp, t) SET(oflag, OXTABS); else CLR(oflag, OXTABS); + if (ISSET(flags, LCASE)) { + SET(iflag, IUCLC); + SET(oflag, OLCUC); + SET(cflag, XCASE); + } + else { + CLR(iflag, IUCLC); + CLR(oflag, OLCUC); + CLR(cflag, XCASE); + } if (ISSET(flags, RAW)) { - iflag &= IXOFF; + iflag &= IXOFF|IXANY; CLR(lflag, ISIG|ICANON|IEXTEN); CLR(cflag, PARENB); } else { @@ -390,7 +402,7 @@ ttcompatsetflags(tp, t) } if (ISSET(flags, RAW|LITOUT|PASS8)) { - CLR(cflag, CSIZE); + CLR(cflag, CSIZE|XCASE); SET(cflag, CS8); if (!ISSET(flags, RAW|PASS8)) SET(iflag, ISTRIP); @@ -403,6 +415,8 @@ ttcompatsetflags(tp, t) } else { CLR(cflag, CSIZE); SET(cflag, CS7); + if (ISSET(iflag, IUCLC) && ISSET(oflag, OLCUC)) + SET(cflag, XCASE); SET(iflag, ISTRIP); SET(oflag, OPOST); } @@ -454,6 +468,11 @@ ttcompatsetlflags(tp, t) SET(iflag, IXANY); else CLR(iflag, IXANY); + if (ISSET(flags, LCASE)) { + SET(oflag, OLCUC); + SET(iflag, IUCLC); + SET(cflag, XCASE); + } CLR(lflag, TOSTOP|FLUSHO|PENDIN|NOFLSH); SET(lflag, ISSET(flags, TOSTOP|FLUSHO|PENDIN|NOFLSH)); @@ -466,13 +485,17 @@ ttcompatsetlflags(tp, t) CLR(iflag, ISTRIP); if (!ISSET(flags, RAW|LITOUT)) SET(oflag, OPOST); - else + else { CLR(oflag, OPOST); + CLR(cflag, XCASE); + } } else { CLR(cflag, CSIZE); SET(cflag, CS7); SET(iflag, ISTRIP); SET(oflag, OPOST); + if (ISSET(oflag, OLCUC) && ISSET(iflag, IUCLC)) + SET(cflag, XCASE); } t->c_iflag = iflag; diff --git a/sys/kern/tty.c b/sys/kern/tty.c index 9d698fccd82..e00ba6a1bbf 100644 --- a/sys/kern/tty.c +++ b/sys/kern/tty.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tty.c,v 1.20 1996/12/08 14:25:48 niklas Exp $ */ +/* $OpenBSD: tty.c,v 1.21 1996/12/16 20:04:54 tholo Exp $ */ /* $NetBSD: tty.c,v 1.68.4.2 1996/06/06 16:04:52 thorpej Exp $ */ /*- @@ -158,6 +158,12 @@ u_char const char_type[] = { #define CLR(t, f) (t) &= ~((unsigned)(f)) #define ISSET(t, f) ((t) & (f)) +#define islower(c) ((c) >= 'a' && (c) <= 'z') +#define isupper(c) ((c) >= 'A' && (c) <= 'Z') + +#define tolower(c) ((c) - 'A' + 'a') +#define toupper(c) ((c) - 'a' + 'A') + struct ttylist_head ttylist; /* TAILQ_HEAD */ int tty_count; @@ -396,6 +402,39 @@ parmrk: (void)putc(0377 | TTY_QUOTE, &tp->t_rawq); * From here on down canonical mode character * processing takes place. */ + /* + * upper case or specials with IUCLC and XCASE + */ + if (ISSET(lflag, XCASE) && ISSET(iflag, IUCLC)) { + if (ISSET(tp->t_state, TS_BKSL)) { + CLR(tp->t_state, TS_BKSL); + switch (c) { + case '\'': + c = '`'; + break; + case '!': + c = '|'; + break; + case '^': + c = '~'; + break; + case '(': + c = '{'; + break; + case ')': + c = '}'; + break; + } + } + else if (c == '\\') { + SET(tp->t_state, TS_BKSL); + goto endcase; + } + else if (isupper(c)) + c = tolower(c); + } + else if (ISSET(iflag, IUCLC) && isupper(c)) + c = tolower(c); /* * erase (^H / ^?) */ @@ -555,7 +594,7 @@ ttyoutput(c, tp) register struct tty *tp; { register long oflag; - register int col, notout, s; + register int col, notout, s, c2; oflag = tp->t_oflag; if (!ISSET(oflag, OPOST)) { @@ -595,7 +634,8 @@ ttyoutput(c, tp) /* * Newline translation: if ONLCR is set, - * translate newline into "\r\n". + * translate newline into "\r\n". If OCRNL + * is set, translate '\r' into '\n'. */ if (c == '\n' && ISSET(tp->t_oflag, ONLCR)) { tk_nout++; @@ -603,6 +643,41 @@ ttyoutput(c, tp) if (putc('\r', &tp->t_outq)) return (c); } + else if (c == '\r' && ISSET(tp->t_oflag, OCRNL)) + c = '\n'; + + if (ISSET(tp->t_oflag, OLCUC) && islower(c)) + c = toupper(c); + else if (ISSET(tp->t_oflag, OLCUC) && ISSET(tp->t_lflag, XCASE)) { + c2 = c; + switch (c) { + case '`': + c2 = '\''; + break; + case '|': + c2 = '!'; + break; + case '~': + c2 = '^'; + break; + case '{': + c2 = '('; + break; + case '}': + c2 = ')'; + break; + } + if (c == '\\' || isupper(c) || c != c2) { + tk_nout++; + tp->t_outcc++; + if (putc('\\', &tp->t_outq)) + return (c); + c = c2; + } + } + if (ISSET(tp->t_oflag, ONOCR) && c == '\r' && tp->t_column == 0) + return (-1); + tk_nout++; tp->t_outcc++; if (!ISSET(tp->t_lflag, FLUSHO) && putc(c, &tp->t_outq)) @@ -617,6 +692,9 @@ ttyoutput(c, tp) case CONTROL: break; case NEWLINE: + if (ISSET(tp->t_oflag, ONLRET)) + col = 0; + break; case RETURN: col = 0; break; diff --git a/sys/sys/termios.h b/sys/sys/termios.h index 9e5102fc662..4639c218806 100644 --- a/sys/sys/termios.h +++ b/sys/sys/termios.h @@ -1,4 +1,4 @@ -/* $OpenBSD: termios.h,v 1.5 1996/10/26 06:54:42 tholo Exp $ */ +/* $OpenBSD: termios.h,v 1.6 1996/12/16 20:04:56 tholo Exp $ */ /* $NetBSD: termios.h,v 1.14 1996/04/09 20:55:41 cgd Exp $ */ /* @@ -102,6 +102,7 @@ #define IXOFF 0x00000400 /* enable input flow control */ #ifndef _POSIX_SOURCE #define IXANY 0x00000800 /* any char will restart after stop */ +#define IUCLC 0x00001000 /* translate upper to lower case */ #define IMAXBEL 0x00002000 /* ring bell on input queue full */ #endif /*_POSIX_SOURCE */ @@ -113,6 +114,10 @@ #define ONLCR 0x00000002 /* map NL to CR-NL (ala CRMOD) */ #define OXTABS 0x00000004 /* expand tabs to spaces */ #define ONOEOT 0x00000008 /* discard EOT's (^D) on output) */ +#define OCRNL 0x00000010 /* map CR to NL */ +#define OLCUC 0x00000020 /* translate lower case to upper case */ +#define ONOCR 0x00000040 /* No CR output at column 0 */ +#define ONLRET 0x00000080 /* NL performs the CR function */ #endif /*_POSIX_SOURCE */ /* @@ -170,6 +175,7 @@ #define TOSTOP 0x00400000 /* stop background jobs from output */ #ifndef _POSIX_SOURCE #define FLUSHO 0x00800000 /* output being flushed (state) */ +#define XCASE 0x01000000 /* canonical upper/lower case */ #define NOKERNINFO 0x02000000 /* no kernel output from VSTATUS */ #define PENDIN 0x20000000 /* XXX retype pending input (state) */ #endif /*_POSIX_SOURCE */ diff --git a/usr.sbin/lpr/lpd/modes.c b/usr.sbin/lpr/lpd/modes.c index 7436a9f3335..9e08017c415 100644 --- a/usr.sbin/lpr/lpd/modes.c +++ b/usr.sbin/lpr/lpd/modes.c @@ -111,6 +111,8 @@ struct modes imodes[] = { { "-igncr", 0, IGNCR }, { "icrnl", ICRNL, 0 }, { "-icrnl", 0, ICRNL }, + { "iuclc", IUCLC, 0 }, + { "-iuclc", 0, IUCLC }, { "ixon", IXON, 0 }, { "-ixon", 0, IXON }, { "flow", IXON, 0 }, @@ -177,6 +179,8 @@ struct modes lmodes[] = { { "-nokerninfo",0, NOKERNINFO }, { "kerninfo", 0, NOKERNINFO }, { "-kerninfo", NOKERNINFO, 0 }, + { "xcase", XCASE, 0 }, + { "-xcase", 0, XCASE }, { NULL }, }; @@ -185,8 +189,16 @@ struct modes omodes[] = { { "-opost", 0, OPOST }, { "litout", 0, OPOST }, { "-litout", OPOST, 0 }, + { "ocrnl", OCRNL, 0 }, + { "-ocrnl", 0, OCRNL }, + { "olcuc", OLCUC, 0 }, + { "-olcuc", 0, OLCUC }, { "onlcr", ONLCR, 0 }, { "-onlcr", 0, ONLCR }, + { "onlret", ONLRET, 0 }, + { "-onlret", 0, ONLRET }, + { "onocr", ONOCR, 0 }, + { "-onocr", 0, ONOCR }, { "tabs", 0, OXTABS }, /* "preserve" tabs */ { "-tabs", OXTABS, 0 }, { "oxtabs", OXTABS, 0 }, diff --git a/usr.sbin/lpr/lpd/ttcompat.c b/usr.sbin/lpr/lpd/ttcompat.c index a31a0dbb594..f368871dbcd 100644 --- a/usr.sbin/lpr/lpd/ttcompat.c +++ b/usr.sbin/lpr/lpd/ttcompat.c @@ -82,6 +82,8 @@ sttygetoflags(tp) if (!ISSET(oflag, OPOST)) SET(flags, LITOUT); } + if (ISSET(lflag, XCASE)) + SET(flags, LCASE); if (!ISSET(lflag, ICANON)) { /* fudge */ @@ -107,7 +109,7 @@ sttysetoflags(tp, flags) if (ISSET(flags, RAW)) { iflag &= IXOFF; - CLR(lflag, ISIG|ICANON|IEXTEN); + CLR(lflag, ISIG|ICANON|IEXTEN|XCASE); CLR(cflag, PARENB); } else { SET(iflag, BRKINT|IXON|IMAXBEL); @@ -116,6 +118,8 @@ sttysetoflags(tp, flags) CLR(lflag, ICANON); else SET(lflag, ICANON); + if (ISSET(iflag, IUCLC) && ISSET(oflag, OLCUC)) + SET(lflag, XCASE); switch (ISSET(flags, ANYP)) { case 0: CLR(cflag, PARENB); @@ -180,6 +184,11 @@ sttyclearflags(tp, flags) CLR(iflag, ICRNL); CLR(oflag, ONLCR); } + if (ISSET(flags, LCASE)) { + CLR(iflag, IUCLC); + CLR(oflag, OLCUC); + CLR(lflag, XCASE); + } if (ISSET(flags, XTABS)) CLR(oflag, OXTABS); @@ -211,6 +220,11 @@ sttysetflags(tp, flags) SET(iflag, ICRNL); SET(oflag, ONLCR); } + if (ISSET(flags, LCASE)) { + SET(iflag, IUCLC); + SET(oflag, OLCUC); + SET(lflag, XCASE); + } if (ISSET(flags, XTABS)) SET(oflag, OXTABS);