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