Capítulo 11. Etiqueta de programas 11.1. Objetivos Aconsejar algunas nociones de etiqueta (buen comportamiento) de programas en cuanto información sobre errores. 11.2. Identificación del programa, mensajes significativios, valor de exit El siguiente programa modifica el leepos.c de la práctica de e/s aleatoria para que cumpla la siguiente etiqueta: • Todos los mensajes salen por la salida de error (ya estaba). • Que el programa se identifique siempre. • Que si los argumentos son incorrectos, diga como se usa el programa. • Que si no hay errores salga con un valor de retorno igual cero (ya estaba). • Que si una llamada al sistema produce un error, dé un mensaje apropiado y salga con un valor de retorno distinto de cero (en este caso hemos usado directamente errno). #include #include #include #include #include <unistd.h> <fcntl.h> <stdio.h> <stdlib.h> <errno.h> static char *p; static void uso(void) { fprintf(stderr, "Uso:\n %s f p\n", p); exit(1); } static void error(void) { perror(p); exit(errno); } int main(int argc, char* argv[]) { int f; char c; off_t pos; p= argv[0]; if (argc != 3) uso(); if ((f = open(argv[1], O_RDONLY)) < 0) error(); if (lseek(f, pos=atoi(argv[2]), SEEK_SET) < 0) error(); if(read(f, &c, 1) != 1) error(); printf("%s[%ld]= %c (%x hex)\n", argv[1], pos, c, c); exit(0); } 1 Capítulo 11. Etiqueta de programas 11.3. Internacionalización y localización Es conveniente que los programas hablen el idioma de los usuarios. Aunque no vamos a aprender a hacer multilingües, sí vamos a hacer uso de funciones multilingües. Observe que usamos setlocale para localizar los mensajes de perror y que tal como tenemos la variable LC_MESSAGES o LC_ALL, salgan en castellano. #include #include #include #include #include #include <unistd.h> <fcntl.h> <stdio.h> <stdlib.h> <errno.h> <locale.h> static char *p; static void uso(void) { fprintf(stderr, "Uso:\n %s f p\n", p); exit(1); } static void error(void) { perror(p); exit(errno); } int main(int argc, char* argv[]) { int f; char c; off_t pos; p= argv[0]; if (argc != 3) uso(); setlocale(LC_ALL, ""); /* Mensajes de error en idioma local */ if ((f = open(argv[1], O_RDONLY)) < 0) error(); if (lseek(f, pos=atoi(argv[2]), SEEK_SET) < 0) error(); if(read(f, &c, 1) != 1) error(); printf("%s[%ld]= %c (%x hex)\n", argv[1], pos, c, c); exit(0); } 11.4. Ficheros ofrecidos En el directorio etiqueta: • Programa leeposingles.c. • Programa leeposinter.c. 2 Capítulo 11. Etiqueta de programas 11.5. Resultados pedidos • Verificación de la etiqueta de informe de errores de leeposingles.c: • Verifique que los mensajes salen por la salida de error (redirigiéndola a un fichero con 2>). • Que el programa se identifica en los errores. • Que si los argumentos son incorrectos, diga como se usa el programa. • Que si no hay errores salga con un valor de retorno igual cero (echo $?). • Que si hay errores salga con un valor de retorno distinto de cero (echo $?). Ejemplos ./leeposingles echo $? ./leeposingles echo $? ./leeposingles echo $? cat errores ./leeposingles echo $? ./leeposingles echo $? ./leeposingles echo $? ./leeposingles cat errores ... etc. • leeposingles.c 3 leeposingles.c leeposingles.c 2> errores leeposingles.c -1 XXXXX 3 /etc/shadow 3 /etc/shadow 3 2> errores Verifique internacionalización de leeposinter.c: echo $LC_ALL ./leeposinter leeposinter.c -1 ./leeposinter XXXXX 3 ./leeposinter /etc/shadow 3 LC_ALL=fr_FR.utf8 echo $LC_ALL ./leeposinter leeposinter.c -1 ./leeposinter XXXXX 3 ./leeposinter /etc/shadow 3 LC_ALL=C echo $LC_ALL ./leeposinter leeposinter.c -1 ./leeposinter XXXXX 3 ./leeposinter /etc/shadow 3 LC_ALL=es_ES.utf8 ./leeposinter /etc/shadow 3 ... etc 3