编译方式可以是下面这样:
$ 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 */ }