Devrais-je définir errno?

J’écris un module qui exporte une interface similaire à send et recv .

Étant donné que ces fonctions sont censées renvoyer respectivement le nombre d’octets envoyés et reçus, je ne peux pas gérer correctement les erreurs comme je le ferais normalement (c’est-à-dire utiliser des énumérations et renvoyer des valeurs mnémoniques).

Dans une situation comme celle-ci, dois-je définir errno de la même manière que la bibliothèque standard? Si tel est le cas, errno spécificité de thread, existe-t-il un moyen d’écrire particulier ou puis-je simplement lui atsortingbuer une valeur?

Edit: expérimentant, j’ai remarqué que la définition de errno par affectation fonctionnait. Encore: est-ce sûr et portable pour tout système?

C’est un peu vieux, mais errno – section 3 du manuel dit que vous pouvez l’affecter directement, même s’il s’agit d’une macro, et que ce sera un thread local

Non seulement vous pouvez définir errno , mais dans de nombreux cas, vous devez définir errno . Lorsque vous appelez certaines fonctions de bibliothèque, vous ne pouvez détecter une erreur de manière fiable que si vous définissez d’abord errno avec errno . Voir strtol pour un exemple .

A partir de la spécification POSIX de strtol :

[CX] [Option Start] La fonction strtol () ne modifiera pas le paramètre errno si elle réussit.

Puisque 0, {LONG_MIN} ou {LLONG_MIN}, et {LONG_MAX} ou {LLONG_MAX} sont renvoyés en cas d’erreur et sont également des retours valides en cas de succès, une application souhaitant vérifier les situations d’erreur doit définir errno sur 0, puis appeler strtol () ou strtoll (), puis vérifiez errno. [Option Fin]

En fait, vous pouvez probablement faire une gestion des erreurs “correcte” (comme vous dites) depuis que vous retournez un int .

Utilisez simplement des valeurs non négatives pour le nombre d’octets lus ou écrits et des valeurs négatives pour les codes d’erreur. Vous n’êtes pas obligé de vous limiter à -1 :

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

Cependant, définir errno de la manière souhaitée est valide. La norme indique que errno développe en une valeur modifiable, ce qui signifie que vous pouvez la définir. De C1x/n1425, 7.5 Errors :

… et errno qui se transforme en une lvalue modifiable de type int, dont la valeur est définie sur un numéro d’erreur positif par plusieurs fonctions de bibliothèque.

Vous pouvez simplement atsortingbuer une valeur à errno , mais n’oubliez pas qu’il existe d’autres moyens de signaler une erreur qui, selon votre situation, peut être plus appropriée:

  1. Ne renvoyez pas le nombre d’octets lus, mais utilisez plutôt un paramètre de sortie de type int * (ou size_t * ou celui que vous size_t * ). Vous pouvez ensuite renvoyer un code d’erreur.
  2. En supposant que votre type de retour soit un type signé et qu’un montant négatif en octets envoyés ou reçus n’ait pas de sens, utilisez des valeurs négatives pour signaler les conditions d’erreur respectives.

Oui, vous pouvez l’affecter et oui, l’affectation sera thread-safe. Voir Est-ce que errno thread-safe?

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

Les seules valeurs portables pour errno sont EDOM et ERANGE

Cela répond donc à votre question sur la portabilité.