'\" -*- coding: UTF-8 -*-
.if \n(.g .ds T< \\FC
.if \n(.g .ds T> \\F[\n[.fam]]
.de URL
\\$2 \(la\\$1\(ra\\$3
..
.if \n(.g .mso www.tmac
.TH sg_get_error 3 2019-03-08 libstatgrab ""
.SH NAME
sg_get_error, sg_get_error_arg, sg_get_error_errno, sg_str_error, sg_get_error_details, sg_strperror \- get last error status
.SH SYNOPSIS
'nh
.nf
\*(T<#include <statgrab.h>\*(T>
.fi
.sp 1
.PP
.fi
.ad l
\*(T<sg_error \fBsg_get_error\fR\*(T> \kx
.if (\nx>(\n(.l/2)) .nr x (\n(.l/5)
'in \n(.iu+\nxu
\*(T<(void);\*(T>
'in \n(.iu-\nxu
.ad b
.PP
.fi
.ad l
\*(T<const char *\fBsg_get_error_arg\fR\*(T> \kx
.if (\nx>(\n(.l/2)) .nr x (\n(.l/5)
'in \n(.iu+\nxu
\*(T<(void);\*(T>
'in \n(.iu-\nxu
.ad b
.PP
.fi
.ad l
\*(T<int \fBsg_get_error_errno\fR\*(T> \kx
.if (\nx>(\n(.l/2)) .nr x (\n(.l/5)
'in \n(.iu+\nxu
\*(T<(void);\*(T>
'in \n(.iu-\nxu
.ad b
.PP
.fi
.ad l
\*(T<sg_error \fBsg_get_error_details\fR\*(T> \kx
.if (\nx>(\n(.l/2)) .nr x (\n(.l/5)
'in \n(.iu+\nxu
\*(T<(sg_error_details *\fIerr_details\fR);\*(T>
'in \n(.iu-\nxu
.ad b
.PP
.fi
.ad l
\*(T<const char *\fBsg_str_error\fR\*(T> \kx
.if (\nx>(\n(.l/2)) .nr x (\n(.l/5)
'in \n(.iu+\nxu
\*(T<(sg_error \fIcode\fR);\*(T>
'in \n(.iu-\nxu
.ad b
.PP
.fi
.ad l
\*(T<char *\fBsg_strperror\fR\*(T> \kx
.if (\nx>(\n(.l/2)) .nr x (\n(.l/5)
'in \n(.iu+\nxu
\*(T<(char **\fIbuf\fR, const sg_error_details * const \fIerr_details\fR);\*(T>
'in \n(.iu-\nxu
.ad b
'hy
.SH DESCRIPTION
There are four functions to get information about the last occurred
error: \*(T<\fBsg_get_error\fR\*(T>,
\*(T<\fBsg_get_error_arg\fR\*(T>,
\*(T<\fBsg_get_error_errno\fR\*(T> and
\*(T<\fBsg_get_error_details\fR\*(T>. The remaining
functions are intended to improve the machine-human-interface (e.g.
the error log or a message box): \*(T<\fBsg_str_error\fR\*(T>
delivers a human readable error name and \*(T<\fBsg_strperror\fR\*(T>
prepares a full blown error message for printing.
.PP
The error argument (\*(T<\fBsg_get_error_arg\fR\*(T>) is stored
thread local and is reused every time an error occures. If a later
usage is intended, duplicating it is a suitable strategy. Same for
the \*(T<error_arg\*(T> of
\*(T<sg_error_details\*(T> delivered by
\*(T<\fBsg_get_error_details\fR\*(T>.
.PP
When someone calls the function \*(T<\fBsg_get_error_details\fR\*(T>
with a NULL pointer, the last error is overridden with a new one
describing that \*(T<\fBsg_get_error_details\fR\*(T> is called
with invalid arguments. Please be careful.
.PP
The function \*(T<\fBsg_strperror\fR\*(T> is allowed to be called
with or without (\*(T<err_details\*(T> is NULL) collected
error details. In the latter case, the last occurred error of this thread
is used to prepare the error message. Be aware, the the buffer pointer
must be non-NULL (points to an existing \*(T<char *\*(T> lvalue),
but the \*(T<char *\*(T> lvalue it points to, must be NULL.
When invoked correctly, there are only two possible error conditions
let \*(T<\fBsg_strperror\fR\*(T> fail: ENOMEM
(out of memory) and EINVAL (invalid error code).

\fBExample\fR
.PP
.nf
\*(T<
if( NULL == sg_get_cpu_stats() ) {
    char *buf = NULL;
    if( NULL != sg_strperror( &buf, NULL ) ) {
        fprintf( stderr, "error getting CPU stats: %s\en", buf );
        free(buf);
        exit(255);
    }
    else {
        fprintf( stderr, "error getting CPU stats and error information\en" );
        exit(255);
    }
}
        \*(T>
.fi
.SH "RETURN VALUES"
The error details contains following information:
.PP
.nf
\*(T<
typedef struct sg_error_details {
        sg_error error;
        int errno_value;
        const char *error_arg;
} sg_error_details;
    \*(T>
.fi
.TP 
\*(T<error\*(T> 
The statgrab library error code.
.TP 
\*(T<errno_value\*(T> 
The operating system error code.
.TP 
\*(T<error_arg\*(T> 
Additional information set when the error was reported.
.SH "SEE ALSO"
\fBstatgrab\fR(3)
.SH WEBSITE
\(lahttps://libstatgrab.org/\(ra