116 lines
5.0 KiB
Plaintext
116 lines
5.0 KiB
Plaintext
The error routines.
|
|
|
|
The 'error' system I've implemented is intended to server 2 purpose, to
|
|
record the reason why a command failed and to record where in the libraries
|
|
the failure occurred. It is more or less setup to record a 'trace' of which
|
|
library components were being traversed when the error occurred.
|
|
|
|
When an error is recorded, it is done so a as single unsigned long which is
|
|
composed of three parts. The top byte is the 'library' number, the middle
|
|
12 bytes is the function code, and the bottom 12 bits is the 'reason' code.
|
|
|
|
Each 'library', or should a say, 'section' of the SSLeay library has a
|
|
different unique 'library' error number. Each function in the library has
|
|
a number that is unique for that library. Each 'library' also has a number
|
|
for each 'error reason' that is only unique for that 'library'.
|
|
|
|
Due to the way these error routines record a 'error trace', there is an
|
|
array per thread that is used to store the error codes.
|
|
The various functions in this library are used to access
|
|
and manipulate this array.
|
|
|
|
void ERR_put_error(int lib, int func,int reason);
|
|
This routine records an error in library 'lib', function 'func'
|
|
and reason 'reason'. As errors get 'put' into the buffer, they wrap
|
|
around and overwrite old errors if too many are written. It is assumed
|
|
that the last errors are the most important.
|
|
|
|
unsigned long ERR_get_error(void );
|
|
This function returns the last error added to the error buffer.
|
|
In effect it is popping the value off the buffer so repeated calls will
|
|
continue to return values until there are no more errors to return in which
|
|
case 0 is returned.
|
|
|
|
unsigned long ERR_peek_error(void );
|
|
This function returns the value of the last error added to the
|
|
error buffer but does not 'pop' it from the buffer.
|
|
|
|
void ERR_clear_error(void );
|
|
This function clears the error buffer, discarding all unread
|
|
errors.
|
|
|
|
While the above described error system obviously produces lots of different
|
|
error number, a method for 'reporting' these errors in a human readable
|
|
form is required. To achieve this, each library has the option of
|
|
'registering' error strings.
|
|
|
|
typedef struct ERR_string_data_st
|
|
{
|
|
unsigned long error;
|
|
char *string;
|
|
} ERR_STRING_DATA;
|
|
|
|
The 'ERR_STRING_DATA' contains an error code and the corresponding text
|
|
string. To add new function error strings for a library, the
|
|
ERR_STRING_DATA needs to be 'registered' with the library.
|
|
|
|
void ERR_load_strings(unsigned long lib,ERR_STRING_DATA *err);
|
|
This function 'registers' the array of ERR_STRING_DATA pointed to by
|
|
'err' as error text strings for the error library 'lib'.
|
|
|
|
void ERR_free_strings(void);
|
|
This function free()s all the loaded error strings.
|
|
|
|
char *ERR_error_string(unsigned long error,char *buf);
|
|
This function returns a text string that is a human readable
|
|
version of the error represented by 'error'. Buff should be at least 120
|
|
bytes long and if it is NULL, the return value is a pointer to a static
|
|
variable that will contain the error string, otherwise 'buf' is returned.
|
|
If there is not a text string registered for a particular error, a text
|
|
string containing the error number is returned instead.
|
|
|
|
void ERR_print_errors(BIO *bp);
|
|
void ERR_print_errors_fp(FILE *fp);
|
|
This function is a convenience routine that prints the error string
|
|
for each error until all errors have been accounted for.
|
|
|
|
char *ERR_lib_error_string(unsigned long e);
|
|
char *ERR_func_error_string(unsigned long e);
|
|
char *ERR_reason_error_string(unsigned long e);
|
|
The above three functions return the 3 different components strings for the
|
|
error 'e'. ERR_error_string() uses these functions.
|
|
|
|
void ERR_load_ERR_strings(void );
|
|
This function 'registers' the error strings for the 'ERR' module.
|
|
|
|
void ERR_load_crypto_strings(void );
|
|
This function 'register' the error strings for just about every
|
|
library in the SSLeay package except for the SSL routines. There is no
|
|
need to ever register any error text strings and you will probably save in
|
|
program size. If on the other hand you do 'register' all errors, it is
|
|
quite easy to determine why a particular routine failed.
|
|
|
|
As a final footnote as to why the error system is designed as it is.
|
|
1) I did not want a single 'global' error code.
|
|
2) I wanted to know which subroutine a failure occurred in.
|
|
3) For Windows NT etc, it should be simple to replace the 'key' routines
|
|
with code to pass error codes back to the application.
|
|
4) I wanted the option of meaningful error text strings.
|
|
|
|
Late breaking news - the changes to support threads.
|
|
|
|
Each 'thread' has an 'ERR_STATE' state associated with it.
|
|
ERR_STATE *ERR_get_state(void ) will return the 'state' for the calling
|
|
thread/process.
|
|
|
|
ERR_remove_state(unsigned long pid); will 'free()' this state. If pid == 0
|
|
the current 'thread/process' will have it's error state removed.
|
|
If you do not remove the error state of a thread, this could be considered a
|
|
form of memory leak, so just after 'reaping' a thread that has died,
|
|
call ERR_remove_state(pid).
|
|
|
|
Have a read of thread.doc for more details for what is required for
|
|
multi-threading support. All the other error routines will
|
|
work correctly when using threads.
|
|
|