File:  [Isaki's NoNo m68k/m88k emulator] / nono / debugger / consio.cpp
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Wed Apr 29 17:04:28 2026 UTC (2 months, 3 weeks ago) by root
Branches: MAIN, Isaki
CVS tags: v002, v001, HEAD
nono 0.0.1

//
// nono
// Copyright (C) 2019 [email protected]
//

#include "header.h"
#include "configfile.h"
#include "consio.h"
#include <poll.h>
#include <netdb.h>
#include <sys/socket.h>

// コンストラクタ
ConsioTCP::ConsioTCP()
{
	ls = -1;
	sock = -1;
}

// デストラクタ
ConsioTCP::~ConsioTCP()
{
	if (res) {
		freeaddrinfo(res);
		res = NULL;
	}
	if (sock != -1) {
		close(sock);
		sock = -1;
	}
	if (ls != -1) {
		close(ls);
		ls = -1;
	}
}

// 初期化
bool
ConsioTCP::Init()
{
	struct addrinfo hints;
	int r;
	int on = 1;

	memset(&hints, 0, sizeof(hints));
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_flags = AI_PASSIVE;

	const char *host = "::1";
	std::string port = gConfig->ReadStr("debugger_port", "9999");
printf("debugger_port=%s\n", port.c_str());

	r = getaddrinfo(host, port.c_str(), &hints, &res);
	if (r != 0) {
		const char *errmsg;
		if (r == EAI_SYSTEM) {
			errmsg = strerror(errno);
		} else {
			errmsg = gai_strerror(r);
		}
		warnx("getaddrinfo: %s: %s", host, errmsg);
		return false;
	}
	if (res == NULL) {
		warnx("getaddrinfo: %s: no address found", host);
		return false;
	}

	// res を順番に試して成功したらそれで待ち受ける
	ls = -1;
	for (ai = res; ai && ls == -1; ai = ai->ai_next) {
		ls = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
		if (ls == -1) {
			warn("socket");
			continue;
		}

		if (setsockopt(ls, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on))) {
			warn("setsockopt(SO_REUSEADDR)");
			close(ls);
			continue;
		}

		if (setsockopt(ls, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on))) {
			warn("setsockopt(SO_REUSEPORT)");
			close(ls);
			continue;
		}

		if (bind(ls, ai->ai_addr, ai->ai_addrlen) == -1) {
			warn("bind");
			close(ls);
			continue;
		}

		if (listen(ls, 0) == -1) {
			warn("listen");
			close(ls);
			continue;
		}

		// ここまで来たら成功
		break;
	}

	if (ls == -1) {
		return false;
	}

	return true;
}

bool
ConsioTCP::Open()
{
	// 待ち受け
	for (;;) {
		sock = accept(ls, ai->ai_addr, &ai->ai_addrlen);
		if (sock == -1) {
			if (errno == EINTR) {
				continue;
			}
			warn("accept");
			return false;
		}
		break;
	}

	return true;
}

void
ConsioTCP::Close()
{
	if (sock != -1) {
		close(sock);
		sock = -1;
	}
}

void
ConsioTCP::Print(const char *fmt, ...)
{
	char buf[1024];
	va_list ap;
	int len;
	int r;

	if (sock == -1) {
		errno = EBADF;
		return;
	}

	va_start(ap, fmt);
	len = vsnprintf(buf, sizeof(buf), fmt, ap);
	va_end(ap);

	len = std::min(len, (int)sizeof(buf));
	r = write(sock, buf, len);
	if (r == -1)
		Close();
}

void
ConsioTCP::Flush()
{
}

int
ConsioTCP::GetChar()
{
	char ch;
	int r;

	if (sock == -1) {
		errno = EBADF;
		return -1;
	}

	r = read(sock, &ch, 1);
	if (r == -1) {
		Close();
		return -1;
	}
	return ch;
}

int
ConsioTCP::Gets(char *buf, int bufsize)
{
	int len;
	int r;

	if (sock == -1) {
		errno = EBADF;
		return -1;
	}

	for (len = 0; len < bufsize - 1; ) {
		r = read(sock, buf + len, 1);
		if (r == 0) {
			goto done;
		}
		if (r == -1) {
			Close();
			return -1;
		}
		char c = buf[len];
		len++;

		if (c == '\n') {
			break;
		}
	}

 done:
	buf[len] = '\0';
	return len;
}

int
ConsioTCP::Poll()
{
	struct pollfd pfd;

	if (sock == -1) {
		errno = EBADF;
		return -1;
	}

	pfd.fd = sock;
	pfd.events = POLLIN;
	pfd.revents = 0;
	int r = poll(&pfd, 1, 0);
	return r;
}

unix.superglobalmegacorp.com

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