zoukankan      html  css  js  c++  java
  • 2018-2019-1 20165226 《信息安全系统设计基础》第6周学习总结

    2018-2019-1 20165226 《信息安全系统设计基础》第6周学习总结

    目录


    一、教材学习内容总结

    **** ## 1、 Unix I/O 这一节涉及到操作系统的基本抽象之一——文件。也就是说,所有的I/O设备都被模型化为文件,而所有的输入输出都被当做对相应文件的读/写。 - I/O设备:网络、磁盘和终端 - 描述符:打开文件时,内核返回一个小的非负整数。 - Unix外壳创建的每个进程开始时都有三个打开的文件:标准输入(描述符为0)、标准输出(描述符为1)、标准错误(描述符为2)。 - 改变当前的文件位置:文件位置为k,初始为0。 - seek操作:显式地设置文件的当前位置为k。 - 关闭文件:内核释放文件打开时创建的数据结构,并将这个描述符恢复到可用的描述符池中。无论一个进程因为何种原因终止时,内核都会关闭所有打开的文件并释放它们的存储器资源。

    2、打开和关闭文件

    (1)open函数:打开一个已存在的文件或者创建一个新文件

    • 定义:
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    
    int open(char *filename,int flags,mode_t mode);
    
    • 参数解析:
      • 返回值:类型为int型,返回的是描述符数字,总是在进程中当前没有打开的最小描述符。如果出错,返回值为-1.
      • filename:文件名
      • flags:指明进程打算如何访问这个文件,可以取的值见下:
      O_RDONLY:只读
      O_WRONLY:只写
      O_RDWR:可读可写
    
      O_CREAT:文件不存在,就创建新文件
      O_TRUNC:如果文件存在,就截断它
      O_APPEND:写操作前设置文件位置到结尾处
    

    这些值可以用或连接起来。
    - mode:指定了新文件的访问权限位,符号名称如下:

    (2)close函数

    • 函数定义
    #include <unistd.h>
    int close(int fd);
    
    • 参数解析
      • 返回值:成功返回0,出错返回-1

    关闭一个已经关闭的描述符会出错

    - fd:即文件的描述符。
    

    3、读和写文件

    • 应用程序是通过分别调用read和write函数来执行输入和输出的。
    #include <unistd.h>
    ssize_t read(int fd,void *buf,size_t n);
    ssize_t write(int fd,const void *buf,size_t n);
    

    read函数:从描述符为fd的当前文件位置拷贝最多n个字节到存储器位置buf。返回值:-1表示一个错误;0表示EOF;否则,返回值表示的是实际传送的字节数量。
    从存储器位置buf拷贝至多n个字节到描述符fd的当前文件位置。返回值:若成功则为写的字节数,若出错则为-1。

    • lseek函数:应用程序能够显式地修改当前文件的位置。
    • 不足值:read和write传送的字节比应用程序要求的少。
      • 读时遇到EOF
      • 从终端读文本行
      • 读和写网络套接字

    4、用RIO包健壮的读写

    RIO包的实质:I/O包
    RIO包提供的两种函数:

    • 无缓冲的输入输出函数
    • 带缓冲的输入函数(线程安全)

    RIO的无缓冲的输入输出函数

    • 应用程序通过调用rioreadn和riowritten函数可以在存储器和文件之间直接传送数据。
    #include "csapp.h"
    ssize_t rio_readn(int fd,void *usrbuf,size_t n);
    ssize_t rio_writen(int fd,void *usrbuf,size_t n);
    
    • rio_ readn函数在遇到EOF时,只能返回一个不足值;
    • rio_ writen函数绝不会返回不足值。

    RIO的带缓冲的输入函数

    • 一个文本行就是一个由换行符结尾的ASCII码字符序列。在Unix系统中,换行符(‘ ')与ASCII码换行符(LF)相同,数字值为0x0a。
    • 计算文本文件中文本行的数量,更好地方法是:
      • 调用一个包装函数(rio、readlineb),它从一个内部读缓冲区拷贝一个文本行,当缓冲区变空时,会自动地调用read重新填满缓冲区。
    #include "csapp.h"
    //每打开一个描述符都会调用一次该函数,它将描述符fd和地址rp处的类型为rio_t的缓冲区联系起来。
    void rio_readinitb(rio_t *rp,int fd);
    //从文件rp中读取一个文本行(包括结尾的换行符),将它拷贝到存储器位置usrbuf,并用空字符来结束这个文本行。
    ssize_t rio_readlineb(rio_t *rp,void *usrbuf,size_t maxlen);
    //从文件rp中最多读n个字节到存储器位置usrbuf。对同一描述符,rioreadnb和rioreadlineb的调用可以交叉进行。
    ssize_t rio_readnb(rio_t *rp,void *usrbuf,size_t n);
    

    读取文件元数据

    • 检索文件信息(元数据):应用程序能够通过调用stat和fstat函数
    #include <unistd.h>
    #include <sys/stat.h>
    int stat(const char *filename,struct stat *buf);
    //stat函数以一个文件名作为输入,填写一个stat数据结构中的各个成员。
    int fstat(int fd,struct stat *buf);
    //fstat函数以文件描述符而不是文件名作为输入。
    
    • st_size成员包含了文件的字节数大小
    • st_mode成员编码了文件访问许可位和文件类型
    • Unix提供的宏指令根据st_mode成员来确定文件的类型
    宏指令 描述
    S_ISREG() 这是一个普通文件吗?
    S_ISDIR() 这是一个目录文件吗?
    S_ISSOCK() 这是一个网络套接字吗?

    返回目录

    二、练习

    **** ###练习题10.1
    #include "csapp.h"
    int main(){
    
            int fd1,fd2;
            fd1=Open("foo.txt",O_RDONLY,0);
            Close(fd1);
            fd2=Open("baz.txt",O_RDONLY,0);
            print("fd2=%d
    ",fd2);
            exit(0);
    
    }
    
    • 编译时发生错误:

    • 说明是Linux系统没有自带csapp/h头文件,需要自己编写。所以,只要把这个头文件加入到系统的include目录中就好了。

      • csapp.h
    /* $begin csapp.h */
    #ifndef __CSAPP_H__
    #define __CSAPP_H__
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    #include <ctype.h>
    #include <setjmp.h>
    #include <signal.h>
    #include <sys/time.h>
    #include <sys/types.h>
    #include <sys/wait.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <sys/mman.h>
    #include <errno.h>
    #include <math.h>
    #include <pthread.h>
    #include <semaphore.h>
    #include <sys/socket.h>
    #include <netdb.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    /* Default file permissions are DEF_MODE & ~DEF_UMASK */
    /* $begin createmasks */
    #define DEF_MODE   S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH
    #define DEF_UMASK  S_IWGRP|S_IWOTH
    /* $end createmasks */
    /* Simplifies calls to bind(), connect(), and accept() */
    /* $begin sockaddrdef */
    typedef struct sockaddr SA;
    /* $end sockaddrdef */
    /* Persistent state for the robust I/O (Rio) package */
    /* $begin rio_t */
    #define RIO_BUFSIZE 8192
    typedef struct {
        int rio_fd;                /* descriptor for this internal buf */
        int rio_cnt;               /* unread bytes in internal buf */
        char *rio_bufptr;          /* next unread byte in internal buf */
        char rio_buf[RIO_BUFSIZE]; /* internal buffer */
    } rio_t;
    /* $end rio_t */
    /* External variables */
    extern int h_errno;    /* defined by BIND for DNS errors */ 
    extern char **environ; /* defined by libc */
    /* Misc constants */
    #define MAXLINE  8192  /* max text line length */
    #define MAXBUF   8192  /* max I/O buffer size */
    #define LISTENQ  1024  /* second argument to listen() */
    /* Our own error-handling functions */
    void unix_error(char *msg);
    void posix_error(int code, char *msg);
    void dns_error(char *msg);
    void app_error(char *msg);
    /* Process control wrappers */
    pid_t Fork(void);
    void Execve(const char *filename, char *const argv[], char *const envp[]);
    pid_t Wait(int *status);
    pid_t Waitpid(pid_t pid, int *iptr, int options);
    void Kill(pid_t pid, int signum);
    unsigned int Sleep(unsigned int secs);
    void Pause(void);
    unsigned int Alarm(unsigned int seconds);
    void Setpgid(pid_t pid, pid_t pgid);
    pid_t Getpgrp();
    
    /* Signal wrappers */
    typedef void handler_t(int);
    handler_t *Signal(int signum, handler_t *handler);
    void Sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
    void Sigemptyset(sigset_t *set);
    void Sigfillset(sigset_t *set);
    void Sigaddset(sigset_t *set, int signum);
    void Sigdelset(sigset_t *set, int signum);
    int Sigismember(const sigset_t *set, int signum);
    /* Unix I/O wrappers */
    int Open(const char *pathname, int flags, mode_t mode);
    ssize_t Read(int fd, void *buf, size_t count);
    ssize_t Write(int fd, const void *buf, size_t count);
    off_t Lseek(int fildes, off_t offset, int whence);
    void Close(int fd);
    int Select(int  n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, 
           struct timeval *timeout);
    int Dup2(int fd1, int fd2);
    void Stat(const char *filename, struct stat *buf);
    void Fstat(int fd, struct stat *buf) ;
    /* Memory mapping wrappers */
    void *Mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset);
    void Munmap(void *start, size_t length);
    /* Standard I/O wrappers */
    void Fclose(FILE *fp);
    FILE *Fdopen(int fd, const char *type);
    char *Fgets(char *ptr, int n, FILE *stream);
    FILE *Fopen(const char *filename, const char *mode);
    void Fputs(const char *ptr, FILE *stream);
    size_t Fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
    void Fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
    /* Dynamic storage allocation wrappers */
    void *Malloc(size_t size);
    void *Realloc(void *ptr, size_t size);
    void *Calloc(size_t nmemb, size_t size);
    void Free(void *ptr);
    /* Sockets interface wrappers */
    int Socket(int domain, int type, int protocol);
    void Setsockopt(int s, int level, int optname, const void *optval, int optlen);
    void Bind(int sockfd, struct sockaddr *my_addr, int addrlen);
    void Listen(int s, int backlog);
    int Accept(int s, struct sockaddr *addr, socklen_t *addrlen);
    void Connect(int sockfd, struct sockaddr *serv_addr, int addrlen);
    /* DNS wrappers */
    struct hostent *Gethostbyname(const char *name);
    struct hostent *Gethostbyaddr(const char *addr, int len, int type);
    /* Pthreads thread control wrappers */
    void Pthread_create(pthread_t *tidp, pthread_attr_t *attrp, 
                void * (*routine)(void *), void *argp);
    void Pthread_join(pthread_t tid, void **thread_return);
    void Pthread_cancel(pthread_t tid);
    void Pthread_detach(pthread_t tid);
    void Pthread_exit(void *retval);
    pthread_t Pthread_self(void);
    void Pthread_once(pthread_once_t *once_control, void (*init_function)());
    /* POSIX semaphore wrappers */
    void Sem_init(sem_t *sem, int pshared, unsigned int value);
    void P(sem_t *sem);
    void V(sem_t *sem);
    
    /* Rio (Robust I/O) package */
    ssize_t rio_readn(int fd, void *usrbuf, size_t n);
    ssize_t rio_writen(int fd, void *usrbuf, size_t n);
    void rio_readinitb(rio_t *rp, int fd); 
    ssize_t rio_readnb(rio_t *rp, void *usrbuf, size_t n);
    ssize_t rio_readlineb(rio_t *rp, void *usrbuf, size_t maxlen);
    /* Wrappers for Rio package */
    ssize_t Rio_readn(int fd, void *usrbuf, size_t n);
    void Rio_writen(int fd, void *usrbuf, size_t n);
    void Rio_readinitb(rio_t *rp, int fd); 
    ssize_t Rio_readnb(rio_t *rp, void *usrbuf, size_t n);
    ssize_t Rio_readlineb(rio_t *rp, void *usrbuf, size_t maxlen);
    /* Client/server helper functions */
    int open_clientfd(char *hostname, int portno);
    int open_listenfd(int portno);
    /* Wrappers for client/server helper functions */
    int Open_clientfd(char *hostname, int port);
    int Open_listenfd(int port); 
    #include <csapp.c>
    #endif /* __CSAPP_H__ */
    /* $end csapp.h */
    
    • csappp.c
    /* $begin csapp.c */
    #include "csapp.h"
    /************************** 
     * Error-handling functions
     **************************/
    /* $begin errorfuns */
    /* $begin unixerror */
    void unix_error(char *msg) /* unix-style error */
    {
        fprintf(stderr, "%s: %s
    ", msg, strerror(errno));
        exit(0);
    }
    /* $end unixerror */
    void posix_error(int code, char *msg) /* posix-style error */
    {
        fprintf(stderr, "%s: %s
    ", msg, strerror(code));
        exit(0);
    }
    void dns_error(char *msg) /* dns-style error */
    {
        fprintf(stderr, "%s: DNS error %d
    ", msg, h_errno);
        exit(0);
    }
    void app_error(char *msg) /* application error */
    {
        fprintf(stderr, "%s
    ", msg);
        exit(0);
    }
    /* $end errorfuns */
    /*********************************************
     * Wrappers for Unix process control functions
     ********************************************/
    /* $begin forkwrapper */
    pid_t Fork(void) 
    {
        pid_t pid;
    
        if ((pid = fork()) < 0)
        unix_error("Fork error");
        return pid;
    }
    /* $end forkwrapper */
    void Execve(const char *filename, char *const argv[], char *const envp[]) 
    {
        if (execve(filename, argv, envp) < 0)
        unix_error("Execve error");
    }
    /* $begin wait */
    pid_t Wait(int *status) 
    {
        pid_t pid;
        if ((pid  = wait(status)) < 0)
        unix_error("Wait error");
        return pid;
    }
    /* $end wait */
    
    pid_t Waitpid(pid_t pid, int *iptr, int options) 
    {
        pid_t retpid;
        if ((retpid  = waitpid(pid, iptr, options)) < 0) 
        unix_error("Waitpid error");
        return(retpid);
    }
    /* $begin kill */
    void Kill(pid_t pid, int signum) 
    {
        int rc;
        if ((rc = kill(pid, signum)) < 0)
        unix_error("Kill error");
    }
    /* $end kill */
    void Pause() 
    {
        (void)pause();
        return;
    }
    unsigned int Sleep(unsigned int secs) 
    {
        unsigned int rc;
        if ((rc = sleep(secs)) < 0)
        unix_error("Sleep error");
        return rc;
    }
    unsigned int Alarm(unsigned int seconds) {
        return alarm(seconds);
    }
    void Setpgid(pid_t pid, pid_t pgid) {
        int rc;
        if ((rc = setpgid(pid, pgid)) < 0)
        unix_error("Setpgid error");
        return;
    }
    pid_t Getpgrp(void) {
        return getpgrp();
    }
    /************************************
     * Wrappers for Unix signal functions 
     ***********************************/
    /* $begin sigaction */
    handler_t *Signal(int signum, handler_t *handler) 
    {
        struct sigaction action, old_action;
    
        action.sa_handler = handler;  
        sigemptyset(&action.sa_mask); /* block sigs of type being handled */
        action.sa_flags = SA_RESTART; /* restart syscalls if possible */
        if (sigaction(signum, &action, &old_action) < 0)
        unix_error("Signal error");
        return (old_action.sa_handler);
    }
    /* $end sigaction */
    void Sigprocmask(int how, const sigset_t *set, sigset_t *oldset)
    {
        if (sigprocmask(how, set, oldset) < 0)
        unix_error("Sigprocmask error");
        return;
    }
    void Sigemptyset(sigset_t *set)
    {
        if (sigemptyset(set) < 0)
        unix_error("Sigemptyset error");
        return;
    }
    void Sigfillset(sigset_t *set)
    { 
        if (sigfillset(set) < 0)
        unix_error("Sigfillset error");
        return;
    }
    void Sigaddset(sigset_t *set, int signum)
    {
        if (sigaddset(set, signum) < 0)
        unix_error("Sigaddset error");
        return;
    }
    void Sigdelset(sigset_t *set, int signum)
    {
        if (sigdelset(set, signum) < 0)
        unix_error("Sigdelset error");
        return;
    }
    int Sigismember(const sigset_t *set, int signum)
    {
        int rc;
        if ((rc = sigismember(set, signum)) < 0)
        unix_error("Sigismember error");
        return rc;
    }
    /********************************
     * Wrappers for Unix I/O routines
     ********************************/
    int Open(const char *pathname, int flags, mode_t mode) 
    {
        int rc;
        if ((rc = open(pathname, flags, mode))  < 0)
        unix_error("Open error");
        return rc;
    }
    ssize_t Read(int fd, void *buf, size_t count) 
    {
        ssize_t rc;
        if ((rc = read(fd, buf, count)) < 0) 
        unix_error("Read error");
        return rc;
    }
    ssize_t Write(int fd, const void *buf, size_t count) 
    {
        ssize_t rc;
        if ((rc = write(fd, buf, count)) < 0)
        unix_error("Write error");
        return rc;
    }
    off_t Lseek(int fildes, off_t offset, int whence) 
    {
        off_t rc;
        if ((rc = lseek(fildes, offset, whence)) < 0)
        unix_error("Lseek error");
        return rc;
    }
    void Close(int fd) 
    {
        int rc;
        if ((rc = close(fd)) < 0)
        unix_error("Close error");
    }
    int Select(int  n, fd_set *readfds, fd_set *writefds,
           fd_set *exceptfds, struct timeval *timeout) 
    {
        int rc;
        if ((rc = select(n, readfds, writefds, exceptfds, timeout)) < 0)
        unix_error("Select error");
        return rc;
    }
    int Dup2(int fd1, int fd2) 
    {
        int rc;
        if ((rc = dup2(fd1, fd2)) < 0)
        unix_error("Dup2 error");
        return rc;
    }
    void Stat(const char *filename, struct stat *buf) 
    {
        if (stat(filename, buf) < 0)
        unix_error("Stat error");
    }
    void Fstat(int fd, struct stat *buf) 
    {
        if (fstat(fd, buf) < 0)
        unix_error("Fstat error");
    }
    /***************************************
     * Wrappers for memory mapping functions
     ***************************************/
    void *Mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset) 
    {
        void *ptr;
        if ((ptr = mmap(addr, len, prot, flags, fd, offset)) == ((void *) -1))
        unix_error("mmap error");
        return(ptr);
    }
    void Munmap(void *start, size_t length) 
    {
        if (munmap(start, length) < 0)
        unix_error("munmap error");
    }
    /***************************************************
     * Wrappers for dynamic storage allocation functions
     ***************************************************/
    void *Malloc(size_t size) 
    {
        void *p;
        if ((p  = malloc(size)) == NULL)
        unix_error("Malloc error");
        return p;
    }
    void *Realloc(void *ptr, size_t size) 
    {
        void *p;
        if ((p  = realloc(ptr, size)) == NULL)
        unix_error("Realloc error");
        return p;
    }
    void *Calloc(size_t nmemb, size_t size) 
    {
        void *p;
        if ((p = calloc(nmemb, size)) == NULL)
        unix_error("Calloc error");
        return p;
    }
    void Free(void *ptr) 
    {
        free(ptr);
    }
    /******************************************
     * Wrappers for the Standard I/O functions.
     ******************************************/
    void Fclose(FILE *fp) 
    {
        if (fclose(fp) != 0)
        unix_error("Fclose error");
    }
    FILE *Fdopen(int fd, const char *type) 
    {
        FILE *fp;
        if ((fp = fdopen(fd, type)) == NULL)
        unix_error("Fdopen error");
        return fp;
    }
    char *Fgets(char *ptr, int n, FILE *stream) 
    {
        char *rptr;
        if (((rptr = fgets(ptr, n, stream)) == NULL) && ferror(stream))
        app_error("Fgets error");
        return rptr;
    }
    FILE *Fopen(const char *filename, const char *mode) 
    {
        FILE *fp;
        if ((fp = fopen(filename, mode)) == NULL)
        unix_error("Fopen error");
        return fp;
    }
    void Fputs(const char *ptr, FILE *stream) 
    {
        if (fputs(ptr, stream) == EOF)
        unix_error("Fputs error");
    }
    size_t Fread(void *ptr, size_t size, size_t nmemb, FILE *stream) 
    {
        size_t n;
        if (((n = fread(ptr, size, nmemb, stream)) < nmemb) && ferror(stream)) 
        unix_error("Fread error");
        return n;
    }
    void Fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) 
    {
        if (fwrite(ptr, size, nmemb, stream) < nmemb)
        unix_error("Fwrite error");
    }
    /**************************** 
     * Sockets interface wrappers
     ****************************/
    int Socket(int domain, int type, int protocol) 
    {
        int rc;
        if ((rc = socket(domain, type, protocol)) < 0)
        unix_error("Socket error");
        return rc;
    }
    void Setsockopt(int s, int level, int optname, const void *optval, int optlen) 
    {
        int rc;
        if ((rc = setsockopt(s, level, optname, optval, optlen)) < 0)
        unix_error("Setsockopt error");
    }
    void Bind(int sockfd, struct sockaddr *my_addr, int addrlen) 
    {
        int rc;
        if ((rc = bind(sockfd, my_addr, addrlen)) < 0)
        unix_error("Bind error");
    }
    void Listen(int s, int backlog) 
    {
        int rc;
        if ((rc = listen(s,  backlog)) < 0)
        unix_error("Listen error");
    }
    
    int Accept(int s, struct sockaddr *addr, socklen_t *addrlen) 
    {
        int rc;
        if ((rc = accept(s, addr, addrlen)) < 0)
        unix_error("Accept error");
        return rc;
    }
    void Connect(int sockfd, struct sockaddr *serv_addr, int addrlen) 
    {
        int rc;
        if ((rc = connect(sockfd, serv_addr, addrlen)) < 0)
        unix_error("Connect error");
    }
    /************************
     * DNS interface wrappers 
     ***********************/
    /* $begin gethostbyname */
    struct hostent *Gethostbyname(const char *name) 
    {
        struct hostent *p;
        if ((p = gethostbyname(name)) == NULL)
        dns_error("Gethostbyname error");
        return p;
    }
    /* $end gethostbyname */
    struct hostent *Gethostbyaddr(const char *addr, int len, int type) 
    {
        struct hostent *p;
        if ((p = gethostbyaddr(addr, len, type)) == NULL)
        dns_error("Gethostbyaddr error");
        return p;
    }
    /************************************************
     * Wrappers for Pthreads thread control functions
     ************************************************/
    void Pthread_create(pthread_t *tidp, pthread_attr_t *attrp, 
                void * (*routine)(void *), void *argp) 
    {
        int rc;
        if ((rc = pthread_create(tidp, attrp, routine, argp)) != 0)
        posix_error(rc, "Pthread_create error");
    }
    void Pthread_cancel(pthread_t tid) {
        int rc;
        if ((rc = pthread_cancel(tid)) != 0)
        posix_error(rc, "Pthread_cancel error");
    }
    void Pthread_join(pthread_t tid, void **thread_return) {
        int rc;
        if ((rc = pthread_join(tid, thread_return)) != 0)
        posix_error(rc, "Pthread_join error");
    }
    /* $begin detach */
    void Pthread_detach(pthread_t tid) {
        int rc;
        if ((rc = pthread_detach(tid)) != 0)
        posix_error(rc, "Pthread_detach error");
    }
    /* $end detach */
    void Pthread_exit(void *retval) {
        pthread_exit(retval);
    }
    pthread_t Pthread_self(void) {
        return pthread_self();
    }
    void Pthread_once(pthread_once_t *once_control, void (*init_function)()) {
        pthread_once(once_control, init_function);
    }
    /*******************************
     * Wrappers for Posix semaphores
     *******************************/
    void Sem_init(sem_t *sem, int pshared, unsigned int value) 
    {
        if (sem_init(sem, pshared, value) < 0)
        unix_error("Sem_init error");
    }
    void P(sem_t *sem) 
    {
        if (sem_wait(sem) < 0)
        unix_error("P error");
    }
    void V(sem_t *sem) 
    {
        if (sem_post(sem) < 0)
        unix_error("V error");
    }
    /*********************************************************************
     * The Rio package - robust I/O functions
     **********************************************************************/
    /*
     * rio_readn - robustly read n bytes (unbuffered)
     */
    /* $begin rio_readn */
    ssize_t rio_readn(int fd, void *usrbuf, size_t n) 
    {
        size_t nleft = n;
        ssize_t nread;
        char *bufp = usrbuf;
        while (nleft > 0) {
        if ((nread = read(fd, bufp, nleft)) < 0) {
            if (errno == EINTR) /* interrupted by sig handler return */
            nread = 0;      /* and call read() again */
            else
            return -1;      /* errno set by read() */ 
        } 
        else if (nread == 0)
            break;              /* EOF */
        nleft -= nread;
        bufp += nread;
        }
        return (n - nleft);         /* return >= 0 */
    }
    /* $end rio_readn */
    
    /*
     * rio_writen - robustly write n bytes (unbuffered)
     */
    /* $begin rio_writen */
    ssize_t rio_writen(int fd, void *usrbuf, size_t n) 
    {
        size_t nleft = n;
        ssize_t nwritten;
        char *bufp = usrbuf;
        while (nleft > 0) {
        if ((nwritten = write(fd, bufp, nleft)) <= 0) {
            if (errno == EINTR)  /* interrupted by sig handler return */
            nwritten = 0;    /* and call write() again */
            else
            return -1;       /* errno set by write() */
        }
        nleft -= nwritten;
        bufp += nwritten;
        }
        return n;
    }
    /* $end rio_writen */
    /* 
     * rio_read - This is a wrapper for the Unix read() function that
     *    transfers min(n, rio_cnt) bytes from an internal buffer to a user
     *    buffer, where n is the number of bytes requested by the user and
     *    rio_cnt is the number of unread bytes in the internal buffer. On
     *    entry, rio_read() refills the internal buffer via a call to
     *    read() if the internal buffer is empty.
     */
    /* $begin rio_read */
    static ssize_t rio_read(rio_t *rp, char *usrbuf, size_t n)
    {
        int cnt;
        while (rp->rio_cnt <= 0) {  /* refill if buf is empty */
        rp->rio_cnt = read(rp->rio_fd, rp->rio_buf, 
                   sizeof(rp->rio_buf));
        if (rp->rio_cnt < 0) {
            if (errno != EINTR) /* interrupted by sig handler return */
            return -1;
        }
        else if (rp->rio_cnt == 0)  /* EOF */
            return 0;
        else 
            rp->rio_bufptr = rp->rio_buf; /* reset buffer ptr */
        }
    
        /* Copy min(n, rp->rio_cnt) bytes from internal buf to user buf */
        cnt = n;          
        if (rp->rio_cnt < n)   
        cnt = rp->rio_cnt;
        memcpy(usrbuf, rp->rio_bufptr, cnt);
        rp->rio_bufptr += cnt;
        rp->rio_cnt -= cnt;
        return cnt;
    }
    /* $end rio_read */
    
    /*
     * rio_readinitb - Associate a descriptor with a read buffer and reset buffer
     */
    /* $begin rio_readinitb */
    void rio_readinitb(rio_t *rp, int fd) 
    {
        rp->rio_fd = fd;  
        rp->rio_cnt = 0;  
        rp->rio_bufptr = rp->rio_buf;
    }
    /* $end rio_readinitb */
    /*
     * rio_readnb - Robustly read n bytes (buffered)
     */
    /* $begin rio_readnb */
    ssize_t rio_readnb(rio_t *rp, void *usrbuf, size_t n) 
    {
        size_t nleft = n;
        ssize_t nread;
        char *bufp = usrbuf;
        while (nleft > 0) {
        if ((nread = rio_read(rp, bufp, nleft)) < 0) {
            if (errno == EINTR) /* interrupted by sig handler return */
            nread = 0;      /* call read() again */
            else
            return -1;      /* errno set by read() */ 
        } 
        else if (nread == 0)
            break;              /* EOF */
        nleft -= nread;
        bufp += nread;
        }
        return (n - nleft);         /* return >= 0 */
    }
    /* $end rio_readnb */
    /* 
     * rio_readlineb - robustly read a text line (buffered)
     */
    /* $begin rio_readlineb */
    ssize_t rio_readlineb(rio_t *rp, void *usrbuf, size_t maxlen) 
    {
        int n, rc;
        char c, *bufp = usrbuf;
        for (n = 1; n < maxlen; n++) { 
        if ((rc = rio_read(rp, &c, 1)) == 1) {
            *bufp++ = c;
            if (c == '
    ')
            break;
        } else if (rc == 0) {
            if (n == 1)
            return 0; /* EOF, no data read */
            else
            break;    /* EOF, some data was read */
        } else
            return -1;    /* error */
        }
        *bufp = 0;
        return n;
    }
    /* $end rio_readlineb */
    
    /**********************************
     * Wrappers for robust I/O routines
     **********************************/
    ssize_t Rio_readn(int fd, void *ptr, size_t nbytes) 
    {
        ssize_t n;
    
        if ((n = rio_readn(fd, ptr, nbytes)) < 0)
        unix_error("Rio_readn error");
        return n;
    }
    void Rio_writen(int fd, void *usrbuf, size_t n) 
    {
        if (rio_writen(fd, usrbuf, n) != n)
        unix_error("Rio_writen error");
    }
    void Rio_readinitb(rio_t *rp, int fd)
    {
        rio_readinitb(rp, fd);
    } 
    ssize_t Rio_readnb(rio_t *rp, void *usrbuf, size_t n) 
    {
        ssize_t rc;
    
        if ((rc = rio_readnb(rp, usrbuf, n)) < 0)
        unix_error("Rio_readnb error");
        return rc;
    }
    ssize_t Rio_readlineb(rio_t *rp, void *usrbuf, size_t maxlen) 
    {
        ssize_t rc;
        if ((rc = rio_readlineb(rp, usrbuf, maxlen)) < 0)
        unix_error("Rio_readlineb error");
        return rc;
    } 
    /******************************** 
     * Client/server helper functions
     ********************************/
    /*
     * open_clientfd - open connection to server at <hostname, port> 
     *   and return a socket descriptor ready for reading and writing.
     *   Returns -1 and sets errno on Unix error. 
     *   Returns -2 and sets h_errno on DNS (gethostbyname) error.
     */
    /* $begin open_clientfd */
    int open_clientfd(char *hostname, int port) 
    {
        int clientfd;
        struct hostent *hp;
        struct sockaddr_in serveraddr;
        if ((clientfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
        return -1; /* check errno for cause of error */
        /* Fill in the server's IP address and port */
        if ((hp = gethostbyname(hostname)) == NULL)
        return -2; /* check h_errno for cause of error */
        bzero((char *) &serveraddr, sizeof(serveraddr));
        serveraddr.sin_family = AF_INET;
        bcopy((char *)hp->h_addr_list[0], 
          (char *)&serveraddr.sin_addr.s_addr, hp->h_length);
        serveraddr.sin_port = htons(port);
        /* Establish a connection with the server */
        if (connect(clientfd, (SA *) &serveraddr, sizeof(serveraddr)) < 0)
        return -1;
        return clientfd;
    }
    /* $end open_clientfd */
    /*  
     * open_listenfd - open and return a listening socket on port
     *     Returns -1 and sets errno on Unix error.
     */
    /* $begin open_listenfd */
    int open_listenfd(int port) 
    {
        int listenfd, optval=1;
        struct sockaddr_in serveraddr;
        /* Create a socket descriptor */
        if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
        return -1;
        /* Eliminates "Address already in use" error from bind. */
        if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, 
               (const void *)&optval , sizeof(int)) < 0)
        return -1;
        /* Listenfd will be an endpoint for all requests to port
           on any IP address for this host */
        bzero((char *) &serveraddr, sizeof(serveraddr));
        serveraddr.sin_family = AF_INET; 
        serveraddr.sin_addr.s_addr = htonl(INADDR_ANY); 
        serveraddr.sin_port = htons((unsigned short)port); 
        if (bind(listenfd, (SA *)&serveraddr, sizeof(serveraddr)) < 0)
        return -1;
        /* Make it a listening socket ready to accept connection requests */
        if (listen(listenfd, LISTENQ) < 0)
        return -1;
        return listenfd;
    }
    /* $end open_listenfd */
    /******************************************
     * Wrappers for the client/server helper routines 
     ******************************************/
    int Open_clientfd(char *hostname, int port) 
    {
        int rc;
        if ((rc = open_clientfd(hostname, port)) < 0) {
        if (rc == -1)
            unix_error("Open_clientfd Unix error");
        else        
            dns_error("Open_clientfd DNS error");
        }
        return rc;
    }
    int Open_listenfd(int port) 
    {
        int rc;
        if ((rc = open_listenfd(port)) < 0)
        unix_error("Open_listenfd error");
        return rc;
    }
    /* $end csapp.c */
    

    返回目录

    三、代码托管与统计

    **** [代码托管](https://gitee.com/Sean-Lxs/5226lxs.git) ![](https://img2018.cnblogs.com/blog/1047870/201811/1047870-20181104230324799-2142825116.png)

    返回目录

    四、学习进度条

    ****
    代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
    目标 5000行 30篇 400小时
    第一周 87/87 2/2 20/20
    第二周 71/158 1/3 12/32
    第三周 100/258 2/5 13/45
    第四周 3265/9750 2/7 15/60
    第五周 282/9786 1/8 8/68
    第六周 1980/13996 2/10 8/76

    尝试一下记录「计划学习时间」和「实际学习时间」,到期末看看能不能改进自己的计划能力。这个工作学习中很重要,也很有用。
    耗时估计的公式
    :Y=X+X/N ,Y=X-X/N,训练次数多了,X、Y就接近了。

    参考:软件工程软件的估计为什么这么难软件工程 估计方法

    • 计划学习时间:8小时

    • 实际学习时间:8小时

    • 改进情况:

    (有空多看看现代软件工程 课件
    软件工程师能力自我评价表
    )

    返回目录

    五、参考资料

    **** - [《深入理解计算机系统V3》学习指导]([http://www.cnblogs.com/rocedu/p/5826467.html]) - [Linux 基础入门(新版)_Linux_实验楼 - 实验楼](https://www.shiyanlou.com/courses/1)

    返回目录

  • 相关阅读:
    限制CPU个数
    delphi 不阻塞提示对话框
    快捷打开vnc 某个连接
    delphi ShellExecute 传递多个参数
    JS对JSON的操作总结 (转)
    Windows Server 2008 IIS下部署网站出现的问题
    SqlParameter序列化的问题
    求解,工作流点通过时,弹出窗口让用户录入审核意见
    oracle调度
    c# 多态
  • 原文地址:https://www.cnblogs.com/musea/p/9875423.html
Copyright © 2011-2022 走看看