c - que - posix threads
¿Cuáles son los errores de WONTFIX en GNU/Linux y cómo solucionarlos? (2)
No creo que el problema UDP exista realmente. En el kernel de Linux actual, udp_poll lee
/**
* 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;
}
Por lo tanto, me parece que oculta los paquetes UDP con sumas de comprobación erróneas para que no se notifiquen mediante selección / sondeo. Esta versión del código se está utilizando desde la revisión 85584672 (2009). Pero incluso antes (al menos desde 2005), el código aparentemente estaba haciendo el mismo tipo de eliminación de paquetes defectuosos en la selección / encuesta ya.
Tanto Linux como el espacio de usuario GNU (glibc) parecen tener una serie de errores "WONTFIX", es decir, errores que las partes responsables han declarado que no están dispuestos a solucionar a pesar de violar claramente los requisitos de ISO C y / o POSIX, pero no estoy al tanto de cualquier recurso para programadores que enumera tales errores y sugerencias para trabajar en torno a ellos.
Aquí hay algunos que vienen a la mente:
- El error de
select
UDP de Linux:select
(y las interfaces relacionadas) marca un descriptor de archivo de socket UDP listo para leer tan pronto como se recibe un paquete, sin confirmar la suma de comprobación. En la siguienterecv
/read
/ etc., Si la suma de comprobación no es válida, la llamada se bloqueará. Para solucionar este problema, siempre se deben configurar los sockets UDP en el modo de no bloqueo y tratar la condiciónEWOULDBLOCK
. Si recuerdo correctamente, MaraDNS fue el primer proyecto notable afectado por este error y el primero en quejarse (sin éxito) de haberlo solucionado. Nota: Como lo señaló Martin v. Löwis, aparentemente este error ya se ha corregido. Las soluciones provisionales probablemente solo sean necesarias si necesita admitir versiones realmente obsoletas de Linux. - La familia
printf
en la biblioteca GNU C trata los argumentos de%s
como cadenas de caracteres multibyte en lugar de cadenas de bytes cuando se especifica una precisión de campo (como en%.3s
), lo que podría causar una salida truncada. No conozco ninguna solución, excepto reemplazar todo el subsistemaprintf
(o simplemente no usar la familia de funcionesprintf
con cadenas de bytes de caracteres no multibyte, pero esto puede ser problemático si desea procesar cadenas de páginas de códigos heredados usandosnprintf
mientras está en una UTF -8 locale). -
Códigos de resultado erróneos erróneos para ciertas llamadas al sistema (no puedo recordar cuáles son correctas).Por lo general, estos son fáciles de verificar si acaba de leer las páginas de manual de GNU / Linux y las compara con el estándar.(No puedo encontrar las referencias para esto y quizás me equivoque. Lo más cercano que puedo encontrar es el problema de queENOTSUP
yEOPNOTSUP
tienen el mismo valor; consulte PDTR 24715 .
¿Cuáles son algunos más errores y soluciones que podemos agregar a esta lista? Mis metas al hacer esta pregunta son:
- Para crear una lista más completa de dichos errores, para que tanto los programadores nuevos como los experimentados puedan conocer rápidamente los problemas potenciales que pueden surgir al ejecutar un programa destinado a ser portátil en GNU / Linux.
- Para aprovechar el cerebro colectivo de SO para idear soluciones alternativas inteligentes y discretas para tantos errores como sea posible, en lugar de que cada uno tenga que inventar sus propias soluciones después de ser picado, y posiblemente hacerlo en formas subóptimas, feas o piratas, o peor sin embargo, en formas que rompen el soporte para sistemas más conformes.
No puedo reproducir el problema de impresión que reclamas. Ejecutando el programa
#include <stdio.h>
#include <locale.h>
int main()
{
setlocale(LC_ALL, "");
printf("%.4s/n", "Löwis");
return 0;
}
en una configuración de_DE.UTF-8 se imprime "Löw", que me parece correcto: pedí 4 bytes y obtuve cuatro bytes (ö es 2 bytes). Si la biblioteca hubiera contado los caracteres de varios bytes, la salida debería haber sido "Löwi". Esto es con glibc 2.11.2.
Editar : Cambiar la cadena a "% .2s / n" solo imprimirá "L", es decir, solo un byte. Sin embargo, esto es conforme a la especificación , que dice
Si se especifica la precisión, no se escribirán más que tantos bytes.
(énfasis mío), y luego
En ningún caso se escribirá un carácter parcial.
Por lo tanto, dado que la impresión de dos bytes (es decir, la L y el byte principal de ö) daría lugar a la escritura de un carácter parcial, no sería conforme con la impresión de UTF-8 incompleto.