--- lbbs/src/io.c 2025/11/17 10:57:23 1.68 +++ lbbs/src/io.c 2025/12/17 03:56:39 1.73 @@ -64,8 +64,8 @@ static int stdout_conv_len = 0; static int stdin_conv_offset = 0; static int stdout_conv_offset = 0; -static iconv_t stdin_cd = NULL; -static iconv_t stdout_cd = NULL; +static iconv_t stdin_cd = (iconv_t)(-1); +static iconv_t stdout_cd = (iconv_t)(-1); int io_init(void) { @@ -308,7 +308,9 @@ int iflush(void) ret = ssh_channel_write(SSH_channel, stdout_conv + stdout_conv_offset, (uint32_t)(stdout_conv_len - stdout_conv_offset)); if (ret == SSH_ERROR) { +#ifdef _DEBUG log_error("ssh_channel_write() error: %s\n", ssh_get_error(SSH_session)); +#endif retry = 0; break; } @@ -392,7 +394,9 @@ int igetch(int timeout) { if (SSH_v2 && ssh_channel_is_closed(SSH_channel)) { +#ifdef _DEBUG log_error("SSH channel is closed\n"); +#endif loop = 0; break; } @@ -450,7 +454,9 @@ int igetch(int timeout) ret = ssh_channel_read_nonblocking(SSH_channel, stdin_buf + stdin_buf_len, sizeof(stdin_buf) - (uint32_t)stdin_buf_len, 0); if (ret == SSH_ERROR) { +#ifdef _DEBUG log_error("ssh_channel_read_nonblocking() error: %s\n", ssh_get_error(SSH_session)); +#endif loop = 0; break; } @@ -1034,6 +1040,7 @@ int io_buf_conv(iconv_t cd, char *p_buf, int ret; int in_control = 0; size_t i = 0; + int skip_current = 0; if (cd == NULL || p_buf == NULL || p_buf_len == NULL || p_buf_offset == NULL || p_conv == NULL || p_conv_len == NULL) { @@ -1057,8 +1064,10 @@ int io_buf_conv(iconv_t cd, char *p_buf, } } - if (in_control) + if (in_control || skip_current) { + skip_current = 0; + if (out_bytes <= 0) { log_error("No enough free space in p_conv, conv_len=%d, conv_size=%d\n", *p_conv_len, conv_size); @@ -1072,7 +1081,7 @@ int io_buf_conv(iconv_t cd, char *p_buf, out_bytes--; (*p_buf_offset)++; - *p_conv_len = (int)(conv_size - out_bytes); + (*p_conv_len)++; i++; if (i >= 2) @@ -1092,7 +1101,7 @@ int io_buf_conv(iconv_t cd, char *p_buf, #endif if (p_buf != in_buf) { - *p_buf_len = (int)(p_buf + *p_buf_len - in_buf); + *p_buf_len -= (int)(in_buf - p_buf); *p_buf_offset = 0; *p_conv_len = (int)(conv_size - out_bytes); memmove(p_buf, in_buf, (size_t)(*p_buf_len)); @@ -1117,27 +1126,41 @@ int io_buf_conv(iconv_t cd, char *p_buf, if (in_bytes == 0) { in_bytes = (size_t)(*p_buf_len - *p_buf_offset); +#ifdef _DEBUG + log_error("Reset in_bytes from 0 to %d\n", in_bytes); +#endif } - *out_buf = *in_buf; - in_buf++; - out_buf++; - in_bytes--; - out_bytes--; - - continue; +#ifdef _DEBUG + log_error("iconv(in_bytes=%d, out_bytes=%d) error: EILSEQ, in_buf[0]=%d\n", + in_bytes, out_bytes, in_buf[0]); +#endif + skip_current = 1; + } + else // something strange + { +#ifdef _DEBUG + log_error("iconv(in_bytes=%d, out_bytes=%d) error: %d, in_buf[0]=%d\n", + in_bytes, out_bytes, errno, in_buf[0]); +#endif + *p_buf_offset = (int)(in_buf - p_buf); + *p_conv_len = (int)(conv_size - out_bytes); + skip_current = 1; } } else { - *p_buf_len = 0; - *p_buf_offset = 0; + *p_buf_offset = (int)(in_buf - p_buf); *p_conv_len = (int)(conv_size - out_bytes); - - break; } } + if (*p_buf_offset >= *p_buf_len) + { + *p_buf_len = 0; + *p_buf_offset = 0; + } + return 0; } @@ -1172,6 +1195,7 @@ int io_conv_init(const char *charset) { log_error("iconv_open(%s->%s) error: %d\n", BBS_default_charset, tocode, errno); iconv_close(stdin_cd); + stdin_cd = (iconv_t)(-1); return -2; } @@ -1180,15 +1204,15 @@ int io_conv_init(const char *charset) int io_conv_cleanup(void) { - if (stdin_cd != NULL) + if (stdin_cd != (iconv_t)(-1)) { iconv_close(stdin_cd); - stdin_cd = NULL; + stdin_cd = (iconv_t)(-1); } - if (stdout_cd != NULL) + if (stdout_cd != (iconv_t)(-1)) { iconv_close(stdout_cd); - stdout_cd = NULL; + stdout_cd = (iconv_t)(-1); } return 0;