unpv13e/sock/error.c

本文介绍了C语言中处理可变参数的机制,通过使用stdarg.h头文件中的宏和数据类型来实现。文章详细解释了va_list、va_start、va_arg、va_end等宏的作用,并给出了具体的函数实现示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值