B.2 Standard Error Routines

team bbl


Two sets of error functions are used in most of the examples throughout the text to handle error conditions. One set begins with err_ and outputs an error message to standard error. The other set begins with log_ and is for daemon processes (Chapter 13) that probably have no controlling terminal.

The reason for our own error functions is to let us write our error handling with a single line of C code, as in

     if (error condition)               err_dump(printf format with any number of arguments); 

instead of

     if (error condition){               char buf[200];               sprintf(buf, printf format with any number of arguments);               perror(buf);               abort();     } 

Our error functions use the variable-length argument list facility from ISO C. See Section 7.3 of Kernighan and Ritchie [1988] for additional details. Be aware that this ISO C facility differs from the varargs facility provided by earlier systems (such as SVR3 and 4.3BSD). The names of the macros are the same, but the arguments to some of the macros have changed.

Figure B.2 summarizes the differences between the various error functions.

Figure B.2. Our standard error functions

Function

Adds string from strerror ?

Parameter to strerror

Terminate ?

err_dump

yes

errno

abort();

err_exit

yes

explicit parameter

exit(1);

err_msg

no

 

return;

err_quit

no

 

exit(1);

err_ret

yes

errno

return;

err_sys

yes

errno

exit(1);

log_msg

no

 

return;

log_quit

no

 

exit(2);

log_ret

yes

errno

return;

log_sys

yes

errno

exit(2);


Figure B.3 shows the error functions that output to standard error.

Figure B.3. Error functions that output to standard error
 #include "apue.h" #include <errno.h>      /* for definition of errno */ #include <stdarg.h>     /* ISO C variable aruments */ static void err_doit(int, int, const char *, va_list); /*  * Nonfatal error related to a system call.  * Print a message and return.  */ void err_ret(const char *fmt, ...) {     va_list     ap;     va_start(ap, fmt);     err_doit(1, errno, fmt, ap);     va_end(ap); } /*  * Fatal error related to a system call.  * Print a message and terminate.  */ void err_sys(const char *fmt, ...) {     va_list     ap;     va_start(ap, fmt);     err_doit(1, errno, fmt, ap);     va_end(ap);     exit(1); } /*  * Fatal error unrelated to a system call.  * Error code passed as explict parameter.  * Print a message and terminate.  */ void err_exit(int error, const char *fmt, ...) {     va_list     ap;     va_start(ap, fmt);     err_doit(1, error, fmt, ap);     va_end(ap);     exit(1); } /*  * Fatal error related to a system call.  * Print a message, dump core, and terminate.  */ void err_dump(const char *fmt, ...) {     va_list     ap;     va_start(ap, fmt);     err_doit(1, errno, fmt, ap);     va_end(ap);     abort();        /* dump core and terminate */     exit(1);        /* shouldn't get here */ } /*  * Nonfatal error unrelated to a system call.  * Print a message and return.  */ void err_msg(const char *fmt, ...) {     va_list     ap;     va_start(ap, fmt);     err_doit(0, 0, fmt, ap);     va_end(ap); } /*  * Fatal error unrelated to a system call.  * Print a message and terminate.  */ void err_quit(const char *fmt, ...) {     va_list     ap;     va_start(ap, fmt);     err_doit(0, 0, fmt, ap);     va_end(ap);     exit(1); } /*  * Print a message and return to caller.  * Caller specifies "errnoflag".  */ static void err_doit(int errnoflag, int error, const char *fmt, va_list ap) {     char    buf[MAXLINE];    vsnprintf(buf, MAXLINE, fmt, ap);    if (errnoflag)        snprintf(buf+strlen(buf), MAXLINE-strlen(buf), ": %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 */ } 

Figure B.4 shows the log_XXX error functions. These require the caller to define the variable log_to_stderr and set it nonzero if the process is not running as a daemon. In this case, the error messages are sent to standard error. If the log_to_stderr flag is 0, the syslog facility (Section 13.4) is used.

Figure B.4. Error functions for daemons
 /*  * Error routines for programs that can run as a daemon.  */ #include "apue.h" #include <errno.h>      /* for definition of errno */ #include <stdarg.h>     /* ISO C variable arguments */ #include <syslog.h> static void log_doit(int, int, const char *, va_list ap); /*  * Caller must define and set this: nonzero if  * interactive, zero if daemon  */ extern int log_to_stderr; /*  * Initialize syslog(), if running as daemon.  */ void log_open(const char *ident, int option, int facility) {     if (log_to_stderr == 0)         openlog(ident, option, facility); } /*  * Nonfatal error related to a system call.  * Print a message with the system's errno value and return.  */ void log_ret(const char *fmt, ...) {     va_list     ap;     va_start(ap, fmt);     log_doit(1, LOG_ERR, fmt, ap);     va_end(ap); } /*  * Fatal error related to a system call.  * Print a message and terminate.  */ void log_sys(const char *fmt, ...) {     va_list     ap;     va_start(ap, fmt);     log_doit(1, LOG_ERR, fmt, ap);     va_end(ap);     exit(2); } /*  * Nonfatal error unrelated to a system call.  * Print a message and return.  */ void log_msg(const char *fmt, ...) {     va_list ap;     va_start(ap, fmt);     log_doit(0, LOG_ERR, fmt, ap);     va_end(ap); } /*  * Fatal error unrelated to a system call.  * Print a message and terminate.  */ void log_quit(const char *fmt, ...) {     va_list     ap;     va_start(ap, fmt);     log_doit(0, LOG_ERR, fmt, ap);     va_end(ap);     exit(2); } /*  * Print a message and return to caller.  * Caller specifies "errnoflag" and "priority".  */ static void log_doit(int errnoflag, int priority, const char *fmt, va_list ap) {     int     errno_save;     char    buf[MAXLINE];     errno_save = errno;     /* value caller might want printed */     vsnprintf(buf, MAXLINE, fmt, ap);     if (errnoflag)         snprintf(buf+strlen(buf), MAXLINE-strlen(buf), ": %s",           strerror(errno_save));     strcat(buf, "\n");     if (log_to_stderr) {         fflush(stdout);         fputs(buf, stderr);         fflush(stderr);     } else {         syslog(priority, buf);     } } 

    team bbl



    Advanced Programming in the UNIX Environment
    Advanced Programming in the UNIX Environment, Second Edition (Addison-Wesley Professional Computing Series)
    ISBN: 0321525949
    EAN: 2147483647
    Year: 2005
    Pages: 370

    flylib.com © 2008-2017.
    If you may any questions please contact us: flylib@qtcs.net