《unix 环境高级编程》练习,附录B
常用函数头文件apue.h
#ifndef _APUE_H
#define _APUE_H
#define _XOPEN_SOURCE 600
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/termios.h>
#ifndef TIOCGWINSZ
#include <sys/ioctl.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#define MAXLINE 4096
/*
*Default file access permissions for new files.
*/
#define FILE_MODE (S_IRUSR | S_IWUSR | S_IROTH)
/*
*Default permissions for new directories.
*/
#define DIR_MODE (FILE_MODE | S_IXUSR | S_IXGRP | S_IXOTH)
typedef void Sigfunc(int);
#if defined(SIG_IGN) && !defined(SIG_ERR)
#define SIG_ERR ((Sigfunc *)-1)
#endif
#define min(a,b) ((a) < (b)? (a): (b))
#define max(a,b) ((a) > (b)? (a): (b))
/*
*Prototypes for our own functions.
*/
char *path_alloc(int *);
long open_max(void);
void clr_fl(int, int);
void set_fl(int, int);
void pr_exit(int);
void pr_mask(const char *);
Sigfunc *signal_intr(int, Sigfunc *);
int tty_cbreak(int);
int tty_raw(int);
int tty_reset(int);
void tty_atexit(void);
#ifdef ECHO /*only if <termios.h> has been included */
struct termios *tty_termios(void);
#endif
void sleep_us(unsigned int);
ssize_t readn(int, void *, size_t);
ssize_t writen(int, const void *, size_t);
void daemonize(const char *);
int s_pipe(int *);
int recv_fd(int, ssize_t (*func)(int, const void *, size_t));
int send_fd(int, int);
int send_err(int, int, const char *);
int serv_listen(const char *);
int serv_accept(int, uid_t *);
int cli_conn(const char *);
int buf_args(char *, int (*func)(int, char**));
int ptym_open(char *, int);
int ptys_open(char *);
#ifdef TIOCGWINSZ
pid_t pty_fork(int *, char *,int, const struct termios *, const struct winsize*);
#endif
int lock_reg(int, int, int, off_t, int, off_t);
#define read_lock(fd, offset, whence, len) lock_reg((fd), F_SETLK, F_RDLCK, (offset), (whence), (len))
#define readw_lock(fd, offset, whence, len) lock_reg((fd), FSETLKW, F_RDLCK, (offset), (whence), (len))
#define write_lock(fd, offset, whence, len) lock_reg((fd),F_SETLK, F_WRLCK,(offset), (whence), (len))
#define writew_lock(fd, offset, whence, len) lock_reg((fd), F_SETLKW, F_WRLCK, (offset), (whence), (len))
#define un_lock(fd, offset, whence, len) lock_reg((fd), F_SETLK, F_UNLCK, (offset), (whence), (len))
pid_t lock_test(int, int, off_t, int, off_t);
#define is_read_lockable(fd, offset, whence, len) (lock_test((fd), F_RDLCK, (offset), (whence), (len)) == 0)
#define is_write_lockable(fd, offset, whence, len) (lock_test((fd), F_WRLCK, (offset), (whence), (len)) == 0)
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*, ...);
void log_msg(const char *, ...);
void log_open(const char *, int, int);
void log_quit(const char *, ...);
void log_ret(const char *, ...);
void log_sys(const char *, ...);
void TELL_WAIT(void);
void TELL_PARENT(pid_t);
void TELL_CHILD(pid_t);
void WAIT_PARENT(void);
void WAIT_CHILD(void);
#endif
标准出错处理例程实现err_hand.c
#include "apue.h"
#include <errno.h>
#include <stdarg.h>
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 message 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();
exit(1);
}
/*
*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);
fputs(buf, stderr);
fflush(NULL);
}
关于孤儿进程orphan.c:
#include "apue.h"
#include <errno.h>
static void sig_hup(int signo)
{
printf("SIGHUP received, pid = %d\n", getpid());
}
static void pr_ids(char *name)
{
printf("%s: pid=%d, ppid=%d, pgrp=%d,tpgrp=%d\n", name, getpid(), getppid(), getpgrp(), tcgetpgrp(STDIN_FILENO));
fflush(stdout);
}
int main(void)
{
char c;
pid_t pid;
pr_ids("parent");
if((pid=fork())<0)
{
err_sys("fork error");
}
else if(pid > 0)
{
sleep(5);
exit(0);
}
else{
pr_ids("child");
signal(SIGHUP, sig_hup);
kill(getpid(), SIGTSTP);
pr_ids("child");
if(read(STDIN_FILENO, &c, 1) != 1)
{
printf("read error from controlling TTY, errno = %d\n", errno);
}
exit(0);
}
}
编译linux动态库:
[you@localhost test]
lsapue.herrhand.corphan.c[you@localhosttest]
ls -l
总用量 12
-rw-rw-r–. 1 you you 3049 1月 8 17:31 apue.h
-rw-rw-r–. 1 you you 1783 1月 8 19:08 err_hand.c
-rw-rw-r–. 1 you you 673 1月 15 23:37 orphan.c
[you@localhost test]
gcc−fpic−cerrhand.c[you@localhosttest]
ls -l
总用量 16
-rw-rw-r–. 1 you you 3049 1月 8 17:31 apue.h
-rw-rw-r–. 1 you you 1783 1月 8 19:08 err_hand.c
-rw-rw-r–. 1 you you 4088 1月 16 00:10 err_hand.o
-rw-rw-r–. 1 you you 673 1月 15 23:37 orphan.c
[you@localhost test]
gcc−shared−olibtest.soerrhand.o[you@localhosttest]
ls -l
总用量 32
-rw-rw-r–. 1 you you 3049 1月 8 17:31 apue.h
-rw-rw-r–. 1 you you 1783 1月 8 19:08 err_hand.c
-rw-rw-r–. 1 you you 4088 1月 16 00:10 err_hand.o
-rwxrwxr-x. 1 you you 12824 1月 16 00:11 libtest.so
-rw-rw-r–. 1 you you 673 1月 15 23:37 orphan.c
[you@localhost test]
gcc−ottorphan.c−L./−ltest[you@localhosttest]
ls -l
总用量 48
-rw-rw-r–. 1 you you 3049 1月 8 17:31 apue.h
-rw-rw-r–. 1 you you 1783 1月 8 19:08 err_hand.c
-rw-rw-r–. 1 you you 4088 1月 16 00:10 err_hand.o
-rwxrwxr-x. 1 you you 12824 1月 16 00:11 libtest.so
-rw-rw-r–. 1 you you 673 1月 15 23:37 orphan.c
-rwxrwxr-x. 1 you you 13400 1月 16 00:11 tt
[you@localhost test]
./ttparent:pid=7211,ppid=5515,pgrp=7211,tpgrp=7211child:pid=7212,ppid=7211,pgrp=7211,tpgrp=7211SIGHUPreceived,pid=7212child:pid=7212,ppid=1,pgrp=7211,tpgrp=7211[you@localhosttest]
动态库参考:http://blog.csdn.net/tigerjibo/article/details/6992531