附录A Wrapper 库参考
概述
Wrapper 库是课程提供的 C 语言工具库,封装了课程用到的所有系统调用。每个 Wrapper 函数在内部调用对应的系统调用并检查返回值,出错时自动打印错误信息并终止程序,从而简化实验代码的编写。
源文件组成:
| 文件 |
说明 |
wrapper.h |
头文件,包含所有函数声明、类型定义和常量 |
wrapper.c |
Wrapper 函数实现 |
ptwrapper.c |
POSIX 线程相关 Wrapper 函数 |
libwrapper.a |
预编译的静态库 |
编译与使用
头文件包含的系统头文件
常量与类型定义
进程控制
| 函数原型 |
对应系统调用 |
说明 |
pid_t Fork(void) |
fork |
创建子进程 |
void Execve(const char *f, char *const a[], char *const e[]) |
execve |
执行程序 |
pid_t Wait(int *status) |
wait |
等待任意子进程 |
pid_t Waitpid(pid_t pid, int *iptr, int options) |
waitpid |
等待指定子进程 |
void Kill(pid_t pid, int signum) |
kill |
发送信号 |
unsigned int Sleep(unsigned int secs) |
sleep |
休眠指定秒数 |
void Pause(void) |
pause |
暂停直到信号到达 |
unsigned int Alarm(unsigned int seconds) |
alarm |
设置定时器 |
void Setpgid(pid_t pid, pid_t pgid) |
setpgid |
设置进程组 |
pid_t Getpgrp(void) |
getpgrp |
获取当前进程组 |
示例:
文件 I/O
| 函数原型 |
对应系统调用 |
说明 |
int Open(const char *path, int flags, mode_t mode) |
open |
打开/创建文件 |
ssize_t Read(int fd, void *buf, size_t count) |
read |
读取数据 |
ssize_t Write(int fd, const void *buf, size_t count) |
write |
写入数据 |
off_t Lseek(int fd, off_t offset, int whence) |
lseek |
文件偏移定位 |
void Close(int fd) |
close |
关闭文件描述符 |
int Dup2(int fd1, int fd2) |
dup2 |
复制文件描述符 |
int Select(int n, fd_set *r, fd_set *w, fd_set *e, struct timeval *t) |
select |
I/O 多路复用 |
void Stat(const char *filename, struct stat *buf) |
stat |
获取文件状态 |
void Fstat(int fd, struct stat *buf) |
fstat |
获取文件状态 |
示例:
信号
| 函数原型 |
对应系统调用 |
说明 |
handler_t *Signal(int signum, handler_t *handler) |
signal |
注册信号处理函数 |
void Sigprocmask(int how, const sigset_t *set, sigset_t *old) |
sigprocmask |
修改信号屏蔽字 |
void Sigemptyset(sigset_t *set) |
sigemptyset |
清空信号集 |
void Sigfillset(sigset_t *set) |
sigfillset |
填满信号集 |
void Sigaddset(sigset_t *set, int signum) |
sigaddset |
添加信号到集合 |
void Sigdelset(sigset_t *set, int signum) |
sigdelset |
从集合移除信号 |
int Sigismember(const sigset_t *set, int signum) |
sigismember |
判断信号是否在集合中 |
示例:
标准 I/O
| 函数原型 |
对应标准库函数 |
说明 |
FILE *Fopen(const char *name, const char *mode) |
fopen |
打开文件 |
void Fclose(FILE *fp) |
fclose |
关闭文件 |
char *Fgets(char *ptr, int n, FILE *stream) |
fgets |
读取一行 |
void Fputs(const char *ptr, FILE *stream) |
fputs |
写入一行 |
size_t Fread(void *ptr, size_t size, size_t nmemb, FILE *stream) |
fread |
二进制读取 |
void Fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) |
fwrite |
二进制写入 |
FILE *Fdopen(int fd, const char *type) |
fdopen |
文件描述符转 FILE* |
内存管理
| 函数原型 |
对应标准库函数 |
说明 |
void *Malloc(size_t size) |
malloc |
分配内存 |
void *Realloc(void *ptr, size_t size) |
realloc |
重新分配内存 |
void *Calloc(size_t nmemb, size_t size) |
calloc |
分配并清零 |
void Free(void *ptr) |
free |
释放内存 |
内存映射
| 函数原型 |
对应系统调用 |
说明 |
void *Mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset) |
mmap |
创建内存映射 |
void Munmap(void *start, size_t length) |
munmap |
取消内存映射 |
Socket 编程
| 函数原型 |
对应系统调用 |
说明 |
int Socket(int domain, int type, int protocol) |
socket |
创建套接字 |
void Setsockopt(int s, int level, int opt, const void *val, int len) |
setsockopt |
设置套接字选项 |
void Bind(int sockfd, struct sockaddr *addr, int addrlen) |
bind |
绑定地址 |
void Listen(int s, int backlog) |
listen |
监听连接 |
int Accept(int s, struct sockaddr *addr, socklen_t *addrlen) |
accept |
接受连接 |
void Connect(int sockfd, struct sockaddr *addr, int addrlen) |
connect |
发起连接 |
DNS 解析
| 函数原型 |
说明 |
struct hostent *Gethostbyname(const char *name) |
按主机名解析 |
struct hostent *Gethostbyaddr(const char *addr, int len, int type) |
按地址解析 |
线程控制
| 函数原型 |
对应系统调用 |
说明 |
void Pthread_create(pthread_t *tid, pthread_attr_t *attr, void *(*r)(void *), void *arg) |
pthread_create |
创建线程 |
void Pthread_join(pthread_t tid, void **retval) |
pthread_join |
等待线程结束 |
void Pthread_detach(pthread_t tid) |
pthread_detach |
分离线程 |
void Pthread_cancel(pthread_t tid) |
pthread_cancel |
取消线程 |
void Pthread_exit(void *retval) |
pthread_exit |
终止线程 |
pthread_t Pthread_self(void) |
pthread_self |
获取当前线程 ID |
void Pthread_once(pthread_once_t *once, void (*init)()) |
pthread_once |
一次性初始化 |
POSIX 信号量
| 函数原型 |
对应系统调用 |
说明 |
void Sem_init(sem_t *sem, int pshared, unsigned int value) |
sem_init |
初始化信号量 |
void P(sem_t *sem) |
sem_wait |
等待(P 操作,值减 1) |
void V(sem_t *sem) |
sem_post |
释放(V 操作,值加 1) |
示例(生产者-消费者):
Robust I/O (Rio)
| 函数原型 |
说明 |
ssize_t rio_readn(int fd, void *buf, size_t n) |
无缓冲读取 n 字节 |
ssize_t rio_writen(int fd, void *buf, size_t n) |
无缓冲写入 n 字节 |
void rio_readinitb(rio_t *rp, int fd) |
初始化缓冲读取 |
ssize_t rio_readnb(rio_t *rp, void *buf, size_t n) |
带缓冲读取 n 字节 |
ssize_t rio_readlineb(rio_t *rp, void *buf, size_t maxlen) |
带缓冲读取一行 |
Wrapper 版本: Rio_readn、Rio_writen、Rio_readinitb、Rio_readnb、Rio_readlineb
客户端/服务器辅助函数
| 函数原型 |
说明 |
int open_client_sock(char *hostname, int port) |
创建客户端套接字并连接 |
int open_listen_sock(int port) |
创建服务器套接字并监听 |
int Open_client_sock(char *hostname, int port) |
同上(带错误检查) |
int Open_listen_sock(int port) |
同上(带错误检查) |
示例(服务器):
示例(客户端):
System V IPC
消息队列
| 函数原型 |
说明 |
int Msgget(key_t key, int msgflg) |
创建/获取消息队列 |
int Msgsnd(int msqid, const void *msg, size_t sz, int msgflg) |
发送消息 |
int Msgrcv(int msqid, void *msg, size_t sz, long type, int msgflg) |
接收消息 |
int Msgctl(int msqid, int cmd, struct msqid_ds *buf) |
控制消息队列 |
共享内存
| 函数原型 |
说明 |
int Shmget(key_t key, size_t size, int shmflg) |
创建/获取共享内存 |
char *Shmat(int shmid, const void *addr, int shmflg) |
附加共享内存 |
int Shmdt(const void *addr) |
分离共享内存 |
int Shmctl(int shmid, int cmd, struct shmid_ds *buf) |
控制共享内存 |
System V 信号量
| 函数原型 |
说明 |
int Semget(key_t key, int nsems, int semflg) |
创建/获取信号量集 |
int Semctl(int semid, int semnum, int cmd, union semun arg) |
控制信号量 |
int Semop(int semid, struct sembuf *sem, int sops) |
操作信号量 |
命名管道
| 函数原型 |
说明 |
int Mkfifo(const char *pathname, mode_t mode) |
创建命名管道 (FIFO) |
错误处理函数
Wrapper 库内部使用以下错误处理函数,也可在自己的代码中直接调用:
| 函数 |
说明 |
void unix_error(char *msg) |
打印系统调用错误并退出 |
void posix_error(int code, char *msg) |
打印 POSIX 错误并退出 |
void dns_error(char *msg) |
打印 DNS 错误并退出 |
void app_error(char *msg) |
打印应用错误并退出 |