|
|
1.1 root 1: //
2: // nono
1.1.1.2 ! root 3: // Copyright (C) 2020 nono project
! 4: // Licensed under nono-license.txt
1.1 root 5: //
6:
7: #include "header.h"
8: #include "config.h"
9: #include "console.h"
10: #include <netdb.h>
11: #include <sys/socket.h>
12:
13: //
14: // TCP コンソール
15: //
16:
17: // コンストラクタ
18: ConsoleTCP::ConsoleTCP()
19: {
20: ls = -1;
21: sock = -1;
22:
23: // editline は使えないようだ...
24: //use_editline = true;
25: }
26:
27: // デストラクタ
28: ConsoleTCP::~ConsoleTCP()
29: {
30: if (res) {
31: freeaddrinfo(res);
32: res = NULL;
33: }
34: if (sock != -1) {
35: close(sock);
36: sock = -1;
37: }
38: if (ls != -1) {
39: close(ls);
40: ls = -1;
41: }
42: }
43:
44: // 初期化
45: bool
46: ConsoleTCP::Init()
47: {
48: struct addrinfo hints;
49: int r;
50: int on = 1;
51:
52: memset(&hints, 0, sizeof(hints));
53: hints.ai_family = AF_UNSPEC;
54: hints.ai_socktype = SOCK_STREAM;
55: hints.ai_flags = AI_PASSIVE;
56:
57: const char *host = "::1";
1.1.1.2 ! root 58: const ConfigItem& item = gConfig->Find("debugger-port");
1.1 root 59: const std::string& port = item.AsString();
60: int portnum = atoi(port.c_str());
61: if (portnum < 0 || portnum > 65535) {
62: item.Err();
63: return false;
64: }
65: // 0 なら待ち受けしない
66: if (portnum == 0) {
67: return false;
68: }
69:
70: r = getaddrinfo(host, port.c_str(), &hints, &res);
71: if (r != 0) {
72: const char *errmsg;
73: if (r == EAI_SYSTEM) {
74: errmsg = strerror(errno);
75: } else {
76: errmsg = gai_strerror(r);
77: }
78: warnx("getaddrinfo: %s: %s", host, errmsg);
79: return false;
80: }
81: if (res == NULL) {
82: warnx("getaddrinfo: %s: no address found", host);
83: return false;
84: }
85:
86: // res を順番に試して成功したらそれで待ち受ける
87: ls = -1;
88: for (ai = res; ai && ls == -1; ai = ai->ai_next) {
89: ls = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
90: if (ls == -1) {
91: warn("socket");
92: continue;
93: }
94:
95: if (setsockopt(ls, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on))) {
96: warn("setsockopt(SO_REUSEADDR)");
97: close(ls);
98: continue;
99: }
100:
101: if (setsockopt(ls, SOL_SOCKET, SO_REUSEPORT, &on, sizeof(on))) {
102: warn("setsockopt(SO_REUSEPORT)");
103: close(ls);
104: continue;
105: }
106:
107: if (bind(ls, ai->ai_addr, ai->ai_addrlen) == -1) {
108: warn("bind");
109: close(ls);
110: continue;
111: }
112:
113: if (listen(ls, 0) == -1) {
114: warn("listen");
115: close(ls);
116: continue;
117: }
118:
119: // ここまで来たら成功
120: break;
121: }
122:
123: if (ls == -1) {
124: return false;
125: }
126:
127: return true;
128: }
129:
1.1.1.2 ! root 130: // 受け付ける
1.1 root 131: bool
1.1.1.2 ! root 132: ConsoleTCP::Accept()
1.1 root 133: {
134: for (;;) {
135: sock = accept(ls, ai->ai_addr, &ai->ai_addrlen);
136: if (sock == -1) {
137: if (errno == EINTR) {
138: continue;
139: }
140: warn("accept");
141: return false;
142: }
143: break;
144: }
145:
146: inp.fd = dup(sock);
147: out.fd = dup(sock);
148: FDOpen();
149:
150: // editline(3) を使う場合、出力側がフルバッファリングだと内部バッファが
151: // 一杯になったか何かのタイミングでしか出力されなくなるので、少なくとも
152: // 行バッファリングにはしないといけない。
153: setlinebuf(out.file);
154: // バッファリングなしにしてもプロンプトは表示されない...
155: //setvbuf(out.file, NULL, _IONBF, 0);
156:
157: return true;
158: }
159:
160: void
161: ConsoleTCP::Close()
162: {
163: inherited::Close();
164:
165: if (sock != -1) {
166: close(sock);
167: sock = -1;
168: }
169: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.