Comment vérifier la valeur de errno
:
- Vous devrez
#include <errno.h>
.
- Oui, vous pouvez certainement dire des choses comme
if(errno == ENOENT) { ... }
, et c'est la façon commune et recommandée de le faire.
- En général, ne pas utiliser
errno
pour déterminer qu'une erreur s'est produite. Vérifiez la valeur de retour de la fonction, et si la valeur de retour indique une erreur, vérifiez errno
pour voir quelle était l'erreur. (Plus de détails ci-dessous.)
errno
ressemble à une variable, mais ce n'est pas le cas. Cela ne vous concerne pas tant que vous dites des choses comme if(errno == ENOENT) { ... }
. Mais vous ne devriez probablement pas essayer de faire quelque chose comme int errno_ptr = &errno;
.
- Vous pouvez utiliser des fonctions telles que
perror()
et strerror()
pour obtenir des chaînes d'erreur lisibles par l'utilisateur correspondant aux valeurs errno
. Mais, oui, les chaînes que vous obtenez sont généralement des choses comme "Aucun fichier ou répertoire". Il n'y a aucun moyen que je connaisse de convertir la valeur errno ENOENT
à la chaîne "ENOENT"
.
Pour en dire un peu plus sur # 3. Parfois, il est tentant de dire quelque chose comme
errno = 0;
printf("Hello, world!\n");
if(errno != 0) {
fprintf(stderr, "printf failed!\n");
}
Mais ne faites pas cela. faire au lieu
errno = 0;
int retval = printf("Hello, world!\n");
if(retval < 0) {
fprintf(stderr, "printf failed!\n");
}
La raison en est que, quelque part dans le processus de faire son travail, printf
aurait pu faire quelque chose qui a donné lieu à une erreur, ce qui a mis errno
, mais printf
aurait pu récupérer de cette erreur et continué pour terminer avec succès.
Il y a très peu de fonctions de bibliothèque qui sont garantis pas toucher errno s'il n'y avait pas une erreur (je pense qu'un exemple pourrait être atoi
), mais en général, cela est quelque chose que vous devez faire attention .
Pour en dire un peu plus sur # 4.errno
ressemble à une variable, et plus précisément, il ressemble à une variable globale. Mais bien sûr, les variables globales sont mauvaises. Mais errno
a été autour pour toujours; il y a des dizaines de millions de lignes de code qui l'utilisent; c'est toujours plutôt pratique; il est trop tard pour "réparer". Ainsi, au lieu, si vous jeter un regard derrière le rideau, vous trouverez que la plupart des implémentations faire quelque chose comme
extern int __errno_pointer;
#define errno (*__errno_pointer)
ou
extern int *__errno_pointer_function();
#define errno (*__errno_function())
De cette façon, ils peuvent organiser errno
fonctionner raisonnablement bien même dans, disons, du code multithread.
Sur quel système d'exploitation? Quel appel système exact? Quelle bibliothèque C? S'il vous plaît ** modifier votre question pour l'améliorer ** –
Chaque appel système a une liste de valeurs errno possibles (voir sa page 'man'), cela vous permettra de savoir ce que vous devriez tester. – Myst
Ce que vous avez écrit est bien. Rappelez-vous, aucune fonction de bibliothèque ne met à zéro, et vous ne devriez pas le tester, sauf si une fonction indique une erreur et est documentée pour définir 'errno'. Notez que de nombreuses fonctions pthreads ne définissent pas 'errno', par exemple; ils renvoient le numéro d'erreur à la place. De même, les fonctions peuvent définir 'errno' sur une valeur non nulle même si elles réussissent. Par exemple, sur Solaris, si la sortie standard n'est pas un terminal, 'errno' peut être défini sur ENOTTY même si l'appel' printf() 'est réussi. –