Linux系统编程错误处理函数

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_38253837/article/details/80397818

作为linux的菜鸟,最近在看《Linux/Uinx系统编程手册》,不得不说这是本很好很好的书。今天整理了一下在本书上册开始部分给出的错误处理函数如下,希望对大家有所帮助:

//tlpi_hdr.h
#ifndef TPLI_HDR_H
#define TPLI_HDR_H  /*Prevent accidental double inclusion*/

#include <sys/types.h>  /*Type definitionos used by many programs*/
#include <stdio.h>  /*Standard I/O function*/
#include <stdlib.h> /**Prototypes of commonly used library functions, plus EXIT_SUCCESS and EXIT_FAILURE constants*/

#include <unistd.h> /*Prototypes for many system calls*/
#include <errno.h>  /*Declares errno and defines error constants*/
#include <string.h> /*Commonly used string-handing functions*/

#include "get_num.h"    /*Declares our functions for handing numeric arguments (getInt(), getLong())*/

#include "error_functions.h"    /*Declars our error-handing functions*/

typedef enum {
    FALSE,
    TRUE
}Boolean;

#define min(m, n) ((m) < (n) ? (m) : (n))
#define max(m, n) ((m) > (n) ? (m) : (n))

#endif
//error_functions.h
#ifndef ERROR_FUNCTIONS
#define ERROR_FUNCTIONS

void errMsg(const char *format, ...);

#ifdef _GNUC_
#define NORETURN _attribute_ ((_noreturn))
#else
#define NORETURN
#endif

void errExit(const char *format, ...) NORETURN;
void err_exit(const char *format, ...) NORETURN;
void errExitEN(int errnum, const char *format, ...) NORETURN;
void fatal(const char *format, ...) NORETURN;
void usageErr(const char *format, ...) NORETURN;
void cmdLineErr(const char *format, ...) NORETURN;

#endif 
//error_functions.c
#include <stdarg.h>
#include "error_functions.h"
#include "tlpi_hdr.h"
#include "ename.c.inc"

#ifdef _GNUC_ 
_attribute_((_noreturn_))

#endif

static void 
terminate(Boolean useExit3) {
    char *s;
    s = getenv("EF_DUMPCORE");

    if (s != NULL && *s != '\0') {
        abort();
    }
    else if (useExit3) {
        exit(EXIT_FAILURE);
    }
    else {
        _exit(EXIT_FAILURE);
    }
}

static void 
outputError(Boolean useErr, int err, Boolean flushStdout,
                const char *format, va_list ap) {
#define BUF_SIZE 500
    char buf[BUF_SIZE], userMsg[BUF_SIZE], errText[BUF_SIZE];

    vsnprintf(userMsg, BUF_SIZE, format, ap);

    if (useErr) {
        snprintf(errText, BUF_SIZE, " [%s %s]",
                    (err > 0 && err <= MAX_ENAME) ? 
                    ename[err] : "?UNKNOWN?", strerror(err));
    }
    else {
        snprintf(errText, BUF_SIZE, ":");
    }
    snprintf(buf, BUF_SIZE, "ERROR%s %s\n", errText, userMsg);

    if (flushStdout) {
        fflush(stdout);
    }
    fputs(buf, stderr);
    fflush(stderr);
}

void errMsg(const char*format, ...) {
    va_list argList;
    int saveErrno;

    saveErrno = errno;
    va_start(argList, format);
    outputError(TRUE, errno, TRUE, format, argList);
    va_end(argList);

    errno = saveErrno;
}

void 
errExit(const char *format, ...) {
    va_list argList;

    va_start(argList, format);
    outputError(TRUE, errno, TRUE, format, argList);
    va_end(argList);

    terminate(TRUE);
}

void
err_exit(const char *format, ...) {
    va_list argList;

    va_start(argList, format);
    outputError(TRUE, errno, FALSE, format, argList);
    va_end(argList);

    terminate(FALSE);
}

void
errExitEN(int errnum, const char *format, ...) {
    va_list argList;

    va_start(argList, format);
    outputError(TRUE, errnum, TRUE, format, argList);
    va_end(argList);

    terminate(TRUE);
}

void 
fatal(const char *format, ...) {
    va_list argList;

    va_start(argList, format);
    outputError(FALSE, 0, TRUE, format, argList);
    va_end(argList);

    terminate(TRUE);
}

void 
usageErr(const char *format, ...) {
    va_list argList;

    fflush(stdout);

    fprintf(stderr, "Usage:");
    va_start(argList, format);
    vfprintf(stderr, format, argList);
    va_end(argList);

    exit(EXIT_FAILURE);
}

void 
cmdLineErr(const char *format, ...) {
    va_list argList;

    fflush(stdout);

    fprintf(stderr, "Command-line usage error:");
    va_start(argList, format);
    vfprintf(stderr, format, argList);
    va_end(argList);

    fflush(stderr);
    exit(EXIT_FAILURE);
}
//get_num.h
#ifndef GET_NUM_H
#define GET_NUM_H

#define GN_NONNEG 01    /*Value mustmust be > 0*/

#define GN_GT_0 02  /*Value*/ 
#define GN_ANY_BASE 0100    /*By default, integers are decimal*/
#define GN_BASE_8 0200  /*Can use any base - like strtol(3)*/
#define GN_BASE_16 0400     /*Value is expressed in octal*/

long getLong(const char *arg, int flags, const char *name);
int getInt(const char *arg, int flags, const char *name);

#endif
//get_num.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <errno.h>
#include "get_num.h"

static void 
gnFail(const char *fname, const char *msg, const char *arg, const char *name) {
    fprintf(stderr, "%s error", fname); 
    if (name != NULL) {
        fprintf(stderr, "(in %s)", name);
    }
    fprintf(stderr, ": %s\n", msg);
    if (arg != NULL && *arg != '\0') {
        fprintf(stderr, "       offending text :%s\n", arg);
    }
    exit(EXIT_FAILURE);
}

static long
getNum(const char *fname, const char *arg, int flags, const char *name) {
    long res;
    char *endptr;
    int base;

    if (arg == NULL || *arg == '\0') {
        gnFail(fname, "null or empty string", arg, name);
    }

    base = (flags & GN_ANY_BASE) ? 0 : (flags & GN_BASE_8) ? 8:
                        (flags & GN_BASE_16) ? 16 : 10;

    errno = 0;
    res = strtol(arg, &endptr, base);
    if (errno != 0) {
        gnFail(fname, "strtol() failed", arg, name);
    }
    if (*endptr != '\0') {
        gnFail(fname, "nonnumeric characters", arg, name);
    }
    if (flags & GN_NONNEG && res < 0) {
        gnFail(fname, "negative value not allowed", arg, name);
    }
    if ((flags & GN_GT_0) && res <= 0) {
        gnFail(fname, "value must be > 0", arg, name);
    }

    return res;
}
long 
getLong(const char *arg, int flags, const char *name) {
    return getNum("getLong", arg, flags, name);
}
int 
getInt(const char *arg, int flags, const char *name) {
    long res;

    res = getNum("getInt", arg, flags, name);
    if (res > INT_MAX || res < INT_MIN) {
        gnFail("getInt", "integer out of range", arg, name);
    }
    return (int)res;
}
//ename.c.inc
static char *ename[] = {
    /*  0*/ "",
    /*  1*/ "EPERM", "ENOENT", "ESRCH", "EINTR", "EIO", "ENXIO", "E2BIG",
    /*  8*/ "ENOEXEC", "EBADF", "ECHILD", "EAGAIN/EWOULDBLOCK", "ENOMEM",
    /* 13*/ "EACCES", "EFAULT", "ENOTBLK", "EBUSY", "EEXIT", "EXDEV",
    /* 19*/ "ENODEV", "ENOTDIR", "EISDIR", "EINVAL", "ENFILE", "EMFILE",
    /* 25*/ "ENOTTY", "ERXTBSY", "EFBIG", "ENOSPC", "ESPIPE", "EROFS",
    /* 31*/ "EMLINK", "EPIPE", "EDOM", "ERANG", "EDEADLK/EDEADLOCK",
    /* 36*/ "ENAMETOOLONG", "ENOLCK", "ENOSYS", "ENOTEMPTY", "ELOOP",
    /* 42*/ "ENOMSG", "EIDRM", "ECHRNG", "EL2NSYNC", "EL3HLT", "EL3RST",
    /* 48*/ "ELNTNG", "EUNATCH", "ENOCSI", "EL2HLT", "EBADE", "EBADR", 
    /* 54*/ "EXFULL", "ENOANO", "EBASRQC", "EBADSLT", "", "EBFONT", "ENOSTR",
    /* 61*/ "ENODATA", "ETIME", "ENOSR", "ENONET", "ENOPKG", "EREMOTE",
    /* 67*/ "ENOLINK", "EADV", "ESRMNT", "ECOMM", "EPROTO", "EMULTIHOP", 
    /* 73*/ "EDOTDOT", "EBADMSG", "EOVERFLOW", "ENOTUNIO", "EBADFD",
    /* 78*/ "EREMCHG", "ELIBACC", "ELIBBAD", "ELIBSCN", "ELIBMAX",
    /* 83*/ "ELIBEXEC", "EILSEQ", "ERESTART", "ESTRPIPE", "EUSERS",
    /* 88*/ "ENOTSOCK", "EDESTADDRREQ", "EMSGSIZE", "EPROTOTYPE", 
    /* 92*/ "ENOPROTOOPT", "EPROTONOSUPPORT", "ESOCKTNOSUPPORT",
    /* 95*/ "EOPNOTSUPP/ENOTSUP", "EPFNSUPPORT", "EAFNOSUPPORT",
    /* 98*/ "EADDRINUSE", "EADDRNOTAVAIL", "ENETDOWN", "ENETUNREACH",
    /*102*/ "ENETRESET", "ECONNABORTED", "ECONNREACH", "ENOBUFS", "EISCONN",
    /*107*/ "ENOTCONN", "ESHUTDOWN", "ETOOMANYREFS", "ETIMEOUT",
    /*111*/ "ECONNREFUSED", "EHOSTDOWN", "EHOSTUNREACH", "EALREADY",
    /*115*/ "EINPROGRESS", "ESTALE", "EUCLEAN", "ENOTNAM", "ENAVAIL",
    /*120*/ "EISNAM", "EREMOTEIO", "EDQUOT", "ENOMEDIUM", "EMEDIUMTYPE",
    /*125*/ "ECANCELED", "ENOKEY", "EKEYEXPIRED", "EKEYREVOKED",
    /*129*/ "EKEYREJECTED", "EOWNERDEAD", "ENOTRCOVERABLE", "ERFKILL"
};
#define MAX_ENAME 132

猜你喜欢

转载自blog.csdn.net/qq_38253837/article/details/80397818