Annotation of nono/host/comdriver_stdio.cpp, revision 1.1.1.3

1.1       root        1: //
                      2: // nono
                      3: // Copyright (C) 2021 nono project
                      4: // Licensed under nono-license.txt
                      5: //
                      6: 
                      7: //
                      8: // シリアルポートの標準入出力ドライバ
                      9: //
                     10: 
                     11: #include "comdriver_stdio.h"
                     12: #include "hostcom.h"
                     13: 
                     14: // コンストラクタ
                     15: COMDriverStdio::COMDriverStdio(HostDevice *hostdev_)
1.1.1.3 ! root       16:        : inherited(hostdev_, "stdio")
1.1       root       17: {
                     18: }
                     19: 
                     20: // デストラクタ
                     21: COMDriverStdio::~COMDriverStdio()
                     22: {
1.1.1.3 ! root       23:        hostdev->DelOuter(STDIN_FILENO);
        !            24: 
1.1       root       25:        // 端末属性を元に戻す
1.1.1.3 ! root       26:        if (tc_changed) {
        !            27:                tcsetattr(STDIN_FILENO, TCSANOW, &oldtc);
        !            28:        }
        !            29: 
        !            30:        stdio_occupied = false;
1.1       root       31: }
                     32: 
                     33: // ドライバ初期化
                     34: bool
1.1.1.3 ! root       35: COMDriverStdio::InitDriver(bool startup)
1.1       root       36: {
                     37:        struct termios tc;
                     38: 
1.1.1.3 ! root       39:        if (stdio_occupied) {
        !            40:                errmsg = "'stdio' is already in use by another hostcom-driver";
        !            41:                putmsg(1, "%s", errmsg.c_str());
        !            42:                return false;
        !            43:        }
        !            44: 
        !            45:        // 現在の端末属性を取得
        !            46:        tcgetattr(STDIN_FILENO, &oldtc);
        !            47: 
1.1       root       48:        // 端末の設定を変更
                     49:        tc = oldtc;
                     50: 
                     51:        // 入力時の変換は無し
                     52:        tc.c_iflag = 0;
                     53: 
                     54:        tc.c_lflag &= ~ECHO;    // エコーオフ
                     55:        tc.c_lflag &= ~ICANON;  // 非カノニカルモード
                     56:        tc.c_lflag &= ~IEXTEN;  // DISCARD(^O)と LNEXT をオフ?
1.1.1.2   root       57:        tc.c_lflag &= ~ISIG;    // シグナルを生成しない
1.1       root       58:        tc.c_cc[VTIME] = 0;
                     59:        tc.c_cc[VMIN] = 1;
                     60: 
                     61:        if (tcsetattr(STDIN_FILENO, TCSANOW, &tc) < 0) {
1.1.1.3 ! root       62:                errmsg = string_format("tcsetattr: %s", strerror(errno));
        !            63:                putmsg(1, "%s", errmsg.c_str());
1.1       root       64:                return false;
                     65:        }
1.1.1.3 ! root       66:        tc_changed = true;
1.1       root       67: 
                     68:        if (hostdev->AddOuter(STDIN_FILENO) < 0) {
1.1.1.3 ! root       69:                errmsg = string_format("AddOuter: %s", strerror(errno));
        !            70:                putmsg(1, "%s", errmsg.c_str());
1.1       root       71:                return false;
                     72:        }
                     73: 
1.1.1.3 ! root       74:        stdio_occupied = true;
1.1       root       75:        return true;
                     76: }
                     77: 
                     78: // 外部への1バイト書き出し
                     79: void
                     80: COMDriverStdio::Write(uint32 data)
                     81: {
                     82:        uint8 buf[1];
                     83:        int r;
                     84: 
                     85:        buf[0] = data;
                     86:        r = write(STDOUT_FILENO, buf, sizeof(buf));
                     87:        if (r < 0) {
                     88:                putmsg(0, "write: %s", strerror(errno));
                     89:                return;
                     90:        }
                     91:        if (r < sizeof(buf)) {
                     92:                putmsg(0, "write: short");
                     93:                return;
                     94:        }
                     95: }
                     96: 
                     97: // 外部からの1バイト読み込み
                     98: int
                     99: COMDriverStdio::Read()
                    100: {
                    101:        uint8 buf[1];
                    102:        int r;
                    103: 
                    104:        r = read(STDIN_FILENO, buf, sizeof(buf));
                    105:        if (r < 0) {
                    106:                putmsg(0, "read: %s", strerror(errno));
                    107:                return NODATA;
                    108:        }
                    109:        if (r == 0) {
                    110:                return NODATA;
                    111:        }
                    112:        return buf[0];
                    113: }
1.1.1.3 ! root      114: 
        !           115: // stdio を使えるのは同時に1人だけに限定する。
        !           116: /*static*/ bool COMDriverStdio::stdio_occupied = false;

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.