编译方式可以是下面这样:
$ gcc -Wall -g -o test ./p1-1.c ./apue.c
注意:-Wall 是为了显示所有的错误信息-g 是为了在程序中加入用于gdb调试的信息-o 是为了指定程序的名称 test
《UNIX环境高级编程》的 程序清单1-1 是 列出一个目录中的所有文件
下面是程序正文:
/* program 1-1 */
/* www.nibaozhu.cn */
#include "./apue.h"
#include <dirent.h>
int main(int argc, char **argv){
DIR *dp;
struct dirent *dirp;
if (argc != 2){
err_quit("Usage: ls directory_name");
}
if ((dp = opendir(argv[1])) == NULL)
err_sys("can't open %s", argv[1]);
while ((dirp = readdir(dp)) != NULL)
printf("%s\n", dirp->d_name);
closedir(dp);
exit(0);
}
它包含了一个 作者自己写的 头文件 apue.h (是 Advanced Programming in the UNIX Environment 的简写)。
这个头文件在附录B被列出来。如下所示(仅用于程序1-1,故有删减):
<pre code_snippet_id="142599" snippet_file_name="blog_20140104_2_5441809" name="code" class="cpp">/* www.nibaozhu.cn */
/* Our own header, to be included before all standard system headers */
#define _APUE_H
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#define MAXLINE (1024*4)
void err_dump(const char *, ...);
void err_msg (const char *, ...);
void err_quit(const char *, ...);
void err_exit(int, const char *, ...);
void err_ret (const char *, ...);
void err_sys (const char *, ...);
#endif // _APUE_H
这些错误处理函数的实现体如下:
/* www.nibaozhu.cn */
#include "./apue.h"
#include <errno.h> /* for definition of errno */
#include <stdarg.h> /* ISO C variable argument */
static void err_doit(int, int, const char *, va_list);
/*
* Nonfatal error related to a system call.
* Print a message and return.
*/
void
err_ret(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
err_doit(1, errno, fmt, ap);
va_end(ap);
}
/*
* Fatal error related to a system call.
* Print a messgae and terminate.
*/
void
err_sys(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
err_doit(1, errno, fmt, ap);
va_end(ap);
exit(1);
}
/*
* Fatal error unrelated to a system call.
* Error code passed as explict parameter.
* Print a message and terminate.
*/
void
err_exit(int error, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
err_doit(1, error, fmt, ap);
va_end(ap);
exit(1);
}
/*
* Fatal error related to a system call.
* Print a message, dump core, and terminate.
*/
void
err_dump(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
err_doit(1, errno, 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
err_msg(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
err_doit(0, 0, fmt, ap);
va_end(ap);
}
/*
* Fatal error unrelated to a system call.
* Print a message and terminate.
*/
void
err_quit(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
err_doit(0, 0, fmt, ap);
va_end(ap);
exit(1);
}
/*
* Print a message and return to caller.
* Caller specifies "errnoflag"
*/
static void
err_doit(int errnoflag, int error, const char *fmt, va_list ap)
{
char buf[MAXLINE];
vsnprintf(buf, MAXLINE, fmt, ap);
if (errnoflag)
snprintf(buf + strlen(buf), MAXLINE - strlen(buf), ": %s",
strerror(error));
strcat(buf, "\n");
fflush(stdout); /* in case stdout and stderr are the same */
fputs(buf, stderr);
fflush(NULL); /* fflushes all stdio output streams */
}