Annotation of nono/debugger/console_tcp.cpp, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

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