Armadilloフォーラム

コンソール使用時のログインIDで大文字入力による動作

yue110

2014年10月11日 18時16分

製品に組み込んで使用していますが、コンソールで使用する場合、初めのログインIDを入力する箇所で大文字で入力を行う(「TEST」など)と、
それ以降が文字化けや、通常小文字で表示されていた箇所が全て大文字で表示されてしまうなどの現象が出ております。
また、この状態でコンソールをクローズすると、再度接続するまでに5分程度の時間を空けなければ接続できない
などといった症状が発生しています。

このような現象の回避方法や、もしくは対策方法はありませんでしょうか?

ご教授のほど、よろしくお願い致します。

コメント

中村です。

> 製品に組み込んで使用していますが、コンソールで使用する場合、初めのログインIDを入力する箇所で大文字で入力を行う(「TEST」など)と、
> それ以降が文字化けや、通常小文字で表示されていた箇所が全て大文字で表示されてしまうなどの現象が出ております。

昔、大文字しか使えない端末がありました。
しかし、UNIXは小文字のコマンドが基本です。
そのような大文字のみの端末でも小文字コマンドを扱えるように、
ログインのユーザ名が大文字だけの場合には、大文字入力を内部で小文字し、
出力文字は全部大文字に変える機能が入ってます。
いまどきこんな機能は必要ないのですが、busyboxのgettyでは有効に
なっているみたいです。

Debianではこの機能はオプションになってます。(たぶんこれがそれだと思います)
ATDE3のman gettyから引用。

       -U     Turn on support for detecting an uppercase only terminal.   This
              setting  will  detect  a  login name containing only capitals as
              indicating an uppercase only terminal and turn on some upper  to
              lower  case  conversions.  Note that this has no support for any
              unicode characters.

大文字でログインしてsttyで端末の状態をみてみると次のようになっています。
("stty -a"が大文字で表示されてますが小文字で入力<※>)

ROOT@ARMADILLO460-0 (TTYMXC1) /]# STTY -A
SPEED 115200 BAUD; ROWS 0; COLUMNS 0;
INTR = ^C; QUIT = ^\; ERASE = ^?; KILL = ^U; EOF = ^D; EOL = <UNDEF>;
EOL2 = <UNDEF>; START = ^Q; STOP = ^S; SUSP = ^Z; RPRNT = ^R; WERASE = ^W;
LNEXT = ^V; FLUSH = ^O; MIN = 1; TIME = 0;
-PARENB -PARODD CS8 HUPCL -CSTOPB CREAD CLOCAL -CRTSCTS
-IGNBRK -BRKINT -IGNPAR -PARMRK -INPCK -ISTRIP -INLCR -IGNCR ICRNL IXON IXOFF
IUCLC -IXANY -IMAXBEL
OPOST OLCUC -OCRNL ONLCR -ONOCR -ONLRET -OFILL -OFDEL NL0 CR0 TAB0 BS0 VT0 FF0
ISIG ICANON -IEXTEN ECHO ECHOE ECHOK -ECHONL -NOFLSH XCASE -TOSTOP -ECHOPRT
-ECHOCTL ECHOKE

この中で通常と違うのは、次の3つです。
IUCLC OLCUC XCASE

普通に小文字でログインしたときのsttyのこの部分は
-iuclc -olcuc -xcase
です。

文字が化け化けになってしまうのもこの影響で、小文字でログインした後、
$ stty iuclc olcuc xcase
とすると、同じ症状になります。

大文字でログインして全部大文字になってしまった状態で、
$ STTY -IUCLC -OLCUC -XCASE
とすると、(大文字で表示されてますが小文字で入力<※>)
小文字に戻ります。

<※>
Armadillo(4x0で試してます)では、iuclcが効いていないような気がします。
ATDE3ではiuclcすると予想通りに動くのですが、Armadilloではそうならないです。

それから、sttyのmanを見ると、[-]iuclc [-]olcuc [-]xcase をまとめて
制御する[-]lcaseというのもあるようです。
$ stty lcase
$ stty -lcase
$ stty LCASE
$ stty -LCASE

busyboxのgettyのソースをみると、次ところでやっているようです。

user/busybox/busybox-1.00.rc3/loginutils/getty.c

/* get_logname - get user name, establish parity, speed, erase, kill, eol */
/* return NULL on failure, logname on success */
static char *get_logname(struct options *op, struct chardata *cp, struct termio
*tp)
{
    ...
        /* Handle names with upper case and no lower case. */
 
        if ((cp->capslock = caps_lock(logname))) {
                for (bp = logname; *bp; bp++)
                        if (isupper(*bp))
                                *bp = tolower(*bp);     /* map name to lower case */
        }
    ...
}
 
/* termio_final - set the final tty mode bits */
static void termio_final(struct options *op, struct termio *tp, struct chardata
*cp)
    ...
        /* Account for upper case without lower case. */
 
        if (cp->capslock) {
                tp->c_iflag |= IUCLC;
                tp->c_lflag |= XCASE;
                tp->c_oflag |= OLCUC;
        }
    ...
}
 
/* caps_lock - string contains upper case without lower case */
/* returns 1 if true, 0 if false */
static int caps_lock(const char *s)
{
        int capslock;
 
        for (capslock = 0; *s; s++) {
                if (islower(*s))
                        return (0);
                if (capslock == 0)
                        capslock = isupper(*s);
        }
        return (capslock);
}

> また、この状態でコンソールをクローズすると、再度接続するまでに5分程度の時間を空けなけ

これは別の問題だと思います。
initが/etc/inittabのrespawn記述にしたがってコマンドを起動するとき、
一定期間に連続して規定回数起動されると、その後、一定時間のsleepが
入るようになっています。

initのソースの次の部分です。

#define TESTTIME  90    /* Threshold for detecting "fast" spawning processes */
#define MAXSPAWN  5     /* Number of rapid respawns that counts as too fast */
#define SLEEPTIME 300   /* Fast spawn hold off period */
#define DELAYTIME 5     /* Time between successive runs of a process */

> このような現象の回避方法や、もしくは対策方法はありませんでしょうか?

上に書いたソースを直せばできると思います。

--
なかむら

中村です。

元の質問から外れますが・・・

> <※>
> Armadillo(4x0で試してます)では、iuclcが効いていないような気がします。
> ATDE3ではiuclcすると予想通りに動くのですが、Armadilloではそうならないです。

コンソールからログインしたとき、-iextenになっているのが原因のようです。
ttyのソース(driver/char/n_tty.c)に次のようなコードがありました。

static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c)
{
    ...
        if (I_IUCLC(tty) && L_IEXTEN(tty))
                c=tolower(c);
    ...
}

でもって、コンソールからログインしたとき、

[root@armadillo460-0 (ttymxc1) ~]# stty
speed 115200 baud;
-brkint ixoff -imaxbel
-iexten -echoctl

となっています。

Armadilloでもtelnetなどでログインしたときはiextenになっているので、
stty iuclc すると大文字⇒小文字変換は働いてました。

--
なかむら

なかむら様
細かくご説明ありがとうございました。

おかげさまで、御説明いただいた方法で、IDに大文字入力しても文字化けせず、
また、文字化けした場合に終了処理に時間がかかるなどの現象が出なくなりました。

有難うございました。