简体   繁体   English

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

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

My goal is to use the C/C++ readline library on the telnet server-side as it delivers all necessary terminal functionality out of the box.我的目标是在 telnet 服务器端使用 C/C++ readline 库,因为它提供了开箱即用的所有必要终端功能。 Readline is already connected to the telnet socket, read and write to the socket works fine. Readline 已经连接到 telnet 套接字,对套接字的读写工作正常。 I'm using libtelnet by Sean Middleditch .我正在使用Sean Middleditch 的 libtelnet

The problem is that the readline outputs '\n' instead of '\n\r' which is a telnet standard to go to a new line = New Line + Carriage Return.问题是 readline 输出 '\n' 而不是 '\n\r' 这是 go 的 telnet 标准到新行 = 新行 + 回车。

Current output on the client-side:客户端当前的 output:

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

Expected output:预期 output:

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

I read documentation trying to find a simple variable with a default newline character, but there's no such thing, or I must've missed it.我阅读文档试图找到一个带有默认换行符的简单变量,但没有这样的东西,或者我一定错过了它。 There's also a chance that this behavior might be changed with the telnet terminal type - I not this far yet. telnet 终端类型也有可能改变这种行为——我还没有到这一步。

Do you have any idea on how to change this '\n' to '\r\n'?你知道如何将这个 '\n' 更改为 '\r\n' 吗?

Edit:编辑:

Telnet initiated & Readline connected to socket: 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");
}

Part of the event handler:部分事件处理程序:

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

I think I should leave the readline module as is.我想我应该保留 readline 模块。 The best solution is probably telling the client side to interpret '\n' or Line Feed as '\n\r' or Line Feed and Carriege Return.最好的解决方案可能是告诉客户端将“\n”或换行解释为“\n\r”或换行和回车。 I'm having problems finding this kind of telnet option.我在寻找这种 telnet 选项时遇到问题。

It's not readline that should be changing its behaviour IMO, but libtelnet that should be performing the appropriate translation.应该改变其行为 IMO 的不是 readline,而是应该执行适当翻译的 libtelnet。

The documentation for libtelnet mentions 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.根据 RFC854 的要求,将带有 C 换行符 (\n) 转换为 CR LF 和 C 回车符 (\r) 转换为 CR NUL 的文本字符发送到 CR NUL,除非已协商以 BINARY 模式传输。

so it should be able to handle this.所以它应该能够处理这个问题。 You'll have to show how readline is talking to libtelnet if you need more detailed help.如果您需要更详细的帮助,您必须展示 readline 如何与 libtelnet 对话。


Edit - it looks like you're using libtelnet to handle input from the telnet client, but allowing readline to put characters directly on the socket back to the client.编辑 - 看起来您正在使用 libtelnet 处理来自 telnet 客户端的输入,但允许 readline 将字符直接放在套接字上返回客户端。 This is a mistake.这是个错误。 Per the libtelnet documentation:根据 libtelnet 文档:

Note: it is very important that ALL data sent to the remote end of the connection be passed through libtelnet.注意:发送到连接远程端的所有数据都必须通过 libtelnet 传递,这一点非常重要。 All user input or process output that you wish to send over the wire should be given to one of the following functions.您希望通过线路发送的所有用户输入或过程 output 应提供给以下函数之一。 Do NOT send or buffer unprocessed output data directly!不要直接发送或缓冲未处理的 output 数据!

That is, you need也就是说,你需要

client <-> libtelnet <-> readline

not不是

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

which I think is what you're doing now.认为这就是你现在正在做的事情。 I can't tell for certain though, since I don't know how conn and sock are set up outside the code you've shown.不过我不能确定,因为我不知道connsock是如何在您显示的代码之外设置的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM