📄 00000020.htm
字号:
pid_t lock_test(int, int, off_t, int, off_t); <BR> /* {Prog <BR>locktest} */ <BR>#define is_readlock(fd, offset, whence, len) \ <BR> lock_test(fd, F_RDLCK, offset, whence, len) <BR>#define is_writelock(fd, offset, whence, len) \ <BR> lock_test(fd, F_WRLCK, offset, whence, len) <BR>void err_dump(const char *, ...); /* {App misc_source} */ <BR>void err_msg(const char *, ...); <BR>void err_quit(const char *, ...); <BR>void err_ret(const char *, ...); <BR>void err_sys(const char *, ...); <BR>void log_msg(const char *, ...); /* {App misc_source} */ <BR>void log_open(const char *, int, int); <BR>void log_quit(const char *, ...); <BR>void log_ret(const char *, ...); <BR>void log_sys(const char *, ...); <BR>void TELL_WAIT(void); /* parent/child from {Sec race_condition <BR>} */ <BR>void TELL_PARENT(pid_t); <BR>void TELL_CHILD(pid_t); <BR>void WAIT_PARENT(void); <BR>void WAIT_CHILD(void); <BR>#endif /* __ourhdr_h */ <BR>程序B.1 我们的头文件ourhdr.h <BR> 在程序中先包括一般系统头文件,然后再包括ourhdr.h,这样就能解决某些系统 <BR>之间的差别(例如4.3BSDReno中没有定义SIG_ERR),并且也可定义一些我们的函 <BR>数原型,而这些仅当包括一般系统头文件之后才是需要的。当尚未定义某个结构就 <BR>在原型中引用该结构时,某些ANSI C编译会认为不正常。 <BR>B.2 标准出错处理例程 <BR> 我们提供了两套出错处理例程,它们用于本书中大多数实例以处理各种出错情况 <BR>。一套例程以err_开头,并向标准出错文件输出一条出错消息。另一套例程以log <BR>_开头,用于精灵进程(第十三章),它们多半没有控制终端。 <BR> 提供了这些出错处理函数后,只要在程序中写一行代码就可以进行出错处理,例 <BR>如: <BR> if (出错条件) <BR> err_dump(带任意参数的printf格式); <BR>这样也就不再需要使用下列代码: <BR> if (出错条件) { <BR> char buff[200]; <BR> sprintf(buff, 带任意参数的printf格式); <BR> perror(buff); <BR> abort( ); <BR> } <BR> 我们的出错处理函数使用了ANSI C的变长参数表功能。其详细说明见Kernighan和 <BR>Ritchie[1998]的7.3接。应当注意的是这一ANSI C功能与较早系统(例如SVR3和4 <BR>.3BSD)提供的varargs功能不同。宏的名字相同,但更改了某些宏的参数。 <BR> 图B.1列出了各个出错处理函数之间的区别。 <BR>Function strerror(errno)? Teerminate? <BR>Err_ret yes return; <BR>Err_sys yes exit(0); <BR>Err_dump yes abort(); <BR>Err_msg no return; <BR>Err_quit no exit(1); <BR>Log_ret yes return; <BR>Log_sys yes exit(2); <BR>Log_msg no return; <BR> if (出错条件) <BR> err_dump(带任意参数的printf格式); <BR>这样也就不再需要使用下列代码: <BR> if (出错条件) { <BR> char buff[200]; <BR> sprintf(buff, 带任意参数的printf格式); <BR> perror(buff); <BR> abort( ); <BR> } <BR> 我们的出错处理函数使用了ANSI C的变长参数表功能。其详细说明见Kernighan和 <BR>Ritchie[1998]的7.3接。应当注意的是这一ANSI C功能与较早系统(例如SVR3和4 <BR>.3BSD)提供的varargs功能不同。宏的名字相同,但更改了某些宏的参数。 <BR> 图B.1列出了各个出错处理函数之间的区别。 <BR>Function strerror(errno)? Teerminate? <BR>Err_ret yes return; <BR>Err_sys yes exit(0); <BR>Err_dump yes abort(); <BR>Err_msg no return; <BR>Err_quit no exit(1); <BR>Log_ret yes return; <BR>Log_sys yes exit(2); <BR>Log_msg no return; <BR>Log_quit no exit(2); <BR> <BR>图B.1 我们的标准出错处理函数 <BR>程序B.2包括了输出至标准出错文件的各个出错处理函数。 <BR>#include <errno.h> /* for definition of errno */ <BR>#include <stdarg.h> /* ANSI C header file */ <BR>#include "ourhdr.h" <BR>static void err_doit(int, const char *, va_list); <BR>char *pname = NULL; /* caller can set this from argv[0] */ <BR>/* Nonfatal error related to a system call. <BR> * Print a message and return. */ <BR>void <BR>err_ret(const char *fmt, ...) <BR>{ <BR> va_list ap; <BR> va_start(ap, fmt); <BR> err_doit(1, fmt, ap); <BR> va_end(ap); <BR> return; <BR>} <BR>/* Fatal error related to a system call. <BR> * Print a message and terminate. */ <BR>void <BR>err_sys(const char *fmt, ...) <BR>{ <BR> va_list ap; <BR> va_start(ap, fmt); <BR> err_doit(1, fmt, ap); <BR> va_end(ap); <BR> exit(1); <BR>} <BR>/* Fatal error related to a system call. <BR> * Print a message, dump core, and terminate. */ <BR>void <BR>err_dump(const char *fmt, ...) <BR>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -