《UNIX网络编程》例子程序中所使用的包裹函数及部分常量

来源:互联网 发布:欢迎来到东莫村 知乎 编辑:程序博客网 时间:2024/04/30 06:41
原文连接 http://blog.csdn.net/small_qch/article/details/8096701

《UNIX网络编程套接字联网API》这本书的示例中定义了许多包裹函数,它们的名称和标准函数一样,只是首字母变成大写字母;每个包裹函数完成实际的函数调用,检查返回值,并在发生错误时终止程序。

我在重写书上例子的时候,也仿照书上的方式,定义了许多包裹函数,提高程序的可读性(当然,我定义的包裹函数的错误处理没有书上例子这么详细了)

PS:这篇文章(博客)会持续更新。

文件my_unp.h:它定义了一些常量,声明了所有的包裹函数

[cpp] view plaincopyprint?
  1. #ifndef MY_UNP_H_    
  2. #define MY_UNP_H_    
  3.   
  4. #include <stdio.h>    
  5. #include <stdarg.h>    
  6. #include <stdlib.h>    
  7. #include <string.h>    
  8. #include <time.h>    
  9.   
  10. #include <unistd.h>    
  11. #include <errno.h>    
  12. #include <pthread.h>  
  13. #include <semaphore.h>  
  14. #include <sys/socket.h>    
  15. #include <sys/wait.h>    
  16. #include <netinet/in.h>    
  17. #include <arpa/inet.h>    
  18. #include <sys/select.h>    
  19. #include <sys/epoll.h>    
  20. #include <sys/poll.h>    
  21. #include <sys/file.h>    
  22. #include <sys/mman.h>  
  23.   
  24. #define MAXLINE 1024    
  25. #define LISTENQ 1024    
  26.   
  27. #define MAXNITEMS 1000000  
  28. #define MAXNTHREADS 100  
  29.   
  30. #define SERV_PORT 9877    
  31. #define SERV_PORT_STR "9877"    
  32.   
  33. #define SA struct sockaddr    
  34. typedef void Sigfunc(int);    
  35.   
  36. #define min(a,b)    ((a) < (b) ? (a) : (b))    
  37. #define max(a,b)    ((a) > (b) ? (a) : (b))    
  38.   
  39.   
  40. //错误处理函数,输出错误信息后退出程序    
  41. void error_quit(char *fmt, ...);    
  42.   
  43. //为了适应网络的慢速IO而编写的读写函数  
  44. ssize_t readn(int fd, void *vptr, size_t n);    
  45. ssize_t writen(int fd, const void *vptr, size_t n);    
  46. ssize_t readline(int fd, void *vptr, size_t maxlen);    
  47.   
  48. //各类读写包裹函数    
  49. void Write(int fd, void *ptr, size_t nbytes);    
  50. ssize_t Read(int fd, void *ptr, size_t nbytes);    
  51. ssize_t Readn(int fd, void *ptr, size_t nbytes);    
  52. void Writen(int fd, void *ptr, size_t nbytes);    
  53. ssize_t Readline(int fd, void *ptr, size_t maxlen);    
  54. void Fputs(const char *ptr, FILE *stream);    
  55. char *Fgets(char *ptr, int n, FILE *stream);     
  56.   
  57. //各类标准包裹函数    
  58. int Open(const char *pathname, int flags, mode_t mode);  
  59. void Close(int fd);   
  60. Sigfunc *Signal(int signo, Sigfunc *func);    
  61. void *Malloc(size_t size);    
  62. void *Calloc(size_t n, size_t size);  
  63. void Pipe(int *fds);    
  64. pid_t Fork(void);    
  65. pid_t Waitpid(pid_t pid, int *iptr, int options);   
  66. void Dup2(int fd1, int fd2);  
  67.   
  68. //各类网络包裹函数    
  69. int Socket(int family, int type, int protocol);    
  70. void Inet_pton(int family, const char *strptr, void *addrptr);    
  71. void Connect(int fd, const struct sockaddr *sa, socklen_t salen);    
  72. void Listen(int fd, int backlog);    
  73. void Bind(int fd, const struct sockaddr *sa, socklen_t salen);    
  74. int Accept(int fd, struct sockaddr *sa, socklen_t *salenptr);    
  75. const char *Inet_ntop(int family, const void *addrptr, char *strptr, size_t len);    
  76. int Select(int nfds, fd_set *readfds, fd_set *writefds,     
  77.            fd_set *exceptfds, struct timeval *timeout);    
  78. int Poll(struct pollfd *fdarray, unsigned long nfds, int timeout);    
  79. void Shutdown(int fd, int how);    
  80. int Epoll_create(int size);    
  81. void Epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);    
  82. int Epoll_wait(int epfd, struct epoll_event *events,    
  83.                int maxevents, int timeout);    
  84. void Sendto(int fd, const void *ptr, size_t nbytes, int flags,    
  85.             const struct sockaddr *sa, socklen_t salen);    
  86. ssize_t Recvfrom(int fd, void *ptr, size_t nbytes, int flags,   
  87.                 struct sockaddr *sa, socklen_t *salenptr);    
  88. void Setsockopt(int fd, int level, int optname,   
  89.                 const void *optval, socklen_t optlen);  
  90. void *Mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset);  
  91. void Munmap(void *addr, size_t len);  
  92. void Ftruncate(int fd, off_t length);  
  93.   
  94. //各类和线程操作相关的包裹函数    
  95. void Pthread_create(pthread_t *tid, const pthread_attr_t *attr,  
  96.                     void * (*func)(void *), void *arg);  
  97. void Pthread_detach(pthread_t tid);  
  98. void Pthread_join(pthread_t tid, void **status);  
  99. void Pthread_kill(pthread_t tid, int signo);  
  100. void Pthread_mutex_lock(pthread_mutex_t *mptr);  
  101. void Pthread_mutex_unlock(pthread_mutex_t *mptr);  
  102. //此函数相当于UNP书上的set_concurrency函数  
  103. void Pthread_setconcurrency(int level);  
  104. void Pthread_cond_signal(pthread_cond_t *cptr);  
  105. void Pthread_cond_wait(pthread_cond_t *cptr, pthread_mutex_t *mptr);  
  106.   
  107. //各类和信号量相关的包裹函数  
  108. sem_t *Sem_open(const char *name, int oflag,  
  109.                 mode_t mode, unsigned int value);  
  110. void Sem_close(sem_t *sem);  
  111. void Sem_unlink(const char *pathname);  
  112. void Sem_init(sem_t *sem, int pshared, unsigned int value);  
  113. void Sem_destroy(sem_t *sem);  
  114. void Sem_wait(sem_t *sem);  
  115. void Sem_post(sem_t *sem);  
  116. void Sem_getvalue(sem_t *sem, int *valp);  
  117.   
  118. #endif    


文件unp_base.c:它定义了基本的包裹函数

[cpp] view plaincopyprint?
  1. #include "my_unp.h"    
  2.   
  3. //此函数是在程序发生错误时被调用    
  4. //先输出字符串fmt,再根据errno输出错误原因(如果有的话),最后退出程序    
  5. //注:在多线程程序中,错误原因可能不正确    
  6. void error_quit(char *fmt, ...)    
  7. {    
  8.     int res;    
  9.     va_list list;    
  10.     va_start(list, fmt);    
  11.     res = vfprintf(stderr, fmt, list);    
  12.     if( errno != 0 )    
  13.         fprintf(stderr, " : %s", strerror(errno));    
  14.     fprintf(stderr, "\n", list);    
  15.     va_end(list);    
  16.     exit(1);    
  17. }    
  18.   
  19. //字节流套接字上调用read时,输入的字节数可能比请求的数量少,    
  20. //但这不是出错的状态,原因是内核中用于套接字的缓冲区可能已经达到了极限,    
  21. //此时需要调用者再次调用read函数    
  22. ssize_t readn(int fd, void *vptr, size_t n)    
  23. {    
  24.     size_t  nleft;    
  25.     ssize_t nread;    
  26.     char    *ptr;    
  27.   
  28.     ptr = vptr;    
  29.     nleft = n;    
  30.     while (nleft > 0)    
  31.     {    
  32.         if ( (nread = read(fd, ptr, nleft)) < 0)    
  33.         {    
  34.             if (errno == EINTR)    
  35.                 nread = 0;      /* and call read() again */    
  36.             else    
  37.                 return(-1);    
  38.         }     
  39.         else if (nread == 0)    
  40.             break;              /* EOF */    
  41.         nleft -= nread;    
  42.         ptr   += nread;    
  43.     }    
  44.     return (n - nleft);     /* return >= 0 */    
  45. }    
  46.   
  47. //字节流套接字上调用write时,输出的字节数可能比请求的数量少,    
  48. //但这不是出错的状态,原因是内核中用于套接字的缓冲区可能已经达到了极限,    
  49. //此时需要调用者再次调用write函数    
  50. ssize_t writen(int fd, const void *vptr, size_t n)    
  51. {    
  52.     size_t      nleft;    
  53.     ssize_t     nwritten;    
  54.     const char  *ptr;    
  55.   
  56.     ptr = vptr;    
  57.     nleft = n;    
  58.     while (nleft > 0)     
  59.     {    
  60.         if ( (nwritten = write(fd, ptr, nleft)) <= 0)     
  61.         {    
  62.             if (nwritten < 0 && errno == EINTR)    
  63.                 nwritten = 0;       /* and call write() again */    
  64.             else    
  65.                 return(-1);         /* error */    
  66.         }    
  67.         nleft -= nwritten;    
  68.         ptr   += nwritten;    
  69.     }    
  70.     return n;    
  71. }    
  72.   
  73. static int  read_cnt;    
  74. static char *read_ptr;    
  75. static char read_buf[MAXLINE];    
  76.   
  77. //内部函数my_read每次最多读MAXLINE个字节,然后每次返回一个字节    
  78. static ssize_t my_read(int fd, char *ptr)    
  79. {    
  80.     if (read_cnt <= 0)     
  81.     {    
  82. again:    
  83.         if ( (read_cnt = read(fd, read_buf, sizeof(read_buf))) < 0)     
  84.         {    
  85.             if (errno == EINTR)    
  86.                 goto again;    
  87.             return(-1);    
  88.         }     
  89.         else if (read_cnt == 0)    
  90.             return(0);    
  91.         read_ptr = read_buf;    
  92.     }    
  93.   
  94.     read_cnt--;    
  95.     *ptr = *read_ptr++;    
  96.     return 1;    
  97. }    
  98.   
  99. //从描述符中读取文本行    
  100. ssize_t readline(int fd, void *vptr, size_t maxlen)    
  101. {    
  102.     ssize_t n, rc;    
  103.     char    c, *ptr;    
  104.   
  105.     ptr = vptr;    
  106.     for (n = 1; n < maxlen; n++)    
  107.     {    
  108.         if ( (rc = my_read(fd, &c)) == 1)     
  109.         {    
  110.             *ptr++ = c;    
  111.             if (c == '\n')    
  112.                 break;  /* newline is stored, like fgets() */    
  113.         }     
  114.         else if (rc == 0)    
  115.         {    
  116.             *ptr = 0;    
  117.             return(n - 1);  /* EOF, n - 1 bytes were read */    
  118.         }    
  119.         else    
  120.             return(-1);     /* error, errno set by read() */    
  121.     }    
  122.     *ptr = 0;   /* null terminate like fgets() */    
  123.     return n;    
  124. }    
  125.   
  126. ssize_t Readn(int fd, void *ptr, size_t nbytes)    
  127. {    
  128.     ssize_t n = readn(fd, ptr, nbytes);    
  129.     if ( n < 0)    
  130.         error_quit("readn error");    
  131.     return n;    
  132. }    
  133.   
  134. void Writen(int fd, void *ptr, size_t nbytes)    
  135. {    
  136.     if ( writen(fd, ptr, nbytes) != nbytes )    
  137.         error_quit("writen error");    
  138. }    
  139.   
  140. ssize_t Readline(int fd, void *ptr, size_t maxlen)    
  141. {    
  142.     ssize_t n = readline(fd, ptr, maxlen);    
  143.     if ( n < 0)    
  144.         error_quit("readline error");    
  145.     return n;    
  146. }    
  147.   
  148. ssize_t Read(int fd, void *ptr, size_t nbytes)    
  149. {    
  150.     ssize_t n = read(fd, ptr, nbytes);    
  151.     if ( n == -1)    
  152.         error_quit("read error");    
  153.     return n;    
  154. }    
  155.   
  156. void Write(int fd, void *ptr, size_t nbytes)    
  157. {    
  158.     if (write(fd, ptr, nbytes) != nbytes)    
  159.         error_quit("write error");    
  160. }    
  161.   
  162. int Open(const char *pathname, int flags, mode_t mode)  
  163. {  
  164.     int fd = open(pathname, flags, mode);  
  165.     if( -1 == fd )  
  166.         error_quit("open file %s error", pathname);  
  167.     return fd;  
  168. }  
  169.   
  170. void Close(int fd)    
  171. {    
  172.     if (close(fd) == -1)    
  173.         error_quit("close error");    
  174. }    
  175.   
  176. void Fputs(const char *ptr, FILE *stream)    
  177. {    
  178.     if (fputs(ptr, stream) == EOF)    
  179.         error_quit("fputs error");    
  180. }    
  181.   
  182. char *Fgets(char *ptr, int n, FILE *stream)    
  183. {    
  184.     char *rptr = fgets(ptr, n, stream);    
  185.     if ( rptr == NULL && ferror(stream) )    
  186.         error_quit("fgets error");    
  187.     return rptr;    
  188. }    
  189.   
  190. int Socket(int family, int type, int protocol)    
  191. {    
  192.     int n = socket(family, type, protocol);    
  193.     if( n < 0)    
  194.         error_quit("socket error");    
  195.     return n;    
  196. }    
  197.   
  198. void Inet_pton(int family, const char *strptr, void *addrptr)    
  199. {    
  200.     int n = inet_pton(family, strptr, addrptr);    
  201.     if( n < 0)    
  202.         error_quit("inet_pton error for %s", strptr);    
  203. }    
  204.   
  205. void Connect(int fd, const struct sockaddr *sa, socklen_t salen)    
  206. {    
  207.     if (connect(fd, sa, salen) < 0)    
  208.         error_quit("connect error");    
  209. }    
  210.   
  211. void Listen(int fd, int backlog)    
  212. {    
  213.     if (listen(fd, backlog) < 0)    
  214.         error_quit("listen error");    
  215. }    
  216.   
  217. void Bind(int fd, const struct sockaddr *sa, socklen_t salen)    
  218. {    
  219.     if (bind(fd, sa, salen) < 0)    
  220.         error_quit("bind error");    
  221. }    
  222.   
  223. int Accept(int fd, struct sockaddr *sa, socklen_t *salenptr)    
  224. {    
  225.     int n = accept(fd, sa, salenptr);    
  226.     if ( n < 0)    
  227.         error_quit("accept error");    
  228.     return n;    
  229. }    
  230.   
  231. const char *Inet_ntop(int family, const void *addrptr, char *strptr, size_t len)    
  232. {    
  233.     const char  *ptr = inet_ntop(family, addrptr, strptr, len);    
  234.     if ( ptr == NULL)    
  235.         error_quit("inet_ntop error");    
  236.     return ptr;    
  237. }    
  238.   
  239. pid_t Fork(void)    
  240. {    
  241.     pid_t pid = fork();    
  242.     if ( pid == -1)    
  243.         error_quit("fork error");    
  244.     return pid;    
  245. }    
  246.   
  247. Sigfunc *Signal(int signo, Sigfunc *func)    
  248. {    
  249.     Sigfunc *sigfunc = signal(signo, func);    
  250.     if ( sigfunc == SIG_ERR)    
  251.         error_quit("signal error");    
  252.     return sigfunc;    
  253. }    
  254.   
  255. int Select(int nfds, fd_set *readfds, fd_set *writefds,     
  256.            fd_set *exceptfds, struct timeval *timeout)    
  257. {    
  258.     int n = select(nfds, readfds, writefds, exceptfds, timeout);    
  259.     if ( n < 0 )    
  260.         error_quit("select error");    
  261.     return n;       /* can return 0 on timeout */    
  262. }    
  263.   
  264. int Poll(struct pollfd *fdarray, unsigned long nfds, int timeout)    
  265. {    
  266.     int n = poll(fdarray, nfds, timeout);    
  267.     if ( n < 0 )    
  268.         error_quit("poll error");    
  269.     return n;    
  270. }    
  271.   
  272. void Shutdown(int fd, int how)    
  273. {    
  274.     if (shutdown(fd, how) < 0)    
  275.         error_quit("shutdown error");    
  276. }    
  277.   
  278. int Epoll_create(int size)    
  279. {    
  280.     int n = epoll_create(size);    
  281.     if( n < 0 )    
  282.         error_quit("epoll create error");    
  283.     return n;    
  284. }    
  285.   
  286. void Epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)    
  287. {    
  288.     if( epoll_ctl(epfd, op, fd, event) < 0 )    
  289.         error_quit("epoll ctl error");    
  290. }    
  291.   
  292. int Epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout)    
  293. {    
  294.     int n = epoll_wait(epfd, events, maxevents, timeout);    
  295.     if( n < 0 )    
  296.         error_quit("epoll wait error");    
  297.     return n;    
  298. }    
  299.   
  300. void Sendto(int fd, const void *ptr, size_t nbytes, int flags,    
  301.             const struct sockaddr *sa, socklen_t salen)    
  302. {    
  303.     if (sendto(fd, ptr, nbytes, flags, sa, salen) != (ssize_t)nbytes)    
  304.         error_quit("sendto error");    
  305. }    
  306.   
  307. ssize_t Recvfrom(int fd, void *ptr, size_t nbytes, int flags,    
  308. struct sockaddr *sa, socklen_t *salenptr)    
  309. {    
  310.     ssize_t n = recvfrom(fd, ptr, nbytes, flags, sa, salenptr);    
  311.     if ( n < 0 )    
  312.         error_quit("recvfrom error");    
  313.     return n;    
  314. }    
  315.   
  316. ssize_t Recvmsg(int fd, struct msghdr *msg, int flags)    
  317. {    
  318.     ssize_t n = recvmsg(fd, msg, flags);    
  319.     if ( n < 0 )    
  320.         error_quit("recvmsg error");    
  321.     return(n);    
  322. }    
  323.   
  324. void *Malloc(size_t size)    
  325. {    
  326.     void *ptr = malloc(size);    
  327.     if ( ptr == NULL )    
  328.         error_quit("malloc error");    
  329.     return ptr;    
  330. }    
  331.   
  332. void *Calloc(size_t n, size_t size)  
  333. {  
  334.     void *ptr = calloc(n, size);  
  335.     if ( ptr == NULL)  
  336.         error_quit("calloc error");  
  337.     return ptr;  
  338. }  
  339.   
  340. void Pipe(int *fds)    
  341. {    
  342.     if ( pipe(fds) < 0 )    
  343.         error_quit("pipe error");    
  344. }    
  345.   
  346. pid_t Waitpid(pid_t pid, int *iptr, int options)    
  347. {    
  348.     pid_t   retpid = waitpid(pid, iptr, options);    
  349.     if ( retpid == -1)    
  350.         error_quit("waitpid error");    
  351.     return retpid;    
  352. }  
  353.   
  354. void Setsockopt(int fd, int level, int optname,   
  355.                 const void *optval, socklen_t optlen)  
  356. {  
  357.     if (setsockopt(fd, level, optname, optval, optlen) < 0)  
  358.         error_quit("setsockopt error");  
  359. }  
  360.   
  361. void Socketpair(int family, int type, int protocol, int *fd)  
  362. {  
  363.     int n = socketpair(family, type, protocol, fd);  
  364.     if ( n < 0 )  
  365.         error_quit("socketpair error");  
  366. }  
  367.   
  368. void Dup2(int fd1, int fd2)  
  369. {  
  370.     if (dup2(fd1, fd2) == -1)  
  371.         error_quit("dup2 error");  
  372. }  
  373.   
  374. void *Mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset)  
  375. {  
  376.     void *ptr = mmap(addr, len, prot, flags, fd, offset);  
  377.     if ( ptr == MAP_FAILED )  
  378.         error_quit("mmap error");  
  379.     return ptr;  
  380. }  
  381.   
  382. void Munmap(void *addr, size_t len)  
  383. {  
  384.     if (munmap(addr, len) == -1)  
  385.         error_quit("munmap error");  
  386. }  
  387.   
  388. void Ftruncate(int fd, off_t length)  
  389. {  
  390.     if (ftruncate(fd, length) == -1)  
  391.         error_quit("ftruncate error");  
  392. }  

文件unp_pthread.c:它定义了基本的线程类包裹函数

[cpp] view plaincopyprint?
  1. #include "my_unp.h"  
  2.   
  3. void Pthread_create(pthread_t *tid, const pthread_attr_t *attr,  
  4.                     void * (*func)(void *), void *arg)  
  5. {  
  6.     int n = pthread_create(tid, attr, func, arg);  
  7.     if ( n == 0)  
  8.         return;  
  9.     errno = n;  
  10.     error_quit("pthread_create error");  
  11. }  
  12.   
  13. void Pthread_detach(pthread_t tid)  
  14. {  
  15.     int n = pthread_detach(tid);  
  16.     if ( n == 0)  
  17.         return;  
  18.     errno = n;  
  19.     error_quit("pthread_detach error");  
  20. }  
  21.   
  22. void Pthread_join(pthread_t tid, void **status)  
  23. {  
  24.     int n = pthread_join(tid, status);  
  25.     if ( n == 0 )  
  26.         return;  
  27.     errno = n;  
  28.     error_quit("pthread_join error");  
  29. }  
  30.   
  31. void Pthread_kill(pthread_t tid, int signo)  
  32. {  
  33.     int n = pthread_kill(tid, signo);  
  34.     if ( n == 0 )  
  35.         return;  
  36.     errno = n;  
  37.     error_quit("pthread_kill error");  
  38. }  
  39.   
  40. void Pthread_mutex_lock(pthread_mutex_t *mptr)  
  41. {  
  42.     int n = pthread_mutex_lock(mptr);  
  43.     if ( n == 0 )  
  44.         return;  
  45.     errno = n;  
  46.     error_quit("pthread_mutex_lock error");  
  47. }  
  48.   
  49. void Pthread_mutex_unlock(pthread_mutex_t *mptr)  
  50. {  
  51.     int n = pthread_mutex_unlock(mptr);  
  52.     if ( n == 0 )  
  53.         return;  
  54.     errno = n;  
  55.     error_quit("pthread_mutex_unlock error");  
  56. }  
  57.   
  58. void Pthread_setconcurrency(int level)  
  59. {  
  60.     int n = pthread_setconcurrency(level);  
  61.     if ( n == 0 )  
  62.         return;  
  63.     errno = n;  
  64.     error_quit("pthread_mutex_unlock error");  
  65. }  
  66.   
  67. void Pthread_cond_signal(pthread_cond_t *cptr)  
  68. {  
  69.     int n = pthread_cond_signal(cptr);  
  70.     if ( n == 0 )  
  71.         return;  
  72.     errno = n;  
  73.     error_quit("pthread_cond_signal error");  
  74. }  
  75.   
  76. void Pthread_cond_wait(pthread_cond_t *cptr, pthread_mutex_t *mptr)  
  77. {  
  78.     int n = pthread_cond_wait(cptr, mptr);  
  79.     if ( n == 0 )  
  80.         return;  
  81.     errno = n;  
  82.     error_quit("pthread_cond_wait error");  
  83. }  
  84.   
  85. sem_t *Sem_open(const char *name, int oflag,  
  86.                 mode_t mode, unsigned int value)  
  87. {  
  88.     sem_t *sem = sem_open(name, oflag, mode, value);  
  89.     if( NULL == sem )  
  90.         error_quit("sem_open error for %s", name);  
  91.     return sem;  
  92. }  
  93.   
  94. void Sem_close(sem_t *sem)  
  95. {  
  96.     if (sem_close(sem) == -1)  
  97.         error_quit("sem_close error");  
  98. }  
  99.   
  100. void Sem_unlink(const char *pathname)  
  101. {  
  102.     if (sem_unlink(pathname) == -1)  
  103.         error_quit("sem_unlink error");  
  104. }  
  105.   
  106. void Sem_init(sem_t *sem, int pshared, unsigned int value)  
  107. {  
  108.     if (sem_init(sem, pshared, value) == -1)  
  109.         error_quit("sem_init error");  
  110. }  
  111.   
  112. void Sem_destroy(sem_t *sem)  
  113. {  
  114.     if (sem_destroy(sem) == -1)  
  115.         error_quit("sem_destroy error");  
  116. }  
  117.   
  118. void Sem_wait(sem_t *sem)  
  119. {  
  120.     if (sem_wait(sem) == -1)  
  121.         error_quit("sem_wait error");  
  122. }  
  123.   
  124. void Sem_post(sem_t *sem)  
  125. {  
  126.     if (sem_post(sem) == -1)  
  127.         error_quit("sem_post error");  
  128. }  
  129.   
  130. void Sem_getvalue(sem_t *sem, int *valp)  
  131. {  
  132.     if (sem_getvalue(sem, valp) == -1)  
  133.         error_quit("sem_getvalue error");  
  134. }  
0 0