GNU / Linux上有哪些WONTFIX错误以及如何解决它们?

时间:2010-12-07 20:49:06

标签: c linux posix standards-compliance

Linux和GNU用户空间(glibc)似乎都有一些“WONTFIX”错误,即责任方已声明他们不愿意修复的错误,尽管明显违反了ISO C和/或POSIX的要求,但我我不知道程序员的任何资源,列出了这些错误和解决它们的建议。

以下是一些想到的内容:

  • Linux UDP 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手册页并将它们与标准进行比较。(我找不到这方面的参考文献,也许我错了。我能找到最接近的是ENOTSUPEOPNOTSUP具有相同值的问题;请参阅PDTR 24715

我们可以在此列表中添加哪些错误和解决方法?我提出这个问题的目的是:

  1. 构建更完整的此类错误列表,以便新手和有经验的程序员能够快速了解​​在GNU / Linux上运行预期可移植程序时可能出现的潜在问题。
  2. 利用SO集体大脑为尽可能多的此类错误思考聪明且不引人注意的标准变通方法,而不是每个人都必须在发生蜇伤后发明自己的变通方法,并且可能以次优,丑陋或hackish方式这样做 - 或者更糟糕的是,以破坏对更符合要求的系统的支持的方式。

2 个答案:

答案 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中同样丢弃坏包了。