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