|
|
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.