📄 csapp.c
字号:
if ((rc = pthread_cond_broadcast(cond)) != 0) posix_error(rc, "Pthread_cond_broadcast error");}void Pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) { int rc; if ((rc = pthread_cond_wait(cond, mutex)) != 0) posix_error(rc, "Pthread_cond_wait error");}/* $begin timedwait */int Pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, struct timespec *abstime) { int rc = pthread_cond_timedwait(cond, mutex, abstime); if ((rc != 0) && (rc != ETIMEDOUT)) posix_error(rc, "Pthread_cond_timedwait error"); return rc;} /* $end timedwait *//******************************* * 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");}/**************************** * 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, int *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;}/******************************** * Client/server helper functions ********************************//* * open_clientfd - open connection to server at <hostname, port> * and return a socket descriptor ready for reading and writing. *//* $begin open_clientfd */int open_clientfd(char *hostname, int port) { int clientfd; struct hostent *hp; struct sockaddr_in serveraddr; clientfd = Socket(AF_INET, SOCK_STREAM, 0); /* fill in the server's IP address and port */ hp = Gethostbyname(hostname); bzero((char *) &serveraddr, sizeof(serveraddr)); serveraddr.sin_family = AF_INET; bcopy((char *)hp->h_addr, (char *)&serveraddr.sin_addr.s_addr, hp->h_length); serveraddr.sin_port = htons(port); /* establish a connection with the server */ Connect(clientfd, (SA *) &serveraddr, sizeof(serveraddr)); return clientfd;}/* $end open_clientfd *//* * open_listenfd - open and return a listening socket on port *//* $begin open_listenfd */int open_listenfd(int port) { int listenfd; int optval; struct sockaddr_in serveraddr; /* create a socket descriptor */ listenfd = Socket(AF_INET, SOCK_STREAM, 0); /* eliminates "Address already in use" error from bind. */ optval = 1; Setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (const void *)&optval , sizeof(int)); /* 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); Bind(listenfd, (SA *)&serveraddr, sizeof(serveraddr)); /* make it a listening socket ready to accept connection requests */ Listen(listenfd, LISTENQ); return listenfd;}/* $end open_listenfd *//****************************************** * I/O helper functions (from Stevens UNP) ******************************************//* $begin readn */ssize_t readn(int fd, void *buf, size_t count) { size_t nleft = count; ssize_t nread; char *ptr = buf; while (nleft > 0) { if ((nread = read(fd, ptr, nleft)) < 0) { if (errno == EINTR) nread = 0; /* and call read() again */ else return -1; /* errno set by read() */ } else if (nread == 0) break; /* EOF */ nleft -= nread; ptr += nread; } return (count - nleft); /* return >= 0 */}/* $end readn *//* $begin writen */ssize_t writen(int fd, const void *buf, size_t count) { size_t nleft = count; ssize_t nwritten; const char *ptr = buf; while (nleft > 0) { if ((nwritten = write(fd, ptr, nleft)) <= 0) { if (errno == EINTR) nwritten = 0; /* and call write() again */ else return -1; /* errorno set by write() */ } nleft -= nwritten; ptr += nwritten; } return count;}/* $end writen *//* $begin readline */static ssize_t my_read(int fd, char *ptr) { static int read_cnt = 0; static char *read_ptr, read_buf[MAXLINE]; if (read_cnt <= 0) { again: if ( (read_cnt = read(fd, read_buf, sizeof(read_buf))) < 0) { if (errno == EINTR) goto again; return -1; } else if (read_cnt == 0) return 0; read_ptr = read_buf; } read_cnt--; *ptr = *read_ptr++; return 1;}ssize_t readline(int fd, void *buf, size_t maxlen) { int n, rc; char c, *ptr = buf; for (n = 1; n < maxlen; n++) { /* notice that loop starts at 1 */ if ( (rc = my_read(fd, &c)) == 1) { *ptr++ = c; if (c == '\n') break; /* newline is stored, like fgets() */ } else if (rc == 0) { if (n == 1) return 0; /* EOF, no data read */ else break; /* EOF, some data was read */ } else return -1; /* error, errno set by read() */ } *ptr = 0; /* null terminate like fgets() */ return n;}/* $end readline *//* * readline_r: Stevens's reentrant readline package * (mentioned but not defined in UNP 23.5) *//* $begin readline_r */static ssize_t my_read_r(Rline *rptr, char *ptr) { if (rptr->rl_cnt <= 0) { again: rptr->rl_cnt = read(rptr->read_fd, rptr->rl_buf, sizeof(rptr->rl_buf)); if (rptr->rl_cnt < 0) { if (errno == EINTR) goto again; else return(-1); } else if (rptr->rl_cnt == 0) return(0); rptr->rl_bufptr = rptr->rl_buf; } rptr->rl_cnt--; *ptr = *rptr->rl_bufptr++ & 255; return(1);}ssize_t readline_r(Rline *rptr) { int n, rc; char c, *ptr = rptr->read_ptr; for (n = 1; n < rptr->read_maxlen; n++) { if ( (rc = my_read_r(rptr, &c)) == 1) { *ptr++ = c; if (c == '\n') 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 */ } *ptr = 0; return(n);}/* $end readline_r *//* * readline_rinit - initialization function for readline_r *//* $begin readline_rinit */void readline_rinit(int fd, void *ptr, size_t maxlen, Rline *rptr) { rptr->read_fd = fd; /* save caller's arguments */ rptr->read_ptr = ptr; rptr->read_maxlen = maxlen; rptr->rl_cnt = 0; /* and init our counter & pointer */ rptr->rl_bufptr = rptr->rl_buf;}/* $end readline_rinit *//**************************************************** * Error-handling wrappers for Stevens's I/O helpers ****************************************************/ssize_t Readn(int fd, void *ptr, size_t nbytes) { ssize_t n; if ((n = readn(fd, ptr, nbytes)) < 0) unix_error("Readn error"); return n;}void Writen(int fd, void *ptr, size_t nbytes) { if (writen(fd, ptr, nbytes) != nbytes) unix_error("Writen error");}ssize_t Readline(int fd, void *ptr, size_t maxlen) { ssize_t n; if ((n = readline(fd, ptr, maxlen)) < 0) unix_error("Readline error"); return n;}ssize_t Readline_r(Rline *rptr) { ssize_t n; if ( (n = readline_r(rptr)) == -1) unix_error("readline_r error"); return(n);}void Readline_rinit(int fd, void *ptr, size_t maxlen, Rline *rptr) { readline_rinit(fd, ptr, maxlen, rptr);}/* $end csapp.c */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -