#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;
}
unpv13e/sock/error.c
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.