|
|
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;
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.