Linux和GNU用户空间(glibc)似乎都有一些“WONTFIX”错误,即责任方已声明他们不愿意修复的错误,尽管明显违反了ISO C和/或POSIX的要求,但我我不知道程序员的任何资源,列出了这些错误和解决它们的建议。
以下是一些想到的内容:
select
错误:select
(和相关接口)标记UDP套接字文件描述符,一旦收到数据包就准备好读取,而不确认校验和。在后续的recv
/ read
/等中,如果校验和无效,则呼叫将被阻止。解决此问题需要始终将UDP套接字设置为非阻塞模式并处理EWOULDBLOCK
条件。如果我没记错的话,MaraDNS是第一个受这个bug影响的着名项目,也是第一个抱怨(不成功)修复它的项目。 注意:正如Martinv.Löwis所指出的,显然这个错误已被修复。如果您需要支持真正过时的Linux版本,可能只需要解决方法。printf
)时,GNU C库中的%s
系列错误地将%.3s
的参数视为多字节字符串而不是字节字符串,可能导致截断输出。我知道没有解决方法,除了替换整个printf
子系统(或者根本不使用带有非多字节字符字符串的printf
系列函数,但如果你想处理遗留问题,这可能会有问题 - 在UTF-8语言环境中使用snprintf
的代码页字符串。)errno
结果代码(不记得哪些是关闭的)。通常这些很容易检查你是否只是阅读GNU / Linux手册页并将它们与标准进行比较。ENOTSUP
和EOPNOTSUP
具有相同值的问题;请参阅PDTR 24715。我们可以在此列表中添加哪些错误和解决方法?我提出这个问题的目的是:
答案 0 :(得分:5)
我无法重现您声明的printf问题。运行程序
#include <stdio.h>
#include <locale.h>
int main()
{
setlocale(LC_ALL, "");
printf("%.4s\n", "Löwis");
return 0;
}
在de_DE.UTF-8语言环境中的打印“Löw”,它看起来对我来说:我要求4个字节,并得到4个字节(ö是2个字节)。如果库计算了多字节字符,则输出应为“Löwi”。这是glibc 2.11.2。
编辑:将字符串更改为“%。2s \ n”将只打印“L”,即只打印一个字节。但是,这符合the specification,即
如果指定了精度,则不再 应写入多个字节。
(强调我的),然后
在任何情况下都不得使用部分字符 写的。
因此,由于打印两个字节(即L和ö的前导字节)会导致写入部分字符,因此不符合打印不完整的UTF-8。
答案 1 :(得分:4)
我不相信UDP问题确实存在。在当前的Linux内核中,udp_poll读取
/**
* udp_poll - wait for a UDP event.
* @file - file struct
* @sock - socket
* @wait - poll table
*
* This is same as datagram poll, except for the special case of
* blocking sockets. If application is using a blocking fd
* and a packet with checksum error is in the queue;
* then it could get return from select indicating data available
* but then block when reading it. Add special case code
* to work around these arguably broken applications.
*/
unsigned int udp_poll(struct file *file, struct socket *sock, poll_table *wait)
{
unsigned int mask = datagram_poll(file, sock, wait);
struct sock *sk = sock->sk;
/* Check for false positives due to checksum errors */
if ((mask & POLLRDNORM) && !(file->f_flags & O_NONBLOCK) &&
!(sk->sk_shutdown & RCV_SHUTDOWN) && !first_packet_length(sk))
mask &= ~(POLLIN | POLLRDNORM);
return mask;
}
因此在我看来,它确实隐藏了通过select / poll报告的校验和错误的UDP数据包。从版本85584672(2009)开始使用此版本的代码。但即使在此之前(至少从2005年开始),代码显然已经在select / poll中同样丢弃坏包了。