这几个函数都会在字符串末尾加上null字节,但返回值是不包扩这个null字节的
在X/Open出的XSH 第四次发行第二版中只有第一个函数,后面的三个系统调用是没有的,不过在IEEE Std 1003.1-2008中都包含,The Open Group Base Specifications Issue 7中有这些函数,故这几个函数不会存在移植性问题,期中issue7中还有vdprintf,原型为int vdprintf(int fildes, const char *restrict format, va_list ap);,还有与dprintf对应的其他函数,用于对输出到文件描述符中,不同于以前的流和buffer。
下面是几个错误处理函数,steven的unix网络编程中写的,写的很完美,看他的代码就是一种享受,再看看自己的代码,错误多,不简洁,不健壮。。。
#include "error.h"
extern int daemon_proc;
static void
err_doit(int errnoflag,int level,const char *fmt,va_list ap)
{
int errno_save,n;
char buf[MAXLINE+1];
errno_save = errno;
#ifdef HAVE_VSNPRINTF
vsnprintf(buf,MAXLINE,fmt,ap);
#else
vsprintf(buf,fmt,ap);
#endif
n = strlen(buf);
if (errnoflag)
snprintf(buf+n,MAXLINE-n,": %s",strerror(errno_save));
strcat(buf,"\n");
if (daemon_proc) {
syslog(level,"%s",buf);//这儿对的,书上源码出现了一点点毗漏,书中没有“%s”,
} else {
fflush(stdout);
fputs(buf,stderr);
fflush(stderr);
}
return;
}
void
err_ret(const char *fmt,...)
{
va_list ap;
va_start(ap,fmt);
err_doit(1,LOG_INFO,fmt,ap);
va_end(ap);
return;
}
void
err_sys(const char *fmt,...)
{
va_list ap;
va_start(ap,fmt);
err_doit(1,LOG_ERR,fmt,ap);
va_end(ap);
exit(1);
}
void
err_dump(const char *fmt,...)
{
va_list ap;
va_start(ap,fmt);
err_doit(1,LOG_ERR,fmt,ap);
va_end(ap);
abort();
exit(1);
}
void
err_msg(const char *fmt,...)
{
va_list ap;
va_start(ap,fmt);
err_doit(0,LOG_INFO,fmt,ap);
va_end(ap);
return;
}
void
err_quit(const char *fmt,...)
{
va_list ap;
va_start(ap,fmt);
err_doit(0,LOG_ERR,fmt,ap);
va_end(ap);
exit(1);
}