--- nono/host/comdriver_stdio.cpp 2026/04/29 17:05:18 1.1.1.2 +++ nono/host/comdriver_stdio.cpp 2026/04/29 17:06:02 1.1.1.4 @@ -8,35 +8,52 @@ // シリアルポートの標準入出力ドライバ // +// 標準入力はここで担当するが、 +// 標準出力はログ出力と共用するため Logger が担当となっている。 + #include "comdriver_stdio.h" #include "hostcom.h" +#include "logger.h" // コンストラクタ COMDriverStdio::COMDriverStdio(HostDevice *hostdev_) - : inherited(hostdev_, "Stdio") + : inherited(hostdev_, "stdio") { - // 現在の端末属性を取得 - tcgetattr(STDIN_FILENO, &oldtc); } // デストラクタ COMDriverStdio::~COMDriverStdio() { + hostdev->DelOuter(STDIN_FILENO); + // 端末属性を元に戻す - tcsetattr(STDIN_FILENO, TCSANOW, &oldtc); + if (tc_changed) { + tcsetattr(STDIN_FILENO, TCSANOW, &oldtc); + } + + stdio_occupied = false; } // ドライバ初期化 bool -COMDriverStdio::InitDriver() +COMDriverStdio::InitDriver(bool startup) { struct termios tc; + if (stdio_occupied) { + errmsg = "'stdio' is already in use by another hostcom-driver"; + putmsg(1, "%s", errmsg.c_str()); + return false; + } + + // 現在の端末属性を取得 + tcgetattr(STDIN_FILENO, &oldtc); + // 端末の設定を変更 tc = oldtc; // 入力時の変換は無し - tc.c_iflag = 0; + tc.c_iflag |= ICRNL; tc.c_lflag &= ~ECHO; // エコーオフ tc.c_lflag &= ~ICANON; // 非カノニカルモード @@ -46,15 +63,19 @@ COMDriverStdio::InitDriver() tc.c_cc[VMIN] = 1; if (tcsetattr(STDIN_FILENO, TCSANOW, &tc) < 0) { - putmsg(0, "tcsetattr: %s", strerror(errno)); + errmsg = string_format("tcsetattr: %s", strerror(errno)); + putmsg(1, "%s", errmsg.c_str()); return false; } + tc_changed = true; if (hostdev->AddOuter(STDIN_FILENO) < 0) { - putmsg(0, "AddOuter: %s", strerror(errno)); + errmsg = string_format("AddOuter: %s", strerror(errno)); + putmsg(1, "%s", errmsg.c_str()); return false; } + stdio_occupied = true; return true; } @@ -62,19 +83,11 @@ COMDriverStdio::InitDriver() void COMDriverStdio::Write(uint32 data) { - uint8 buf[1]; - int r; + char str[2]; - buf[0] = data; - r = write(STDOUT_FILENO, buf, sizeof(buf)); - if (r < 0) { - putmsg(0, "write: %s", strerror(errno)); - return; - } - if (r < sizeof(buf)) { - putmsg(0, "write: short"); - return; - } + str[0] = (uint8)data; + str[1] = '\0'; + logger->WriteStdout(str); } // 外部からの1バイト読み込み @@ -94,3 +107,6 @@ COMDriverStdio::Read() } return buf[0]; } + +// stdio を使えるのは同時に1人だけに限定する。 +/*static*/ bool COMDriverStdio::stdio_occupied = false;