unpv13e/sock/error.c

#include    <errno.h>       /* for definition of errno */
#include    <stdarg.h>      /* ANSI C header file */
#include    "ourhdr.h"

static void err_doit(int, const char *, va_list);

char    *pname = NULL;      /* caller can set this from argv[0] */

/* Nonfatal error related to a system call.
 * Print a message and return. */


 /*
    頭文件:<stdarg.h>
    1.意義:是C語言中C標準函數庫的標頭檔,stdarg是由stdandard(標準) arguments(參數)簡化而來,
    主要目的爲讓函數能夠接收不定量參數;

    2.頭文件位置:在Ubuntu16.04環境下,頭文件不在/usr/include下,而在/usr/lib/gcc/x86_64-linux-gnu/5/include下。

    3.數據類型和宏
                    名稱      |           描述                          |   相容
    數據類型        va_list     |   用來保存宏va_arg與宏va_end所需信息     |   C89
        宏           va_start    |   使va_list指向起始的參數                 |   C89
        宏           va_arg      |   檢索參數                                |   C89
        宏           va_end      |   釋放va_list                               |   C89 
        宏           va_copy     |   拷貝va_list的內容                        |   C89 

    4.宏定義
    #define _INTSIZEOF(n) ((sizeof(n)+sizeof(int)-1)&~(sizeof(int) - 1) )      //整個做的事情就是將n的長度化爲int長度的整數倍
    #define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) )                 //第一個可選參數地址;
                                                                                //獲取v變量的地址和v的長度,求得在v的下一個東西的起始地址,保存在指針ap中
    #define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )      //下一個參數地址
    #define va_end(ap) ( ap = (va_list)0 )                                      // 將指針置爲無效

    函數在堆棧中的分佈情況是:地址從高到低,依次是:函數參數列表,函數返回地址,函數執行代碼段


 */



void
/* $f err_ret $ */
err_ret(const char *fmt, ...)
{
    va_list     ap;

    va_start(ap, fmt);
    err_doit(1, fmt, ap);
    va_end(ap);
    return;
}

/* Fatal error related to a system call.
 * Print a message and terminate. */

void
/* $f err_sys $ */
err_sys(const char *fmt, ...)
{
    va_list     ap;

    va_start(ap, fmt);
    err_doit(1, fmt, ap);
    va_end(ap);
    exit(1);
}

/* Fatal error related to a system call.
 * Print a message, dump core, and terminate. */

void
/* $f err_dump $ */
err_dump(const char *fmt, ...)
{
    va_list     ap;

    va_start(ap, fmt);
    err_doit(1, 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
/* $f err_msg $ */
err_msg(const char *fmt, ...)
{
    va_list     ap;

    va_start(ap, fmt);
    err_doit(0, fmt, ap);
    va_end(ap);
    return;
}

/* Fatal error unrelated to a system call.
 * Print a message and terminate. */

void
/* $f err_quit $ */
err_quit(const char *fmt, ...)
{
    va_list     ap;

    va_start(ap, fmt);
    err_doit(0, fmt, ap);
    va_end(ap);
    exit(1);
}

/* Print a message and return to caller.
 * Caller specifies "errnoflag". */

static void
err_doit(int errnoflag, const char *fmt, va_list ap)
{
    int     errno_save;
    char    buf[MAXLINE];

    errno_save = errno;     /* value caller might want printed */
    vsprintf(buf, fmt, ap);
    if (errnoflag)
        sprintf(buf+strlen(buf), ": %s", strerror(errno_save));
    strcat(buf, "\n");
    fflush(stdout);     /* in case stdout and stderr are the same */
    fputs(buf, stderr);
    fflush(stderr);     /* SunOS 4.1.* doesn't grok NULL argument */
    return;
}
發佈了51 篇原創文章 · 獲贊 27 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章