如何更改默认 C/C++ gnu readline 换行符?

How to change default C/C++ gnu readline newline character?

我的目标是在 telnet 服务器端使用 C/C++ readline 库,因为它提供了开箱即用的所有必要终端功能。 Readline 已经连接到 telnet 套接字,读取和写入套接字工作正常。我正在使用 libtelnet by Sean Middleditch.

问题是 readline 输出 '\n' 而不是 '\n\r' 这是一个 telnet 标准去换行 = New Line + Carriage Return.

客户端当前输出:

Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
> example
         > another example
                          > 3rd example
                                       > 

预期输出:

Trying 127.0.0.1...
Connected to localhost.
The escape character is '^]'.
> example
> another example
> 3rd example
> 

我阅读了试图找到一个带有默认换行符的简单变量的文档,但是没有这样的东西,或者我一定是错过了。这种行为也有可能随着 telnet 终端类型而改变——我还没到这一步。

你知道如何把这个 '\n' 改成 '\r\n' 吗?[​​=16=]

编辑:

Telnet 启动 & Readline 连接到套接字:

void startLibTelnet(int connfd)
{
    char buffer[512];
    int rs;

    telnet_t *telnet;
        telnet = telnet_init(telopts, _event_handler, 0, &connfd);

    // telnet options
    telnet_negotiate(telnet, TELNET_DO,
            TELNET_TELOPT_LINEMODE);

    telnet_negotiate(telnet, TELNET_WILL,
            TELNET_TELOPT_ECHO);

    telnet_negotiate(telnet, TELNET_WILL,
            TELNET_TELOPT_TTYPE);

    // redirecting readline input/output to TCP socket
    rl_instream = fdopen(connfd, "r");
    rl_outstream = fdopen(connfd, "w");

again:
    // forever loop
    while ( (rs = recv(connfd, buffer, sizeof(buffer), 0)) > 0)
    {
        telnet_recv(telnet, buffer, rs);
    }
    if (rs  < 0 && errno == EINTR)
        goto again;
    else if (rs  < 0)
        perror("str_echo: read error");
}

部分事件处理程序:

static void _event_handler(telnet_t *telnet, telnet_event_t *ev,
                void *user_data)
{
    int sock = *(int*)user_data;

    switch (ev->type) {
    /* data received */
    case TELNET_EV_DATA:
        rl_gets("> ");
        break;
    /* data must be sent */
    case TELNET_EV_SEND:
        _send(sock, ev->data.buffer, ev->data.size);
        break;
    /* request to enable remote feature (or receipt) */
    case TELNET_EV_WILL:
        break;
    /* notification of disabling remote feature (or receipt) */
    case TELNET_EV_WONT:
        break;
    . // here's also 
    . // case DO
    . // case DONT
    default:
        break;
    }
}

我想我应该保留 readline 模块。最好的解决方案可能是告诉客户端将“\n”或换行解释为“\n\r”或换行和回车 Return。我在查找此类 telnet 选项时遇到问题。

IMO 应该改变其行为的不是 readline,而是应该执行适当转换的 libtelnet。

libtelnet 的文档提到

  • void telnet_send_text(telnet_t *telnet, const char *buffer, size_t size);

Sends text characters with translation of C newlines (\n) into CR LF and C carriage returns (\r) into CR NUL, as required by RFC854, unless transmission in BINARY mode has been negotiated.

所以它应该能够处理这个。如果您需要更详细的帮助,您必须展示 readline 如何与 libtelnet 通信。


编辑 - 看起来您正在使用 libtelnet 来处理来自 telnet 客户端的输入,但允许 readline 将字符直接放在套接字上返回给客户端。这是个错误。根据 libtelnet 文档:

Note: it is very important that ALL data sent to the remote end of the connection be passed through libtelnet. All user input or process output that you wish to send over the wire should be given to one of the following functions. Do NOT send or buffer unprocessed output data directly!

也就是说,你需要

client <-> libtelnet <-> readline

没有

client  -> libtelnet -> readline
   |                       /
    ----------<----------- 

认为是你现在正在做的。不过我不能确定,因为我不知道 connsock 是如何在您显示的代码之外设置的。