|
Appunti informatica |
|
Visite: 1330 | Gradito: | [ Picolo appunti ] |
Leggi anche appunti:Le variabiliLe variabili E' il momento di ripescare CIAO.C e complicarlo un poco. #include La gestione degli erroriLa gestione degli errori Le librerie della maggior parte dei compilatori implementano Le funzioniLe funzioni La funzione è l'unità elaborativa fondamentale dei programmi C. |
Le librerie della maggior parte dei compilatori implementano una modalità standard, derivata da Unix, di gestione degli errori restituiti dai servizi DOS utilizzati dalle funzioni di libreria. Concentriamo la nostra attenzione su alcune variabili globali, dichiarate nel file STDLIB.H
extern char *sys_errlist[]
extern int errno
extern int _doserrno
L'array sys_errlist contiene i puntatori alle stringhe che descrivono i diversi errori . Vi è una funzione dedicata alla gestione dei messaggi d'errore, perror(), che richiede una stringa quale parametro, la scrive sullo standard error seguita da ' ', dalla stringa che costituisce l'elemento di sys_errlist corrispondente all'errore verificatosi e dal carattere 'n'. L'utilizzo di perror() non presenta difficoltà:
#include <stdio.h> // prototipi di fopen() e perror()
#define PRG_NAME 'MYPROG'
if(!(stream = fopen(filename,'r')))
Nell'ipotesi che filename contenga un pathname errato, fopen() non riesce ad aprire il file e restituisce NULL; la perror() produce il seguente output:
MYPROG: path not found
Come riesce perror() a individuare il messaggio? Semplice: si basa sul valore assunto dalla variabile errno, che può essere validamente utilizzata come indice. In altre parole, sys_errlist[errno] è la stringa che descrive l'errore. Dietro le quinte, tutte le funzioni di libreria che per svolgere il proprio compito utilizzano servizi DOS , se ricevono da questo un codice di errore lo passano ad una funzione (generalmente non documentata), la __IOerror() , che lo assegna a _doserrno, la quale contiene perciò il codice di errore DOS, e, tramite un'apposita tabella di conversione, ricava il valore appropriato da assegnare ad errno
Può essere utile chiamare direttamente la __IOerror() nei propri sorgenti, soprattutto quando si scrivano funzioni destinate ad essere inserite in una libreria: risulta è immediato implementare la gestione degli errori in modo del tutto coerente con le librerie standard del compilatore utilizzato. E' sufficiente dichiarare nel sorgente il prototipo di __IOerror()
int pascal __IOerror(int dosErr);
La parola riservata pascal ha lo scopo di modificare lo stile di chiamata della funzione: a tutte le funzioni dichiarate pascal, secondo lo standard di questo linguaggio, i parametri attuali sono passati in ordine diretto, cioè dal primo a sinistra all'ultimo a destra, e non viceversa, secondo quanto previsto invece, per default, dalle regole del C (pag. ). Lo scopo è ottenere una chiamata più efficiente; la perdita della possibilità di gestire un numero variabile di parametri, in questo caso, non ha alcuna importanza, in quanto __IOerror() ne riceve uno solo, dosErr, che rappresenta il codice di errore restituito dalla routine DOS (solitamente nel registro AX). La __IOerror() restituisce sempre
Vediamo un esempio. Vogliamo scrivere una funzione in grado di dirci, in un ambiente di rete, se un drive è locale o remoto: allo scopo si può utilizzare l'int 21h, servizio 44h, subfunzione 09h:
Int 21h, serv. 44h, subf. 09h: Determina se il drive è remoto
Input |
AX BL |
4409h Drive (00h = default, 01h A: 02h B:, etc.) |
Output |
DX |
Se CarryFlag , il bit 12 di DX a indica che il drive è remoto; Se CarryFlag allora AX contiene il codice di errore. |
Ed ecco il listato:
BARNINGA_Z! - 1991
ISREMOTE.C - isDriveRemote()
int cdecl isDriveRemote(int driveNum);
int driveNum; drive da testare (0 = default, 1 = A:, )
Restituisce: 0 = drive locale
1 = drive remoto
-1 = errore (errno e _doserrno gestite come standard)
COMPILABILE CON BORLAND C++ 3.0
bcc -O -d -c -mx isremote.c
dove -mx puo' essere -mt -ms -mc -mm -ml -mh
#pragma inline
#include <dos.h> // per geninterrupt()
int pascal __IOerror(int dosErr);
int cdecl isDriveRemote(int driveNum)
La funzione isDriveRemote() restituisce in caso di errore, se il drive è locale, se è remoto. Il parametro è un intero che esprime il drive su cui effettuare il test ( indica il drive di default, indica il drive A: il drive B:, etc.). Quando la funzione restituisce è possibile chiamare perror() per scrivere su stderr la descrizione dell'errore verificatosi:
if(isDriveRemote(0) == -1)
perror('What a pity');
E' immediato constatare che il comportamento di isDriveRemote() è conforme a quello delle altre funzioni di libreria che interagiscono con il DOS. Per altri esempi di utilizzo della __IOerror() in funzioni di libreria, vedere pag.
Appunti su: |
|