Annotation of nono/debugger/console_tcp.cpp, revision 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.