#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
最新推荐文章于 2022-04-27 17:42:38 发布