¿Debo poner errno?


Estoy escribiendo un módulo que exporta una interfaz similar a send y recv.

Dado que se supone que esas funciones devuelven respectivamente el número de bytes enviados y recibidos, no puedo hacer una gestión de errores adecuada como lo haría normalmente (es decir, usar enumerativos y devolver valores mnemotécnicos).

En una situación como esta ¿debería establecer errno como lo hace la biblioteca estándar? Si es así, ya que errno es un hilo específico, ¿hay una forma particular de escribir en él, o puedo simplemente ¿asignarle un valor?

Editar: experimentando Me di cuenta de que la configuración errno por asignación está funcionando. Aún así: ¿es seguro y portátil para cualquier sistema?

 37
Author: Dacav, 2012-03-25

6 answers

Esto es un poco antiguo, pero errno-manual section 3 dice que se puede asignar directamente a él, aunque sea una macro, y será thread local

 30
Author: gbulmer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-25 00:20:46

No solo puede establecer errno, en muchos casos debe establecer errno. Al llamar a algunas funciones de biblioteca, solo puede detectar un error de forma fiable si primero establece errno a cero. Véase strtol para un ejemplo.

De la especificación POSIX de strtol:

[CX] [Option Start] La función strtol() no cambiará la configuración de errno si tiene éxito.

Desde que 0, {LONG_MIN} o {LLONG_MIN}, y {LONG_MAX} o {LLONG_MAX} se devuelven en caso de error y también son retornos válidos en caso de éxito, una aplicación que desee verificar situaciones de error debe establecer errno a 0, luego llamar a strtol() o strtoll(), luego verificar errno. [Fin de la opción]

 14
Author: Dan Moulding,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-07-05 11:14:27

En realidad, probablemente puede hacer la gestión de errores "adecuada" (como usted lo dice) ya que devuelve un int.

Simplemente use valores no negativos para el número de bytes leídos o escritos y valores negativos para los códigos de error. No tienes que limitarte a -1:

enum myerrors {
    ERR_NO_MEMORY    = -1,
    ERR_BAD_ARGS     = -2,
    ERR_CPU_EXPLODED = -3,
    // and so on
};

Sin embargo, configurar errno de la manera que desee es válido. El estándar establece que errno se expande a un lvalue modificable, lo que significa que puede configurarlo. De C1x/n1425, 7.5 Errors <errno.h>:

... y errno que se expande a un lvalue modificable que tiene el tipo int, cuyo valor se establece en un número de error positivo por varias funciones de biblioteca.

 8
Author: paxdiablo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-30 13:53:26

Solo puede asignar un valor a errno, pero tenga en cuenta que hay otras formas de señalar un error que, dependiendo de su situación, pueden ser más adecuadas:

  1. No devuelve el número de bytes leídos, sino que tiene un parámetro de salida con el tipo int * (o size_t * o lo que use). A continuación, puede devolver un código de error.
  2. Suponiendo que su tipo de retorno es un tipo firmado y que una cantidad de bytes enviada o recibida negativa no tiene sentido, use negativo valores para indicar las condiciones de error respectivas.
 6
Author: Julien Oster,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-07-05 13:22:59

Sí, puede asignarle, y sí, la asignación será segura para subprocesos. Ver ¿Es seguro el hilo de errno?

 2
Author: Kyle Jones,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:32:29

De: http://support.sas.com/documentation/onlinedoc/sasc/doc700/html/lr1/errno.htm

Los únicos valores portables para errno son EDOM y ERANGE

Así que eso responde a tu pregunta de portabilidad.

 2
Author: prelic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-01-07 13:46:48