--- nono/host/netdriver_slirp.cpp 2026/04/29 17:05:51 1.1.1.4 +++ nono/host/netdriver_slirp.cpp 2026/04/29 17:06:02 1.1.1.5 @@ -163,7 +163,7 @@ NetDriverSlirp::Close() // モニタ (ドライバ依存情報のみ) void -NetDriverSlirp::MonitorUpdateMD(TextScreen& screen, int y) +NetDriverSlirp::MonitorScreenMD(TextScreen& screen, int y) { // なし } @@ -174,7 +174,7 @@ void NetDriverSlirp::Write(const void *buf, int buflen) { struct iovec iov[2]; - ssize_t r; + ssize_t n; // 先頭4バイトに後続パケット長を入れておく。 static_assert(sizeof(buflen) == sizeof(uint32), ""); @@ -182,9 +182,14 @@ NetDriverSlirp::Write(const void *buf, i iov[0].iov_len = sizeof(buflen); iov[1].iov_base = const_cast(buf); iov[1].iov_len = buflen; - r = writev(txd, &iov[0], countof(iov)); - if (r < 0) { - putmsg(0, "writev failed: %s", strerror(errno)); + n = writev(txd, &iov[0], countof(iov)); + if (n < 0) { + putmsg(0, "writev(%zu+%d) failed: %s", + sizeof(buflen), buflen, strerror(errno)); + return; + } + if (n < sizeof(buflen) + buflen) { + putmsg(0, "writev(%zu+%d): short(%zd)", sizeof(buflen), buflen, n); return; } } @@ -194,25 +199,58 @@ NetDriverSlirp::Write(const void *buf, i int NetDriverSlirp::Read(NetPacket *p) { - ssize_t n; - uint32 len; + std::vector databuf; + ssize_t r; + ssize_t len; + ssize_t bufsize; + uint8 *buf; + uint32 datalen; // 先頭4バイトに後続パケット長を入れてある。 - len = 0; - n = read(rxd, &len, sizeof(len)); - if (n < 0) { - putmsg(0, "read(len) failed: %s", strerror(errno)); - return NODATA; + buf = reinterpret_cast(&datalen); + bufsize = sizeof(datalen); + for (len = 0; len < bufsize; ) { + r = read(rxd, buf + len, bufsize - len); + if (r < 0) { + putmsg(0, "read(len) failed: %s", strerror(errno)); + goto nodata; + } + if (r == 0) { + putmsg(0, "read(len) failed: EOF?"); + goto nodata; + } + len += r; } - n = read(rxd, p->data(), len); - if (n < 0) { - putmsg(0, "read(buf) failed: %s", strerror(errno)); - return NODATA; + // データ本体。 + databuf.resize(datalen); + len = 0; + for (auto datasize = databuf.size(); len < datasize; ) { + r = read(rxd, databuf.data() + len, datasize - len); + if (r < 0) { + putmsg(0, "read(data) failed: %s", strerror(errno)); + goto nodata; + } + if (r == 0) { + putmsg(0, "read(data) failed: EOF?"); + goto nodata; + } + len += r; } + p->Assign(databuf.data(), len); - p->length = n; return 0; + + nodata: + // 一旦全部読み捨てるくらいしか。 + std::vector dropbuf(1024); + for (;;) { + r = read(rxd, dropbuf.data(), dropbuf.size()); + if (r <= 0) { + break; + } + } + return NODATA; } // usermode を使えるのは同時に1人だけに限定する。 @@ -447,7 +485,7 @@ SlirpThread::InitBackend(const std::stri monitor = gMonitorManager->Find(ID_MONITOR_SLIRP); assert(monitor); monitor->obj = this; - monitor->func = ToMonitorCallback(&SlirpThread::MonitorUpdate); + monitor->SetCallback(&SlirpThread::MonitorScreen); monitor->SetSize(80, 40); return true; @@ -758,6 +796,9 @@ void SlirpThread::Terminate() { txd_r.Close(); + txd_w.Close(); + rxd_r.Close(); + rxd_w.Close(); } // スレッド @@ -768,7 +809,7 @@ SlirpThread::ThreadRun() while (exit_requested == false) { // タイマー処理。 - int64 cur_msec = ClockGetNsCB() / 1000'000; + int64 cur_msec = nsec_to_msec(ClockGetNsCB()); for (auto it = timerlist.begin(); it != timerlist.end(); ) { SlirpTimer *timer = *it; if (timer->expire_msec <= cur_msec) { @@ -1139,7 +1180,7 @@ SlirpThread::UpdateInfo() } void -SlirpThread::MonitorUpdate(Monitor *, TextScreen& screen) +SlirpThread::MonitorScreen(Monitor *, TextScreen& screen) { std::string local_conn; std::string local_nbr;