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

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

unix.superglobalmegacorp.com

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