3/18/22, 8:02 PM CMPUT379 – Error Handling
CMPUT 379: Experiments with the [APUE]
Error Handling Routines
1. Understanding Error Handling in [APUE 3/E]
Copyright By PowCoder代写 加微信 powcoder
Reference: source code on http://www.apuebook.com/, and Appendix B in [APUE 3/E]
The [APUE 3/E] book uses 7 functions for testing and displaying errors after system calls. (Another family of functions log errors to designated files.)
The design of this family of error handling functions
satisfies the following objectives:
1. Any function allows the use of a user specified printf-like formatted string that contains a variable number of user specified arguments (for printing context around the error location)
2. Following the processing of the user specified arguments, the function prints a text string corresponding to an integer error value (either user specified, or taken from the system’s errno)
3. A function then flushes buffered I/O data to the kernel
4. At the end, the function either
returns back to the user code for non fatal errors,
performs exit(1) for fatal errors, or performs abort(); exit(1) for generating a core dump file and exiting
The following table summarizes the above properties:
2. Implementation
The core function in the [APUE] implementation is function err_doit. The function takes 4 arguments: errnoflag: a value of 1 causes the function to
invoke strerror() to print a text explaining the
webdocs.cs.ualberta.ca/~cmput379/W22/379only/lab-error-handling.html
3/18/22, 8:02 PM CMPUT379 – Error Handling
error whose number is passed as an argument
error: either a user specified integer, or the value of errno
fmt: a printf-like format string
ap: a struct of type va_list
#define MAXLINE 4096 /* max line length */
// ——————————
// Print a message and return to caller. Caller specifies “errnoflag”.
// Source: [APUE 3/E]
static void err_doit(int errnoflag, int error, const char *fmt, va_list ap)
char buf[MAXLINE];
vsnprintf(buf, MAXLINE-1, fmt, ap);
if (errnoflag)
snprintf(buf+strlen(buf), MAXLINE-strlen(buf)-1, “: %s”,
strerror(error));
strcat(buf, “\n”);
fflush(stdout); /* in case stdout and stderr are the same */
fputs(buf, stderr);
fflush(NULL); /* flushes all stdio output streams */
Function err_quit is defined as:
// ——————————
// Fatal error unrelated to a system call. Print a message and terminate.
// Source: [APUE 3/E]
void err_quit(const char *fmt, …)
va_list ap;
va_start(ap, fmt);
err_doit(0, 0, fmt, ap);
va_end(ap);
And, function err_sys is defined as:
// ——————————
// Fatal error related to a system call. Print a message and terminate.
// Source: [APUE 3/E]
void err_sys(const char *fmt, …)
va_list ap;
va_start(ap, fmt);
err_doit(1, errno, fmt, ap);
va_end(ap);
3. Variable-length Argument Lists
The above code relies heavily on using variable-length argument lists. This topic is discussed in The C
webdocs.cs.ualberta.ca/~cmput379/W22/379only/lab-error-handling.html
3/18/22, 8:02 PM CMPUT379 – Error Handling
Programming Language, B. Kernighan and D. Ritchie, Sec. 7.3
In a nutshell, The C language allows a user to write a function that takes a variable-length argument list.
A function with one known argument, followed by a variable-length argument list appears as: foo (fmt, …)
To get the arguments passed to foo in a particular invocation, foo does the following:
Declares a variable of type va_list: e.g., va_list ap;
Initializes the variable to point to the 1st unnamed argument. This is done by executing va_start (ap, fmt)
foo then invokes a loop to access every argument in the variable list, and advances the pointer ap to the next argument; this is done by calling va_arg(ap, …)
When all arguments in the variable argument list
are processed, foo calls va_end(ap) to clean up. The above code then uses the following functions (see [AUPE 3/E] Sec. 5.11 on Formatted I/O):
int vsprintf (char *buf, const char *format, va_list
int snprintf (char *buf, size_t n, const char *format,
4. Suggested Activity
Test the above functions using, e.g., the following test_err.c program.
Use the following include files: stdio.h, stdlib.h, string.h, unistd.h, errno.h, stdarg.h, fcntl.h
#include …
#define MAXLINE 4096
static void err_doit( … ) { … }
void err_quit( … ) { … }
void err_sys( … ) { … }
int main (int argc, char *argv[])
// testing non-fatal error
if (argc != 20)
/* max line length */
err_quit (“wrong number of arguments (= %d)”, argc);
// testing with low level open()
if ( fd= open (“no_such_file”, O_RDONLY) < 0 )
err_sys ("unable to open file (errno= %d)", errno);
// testing with the standard I/O library fopen()
if ( (fp= fopen("no_such_file", "r")) == NULL )
err_sys ("fopen error (fp= %p)", fp);
Add other possible test lines
webdocs.cs.ualberta.ca/~cmput379/W22/379only/lab-error-handling.html
3/18/22, 8:02 PM CMPUT379 - Error Handling
5. Shorter Error Handling Routines
In the implementation of the AWK Programming Language
interpreter, the authors (A. Aho, B. Kernighan, and P.
Weinberger) have used two (shorter) error handling
#include .... (use the above list of include files)
void FATAL (const char *fmt, ... )
va_list ap;
fflush (stdout);
va_start (ap, fmt); vfprintf (stderr, fmt, ap); va_end(ap);
fflush (NULL);
void WARNING (const char *fmt, ... )
va_list ap;
fflush (stdout);
va_start (ap, fmt); vfprintf (stderr, fmt, ap); va_end(ap);
These two functions can be used, e.g., as:
WARNING ("wrong number of arguments (= %d) \n", argc);
FATAL ("unable to open file (errno= %d): %s \n", errno, strerror(errno));
More activity: Test the above functions in a program. 6. Acknowledgment
If you use the above code, acknowledge the [APUE 3/E]
book, or the code of the AWK programming language.
CMPUT 379: U. of Alberta, Author: E. Elmallah
webdocs.cs.ualberta.ca/~cmput379/W22/379only/lab-error-handling.html
程序代写 CS代考 加微信: powcoder QQ: 1823890830 Email: powcoder@163.com