err(), warn() et leurs amis

Souvent méconnues, ces fonctions sont pourtant présentes partout (“non-standard BSD extensions” dit le man sous Linux) et elles simplifient pas mal la vie..

#include <err.h>
void err(int eval, const char *fmt, ...);
void errx(int eval, const char *fmt, ...);
void warn(const char *fmt, ...);
void warnx(const char *fmt, ...);

Les 2 premières affichent un message d'erreur printf-style, et appellent exit() avec la valeur passée en 1er paramêtre. Les 2 dernières affichent juste le message d'erreur. De plus, err() et warn() affichent le message d'erreur standard correspondant a la dernière valeur de errno via strerror().

codaz

$cat l.c 
#include <err.h>
#include <stdio.h>
 
int main()
{
        int fd = 0;
        char str[] = "ZOMG";
        if ((fd = open("/foo/bar", "r")) == -1)
                warn("%s, i can has warning ? ", str);
 
        if (3 != 4)
                warnx("%s, 3 is not 4 !", str);
 
        if (close(fd) == -1)
                err(1, "%s, i can has error ? ", str);
 
        return 0; /* NOTREACHED */
}

résultat

$gcc l.c -o l
$./l
l: ZOMG, i can has warning ? : No such file or directory
l: ZOMG, 3 is not 4 !
l: ZOMG, i can has error ? : Bad file descriptor
$echo $?
1

<sysexits.h>

Les *BSD dispose de codes de retour bien définis disponibles dans <sysexits.h> ou sysexits(3). Ces codes sont des codes d'exit prédéfinis que l'on a l'habitude de traiter nous même en général… C'est une spécificité des *BSD, bien que présent sur OpenSolaris (voir ici).

Et voilà une manière de plus pour écrire du code BSD compliant.

codaz

cat toto.c
#include <stdio.h>
#include <stdlib.h>
#include <sysexits.h>
#include <unistd.h>
 
extern char *__progname;
 
static int
usage(void) 
{
    fprintf(stderr,"usage: %s <arg1> \n", __progname);
    return EX_USAGE;
}
 
int
main(int argc, char *argv[])
{
    int fd, ch;
 
    while ((ch = getopt(argc, argv, "h")) != -1) {
        switch (ch) {
        case 'h':
        default:
            return usage();
        }
    }
    argc -= optind;
    argv += optind;
 
    if (argc != 0)
        return usage();
 
    if (fd = open("/tmp/baz",'r') == -1)
        return EX_OSFILE;   
 
    return EX_OK;
}

résultat

% touch /tmp/baz
% make toto
cc -O2 -fstrict-aliasing -pipe  -march=pentium-m  toto.c  -o toto
% toto 
% echo $?
0
toto -h
usage: toto <arg1> 
% echo $?
64
% rm -rf /tmp/baz
% toto
% echo $?
72
c/messages_d_erreurs.txt · Last modified: 2010/01/12 13:29 (external edit)
www.chimeric.de Creative Commons License Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0