
...
where rbytes
is a pointer to a size_t
. If no error occurs, and rbytes
is not NULL
, its value is set to the total number of bytes read, and read()
returns 0. If an error occurs, read()
returns a nonzero value indicating the error.
Noncompliant Code Example (C11, Annex K)
In this noncompliant code example, the error handler returns normally, but the strcpy_s()
function's return value is not checked:
Code Block | ||||
---|---|---|---|---|
| ||||
constraint_handler_t handle_errors(void) {
constraint_handler_t data;
/* Define what to do when error occurs */
return data;
}
/* ... */
set_constraint_handler(handle_errors);
/* ... */
/* Returns zero on success */
errno_t function(char *dst1, size_t dst_size) {
char src1[100] = "hello";
strcpy_s(dst1, dst_size, src1);
/*
* At this point strcpy_s may have yielded an
* error, and handle_errors() might have returned.
*/
/* ... */
return 0;
}
|
Compliant Solution (C11, Annex K)
In this compliant solution, the error handler terminates the program, ensuring that strcpy_s()
never returns unless it fully succeeds:
Code Block | ||||
---|---|---|---|---|
| ||||
/*
* The abort_handler_s() function writes
* a message on the standard error stream and
* then calls the abort() function.
*/
set_constraint_handler(abort_handler_s);
/* ... */
/* Returns zero on success */
errno_t function(char *dst1, size_t dst_size) {
char src1[100] = "hello";
strcpy_s(dst1, dst_size, src1);
/*
* Because abort_handler_s() never returns,
* we get here only if strcpy_s() succeeds.
*/
/* ... */
return 0;
}
|
Exceptions
ERR02-EX1: Null pointers are another example of an in-band error indicator. Use of null pointers is allowed because it is supported by the language. According to the C Standard, subclause 6.3.2.3 [ISO/IEC 9899:2011]:
...
ERR02-EX2: You may use a function returning in-band error indicators if you can securely guarantee the program will not try to continue processing should an error occur in the function. For example, the functions defined in C11 Annex K provide hooks for internal constraint violations. If a constraint violation handler is guaranteed not to return upon an error, then you may safely ignore errors returned by these functions. You might accomplish this by having the constraint-violation handler call abort()
or longjmp()
, for instance.See ERR03-C. Use runtime-constraint handlers when calling the bounds-checking interfaces for more on the functions defined in C11 Annex K.
Risk Assessment
The risk in using in-band error indicators is difficult to quantify and is consequently given as low. However, if the use of in-band error indicators results in programmers' failing to check status codes or incorrectly checking them, the consequences can be more severe.
...