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