亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊(cè) 查看新帖 |

Chinaunix

  平臺(tái) 論壇 博客 文庫(kù)
最近訪問板塊 發(fā)新帖
查看: 1440 | 回復(fù): 0
打印 上一主題 下一主題

《UNIX 網(wǎng)絡(luò)編程:第3版》封裝函數(shù)的分析說明 [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報(bào)告]
發(fā)表于 2009-11-05 17:14 |只看該作者 |倒序?yàn)g覽

#include    "unp.h"
#include    stdarg.h>        /* ANSI C header file 可變參數(shù)列表*/
#include    syslog.h>        /* for syslog() */
int        daemon_proc;        /* set nonzero by daemon_init() */
static void    err_doit(int, int, const char *, va_list);
//跟系統(tǒng)調(diào)用無關(guān)的錯(cuò)誤均不打印errno
/* Nonfatal error related to system call
* Print message and return 跟系統(tǒng)調(diào)用相關(guān)的非致命錯(cuò)誤,僅打印信息不終止進(jìn)程*/
err_ret(const char *fmt, ...)
{
    va_list        ap;
    va_start(ap, fmt);
    err_doit(1, LOG_INFO, fmt, ap);//打印errno
    va_end(ap);
    return;
}
/* Fatal error related to system call
* Print message and terminate 跟系統(tǒng)調(diào)用相關(guān)的致命錯(cuò)誤,打印信息并且終止進(jìn)程*/
void
err_sys(const char *fmt, ...)
{
    va_list        ap;
    va_start(ap, fmt);
    err_doit(1, LOG_ERR, fmt, ap);//打印errno
    va_end(ap);
    exit(1);
}
/* Fatal error related to system call
* Print message, dump core, and terminate 跟系統(tǒng)調(diào)用相關(guān)的致命錯(cuò)誤,打印信息、生成core文件并且終止進(jìn)程*/
void
err_dump(const char *fmt, ...)
{
    va_list        ap;
    va_start(ap, fmt);
    err_doit(1, LOG_ERR, fmt, ap);//打印errno
    va_end(ap);
    abort();        /* dump core and terminate */
    exit(1);        /* shouldn't get here 一般不會(huì)執(zhí)行到此*/
}
//跟系統(tǒng)調(diào)用無關(guān)的錯(cuò)誤均不打印errno
/* Nonfatal error unrelated to system call
* Print message and return 跟系統(tǒng)調(diào)用無關(guān)的非致命錯(cuò)誤,僅打印信息不終止進(jìn)程*/
void
err_msg(const char *fmt, ...)
{
    va_list        ap;
    va_start(ap, fmt);
    err_doit(0, LOG_INFO, fmt, ap);//不打印errno
    va_end(ap);
    return;
}
/* Fatal error unrelated to system call
* Print message and terminate 跟系統(tǒng)調(diào)用無關(guān)的致命錯(cuò)誤,打印信息并且終止進(jìn)程*/
void
err_quit(const char *fmt, ...)
{
    va_list        ap;
    va_start(ap, fmt);
    err_doit(0, LOG_ERR, fmt, ap);//不打印errno
    va_end(ap);
    exit(1);
}
/* Print message and return to caller
* Caller specifies "errnoflag" and "level" */
static void
err_doit(int errnoflag, int level, const char *fmt, va_list ap)            //第一個(gè)參數(shù)為1則打印errno的值,為0則不打印;第二個(gè)參數(shù)傳給
{                                                                        //syslog的level參數(shù),fmt是類似printf的格式控制字符串,
    int        errno_save, n;
    char    buf[MAXLINE + 1];
    errno_save = errno;        /* value caller might want printed */
#ifdef    HAVE_VSNPRINTF
    vsnprintf(buf, MAXLINE, fmt, ap);    /* safe */
#else
    vsprintf(buf, fmt, ap);                    /* not safe */
#endif
    n = strlen(buf);
    if (errnoflag)
        snprintf(buf + n, MAXLINE - n, ": %s", strerror(errno_save));
    strcat(buf, "\n");
    if (daemon_proc) {                //如果是守護(hù)進(jìn)程的話,將出錯(cuò)消息寫到記錄文件中。
        syslog(level, buf);
    } else {
        fflush(stdout);                /* in case stdout and stderr are the same */
        fputs(buf, stderr);
        fflush(stderr);
    }
    return;
}
這些函數(shù)封裝不錯(cuò),我們自己在編程中也可以借鑒利用。這些出錯(cuò)封裝函數(shù)用在了本書幾乎所有系統(tǒng)調(diào)用的封裝中,對(duì)系統(tǒng)調(diào)用進(jìn)行封裝以進(jìn)行出錯(cuò)處理是一種不錯(cuò)的方法。封裝后的函數(shù)都放到了自己的庫(kù)libunp.a中,并在頭文件unp.h中作了聲明,我們的程序在使用這些封裝函數(shù)時(shí)只需包括頭文件unp.h即可,下面是幾個(gè)例子。
#include    "unp.h"
int
Accept(int fd, struct sockaddr *sa, socklen_t *salenptr)
{
    int        n;
again:
    if ( (n = accept(fd, sa, salenptr))  0) {
#ifdef    EPROTO
        if (errno == EPROTO || errno == ECONNABORTED)
#else
        if (errno == ECONNABORTED)
#endif
            goto again;
        else
            err_sys("accept error");
    }
    return(n);
}
void
Bind(int fd, const struct sockaddr *sa, socklen_t salen)
{
    if (bind(fd, sa, salen)  0)
        err_sys("bind error");
}
void
Connect(int fd, const struct sockaddr *sa, socklen_t salen)
{
    if (connect(fd, sa, salen)  0)
        err_sys("connect error");
}
void
Listen(int fd, int backlog)
{
    char    *ptr;
        /*4can override 2nd argument with environment variable */
    if ( (ptr = getenv("LISTENQ")) != NULL)
        backlog = atoi(ptr);
    if (listen(fd, backlog)  0)
        err_sys("listen error");
}
int
Socket(int family, int type, int protocol)
{
    int        n;
    if ( (n = socket(family, type, protocol))  0)
        err_sys("socket error");
    return(n);
}
/* end Socket */
void
Socketpair(int family, int type, int protocol, int *fd)
{
    int        n;
    if ( (n = socketpair(family, type, protocol, fd))  0)
        err_sys("socketpair error");
}
ssize_t
Recv(int fd, void *ptr, size_t nbytes, int flags)
{
    ssize_t        n;
    if ( (n = recv(fd, ptr, nbytes, flags))  0)
        err_sys("recv error");
    return(n);
}
ssize_t
Recvfrom(int fd, void *ptr, size_t nbytes, int flags,
         struct sockaddr *sa, socklen_t *salenptr)
{
    ssize_t        n;
    if ( (n = recvfrom(fd, ptr, nbytes, flags, sa, salenptr))  0)
        err_sys("recvfrom error");
    return(n);
}
ssize_t
Recvmsg(int fd, struct msghdr *msg, int flags)
{
    ssize_t        n;
    if ( (n = recvmsg(fd, msg, flags))  0)
        err_sys("recvmsg error");
    return(n);
}
int
Select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
       struct timeval *timeout)
{
    int        n;
    if ( (n = select(nfds, readfds, writefds, exceptfds, timeout))  0)
        err_sys("select error");
    return(n);        /* can return 0 on timeout */
}
void
Send(int fd, const void *ptr, size_t nbytes, int flags)
{
    if (send(fd, ptr, nbytes, flags) != (ssize_t)nbytes)
        err_sys("send error");
}
void
Sendto(int fd, const void *ptr, size_t nbytes, int flags,
       const struct sockaddr *sa, socklen_t salen)
{
    if (sendto(fd, ptr, nbytes, flags, sa, salen) != (ssize_t)nbytes)
        err_sys("sendto error");
}
void
Sendmsg(int fd, const struct msghdr *msg, int flags)
{
    unsigned int    i;
    ssize_t            nbytes;
    nbytes = 0;    /* must first figure out what return value should be */
    for (i = 0; i  msg->msg_iovlen; i++)
        nbytes += msg->msg_iov.iov_len;
    if (sendmsg(fd, msg, flags) != nbytes)
        err_sys("sendmsg error");
}
void
Setsockopt(int fd, int level, int optname, const void *optval, socklen_t optlen)
{
    if (setsockopt(fd, level, optname, optval, optlen)  0)
        err_sys("setsockopt error");
}
void
Shutdown(int fd, int how)
{
    if (shutdown(fd, how)  0)
        err_sys("shutdown error");
}
以上函數(shù)的原文進(jìn)均在unpv13e/lib目錄中。此目錄中還有大量其他的函數(shù)。我們?cè)谧约壕幊虝r(shí),也可以將一些標(biāo)準(zhǔn)API封裝,然后將它們連同一些我們自己的其他的常用函數(shù)做成一個(gè)自己的庫(kù)。
本書作者在unp.h頭文件中有如下語(yǔ)句:
#include    "../config.h"    /* configuration options for current OS */
                            /* "../config.h" is generated by configure */

config.h頭文件由configure腳本生成,從而很好的解決了代碼的可移植性,使得在任何操作系統(tǒng)上都能正確的運(yùn)行。

本文來自ChinaUnix博客,如果查看原文請(qǐng)點(diǎn):http://blog.chinaunix.net/u3/103462/showart_2087176.html
您需要登錄后才可以回帖 登錄 | 注冊(cè)

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號(hào)-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號(hào):11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報(bào)專區(qū)
中國(guó)互聯(lián)網(wǎng)協(xié)會(huì)會(huì)員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請(qǐng)注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP