《CSAPP》(第3版)答案(第十一章)
生活随笔
收集整理的這篇文章主要介紹了
《CSAPP》(第3版)答案(第十一章)
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
《CSAPP》(第3版)答案(第十一章)
P6
- A
- B
- C
HTTP 1.1 - D
rfc
P7
#include "csapp.h" void doit(int fd); void read_requesthdrs(rio_t *rp); int parse_uri(char *uri, char *filename, char *cgiargs); void serve_static(int fd, char *filename, int filesize); void get_filetype(char *filename, char *filetype); void serve_dynamic(int fd, char *filename, char *cgiargs); void clienterror(int fd, char *cause, char *errnum,char *shortmsg, char *longmsg); int main(int argc, char **argv) {int listenfd, connfd;char hostname[MAXLINE], port[MAXLINE];socklen_t clientlen;struct sockaddr_storage clientaddr;/* Check command line args */if (argc != 2) {fprintf(stderr, "usage: %s <port>\n", argv[0]);exit(1);}listenfd = Open_listenfd(argv[1]);while (1) {clientlen = sizeof(clientaddr);connfd = Accept(listenfd, (SA *)&clientaddr, &clientlen); //line:netp:tiny:acceptGetnameinfo((SA *) &clientaddr, clientlen, hostname, MAXLINE,port, MAXLINE, 0);printf("Accepted connection from (%s, %s)\n", hostname, port);doit(connfd); //line:netp:tiny:doitClose(connfd); //line:netp:tiny:close} } /** doit - handle one HTTP request/response transaction*/ void doit(int fd) {int is_static;struct stat sbuf;char buf[MAXLINE], method[MAXLINE], uri[MAXLINE], version[MAXLINE];char filename[MAXLINE], cgiargs[MAXLINE];rio_t rio;/* Read request line and headers */Rio_readinitb(&rio, fd);if (!Rio_readlineb(&rio, buf, MAXLINE)) //line:netp:doit:readrequestreturn;printf("%s", buf);sscanf(buf, "%s %s %s", method, uri, version); //line:netp:doit:parserequestif (strcasecmp(method, "GET")) { //line:netp:doit:beginrequesterrclienterror(fd, method, "501", "Not Implemented","Tiny does not implement this method");return;} //line:netp:doit:endrequesterrread_requesthdrs(&rio); //line:netp:doit:readrequesthdrs/* Parse URI from GET request */is_static = parse_uri(uri, filename, cgiargs); //line:netp:doit:staticcheckif (stat(filename, &sbuf) < 0) { //line:netp:doit:beginnotfoundclienterror(fd, filename, "404", "Not found","Tiny couldn't find this file");return;} //line:netp:doit:endnotfoundif (is_static) { /* Serve static content */if (!(S_ISREG(sbuf.st_mode)) || !(S_IRUSR & sbuf.st_mode)) { //line:netp:doit:readableclienterror(fd, filename, "403", "Forbidden","Tiny couldn't read the file");return;}serve_static(fd, filename, sbuf.st_size); //line:netp:doit:servestatic}else { /* Serve dynamic content */if (!(S_ISREG(sbuf.st_mode)) || !(S_IXUSR & sbuf.st_mode)) { //line:netp:doit:executableclienterror(fd, filename, "403", "Forbidden","Tiny couldn't run the CGI program");return;}serve_dynamic(fd, filename, cgiargs); //line:netp:doit:servedynamic} } /** read_requesthdrs - read HTTP request headers*/ void read_requesthdrs(rio_t *rp) {char buf[MAXLINE];Rio_readlineb(rp, buf, MAXLINE);printf("%s", buf);while(strcmp(buf, "\r\n")) { //line:netp:readhdrs:checktermRio_readlineb(rp, buf, MAXLINE);printf("%s", buf);}return; } /** parse_uri - parse URI into filename and CGI args* return 0 if dynamic content, 1 if static*/ int parse_uri(char *uri, char *filename, char *cgiargs) {char *ptr;if (!strstr(uri, "cgi-bin")) { /* Static content */ //line:netp:parseuri:isstaticstrcpy(cgiargs, ""); //line:netp:parseuri:clearcgistrcpy(filename, "."); //line:netp:parseuri:beginconvert1strcat(filename, uri); //line:netp:parseuri:endconvert1if (uri[strlen(uri)-1] == '/') //line:netp:parseuri:slashcheckstrcat(filename, "home.html"); //line:netp:parseuri:appenddefaultreturn 1;}else { /* Dynamic content */ //line:netp:parseuri:isdynamicptr = index(uri, '?'); //line:netp:parseuri:beginextractif (ptr) {strcpy(cgiargs, ptr+1);*ptr = '\0';}elsestrcpy(cgiargs, ""); //line:netp:parseuri:endextractstrcpy(filename, "."); //line:netp:parseuri:beginconvert2strcat(filename, uri); //line:netp:parseuri:endconvert2return 0;} } /** serve_static - copy a file back to the client*/ void serve_static(int fd, char *filename, int filesize) {int srcfd;char *srcp, filetype[MAXLINE], buf[MAXBUF];/* Send response headers to client */get_filetype(filename, filetype); //line:netp:servestatic:getfiletypesprintf(buf, "HTTP/1.0 200 OK\r\n"); //line:netp:servestatic:beginservesprintf(buf, "%sServer: Tiny Web Server\r\n", buf);sprintf(buf, "%sConnection: close\r\n", buf);sprintf(buf, "%sContent-length: %d\r\n", buf, filesize);sprintf(buf, "%sContent-type: %s\r\n\r\n", buf, filetype);Rio_writen(fd, buf, strlen(buf)); //line:netp:servestatic:endserveprintf("Response headers:\n");printf("%s", buf);/* Send response body to client */srcfd = Open(filename, O_RDONLY, 0); //line:netp:servestatic:opensrcp = Mmap(0, filesize, PROT_READ, MAP_PRIVATE, srcfd, 0);//line:netp:servestatic:mmapClose(srcfd); //line:netp:servestatic:closeRio_writen(fd, srcp, filesize); //line:netp:servestatic:writeMunmap(srcp, filesize); //line:netp:servestatic:munmap } /** get_filetype - derive file type from file name*/ void get_filetype(char *filename, char *filetype) {if (strstr(filename, ".html"))strcpy(filetype, "text/html");else if (strstr(filename, ".gif"))strcpy(filetype, "image/gif");else if (strstr(filename, ".png"))strcpy(filetype, "image/png");else if (strstr(filename, ".jpg"))strcpy(filetype, "image/jpeg");else if (strstr(filename, ".mpeg"))strcpy(filetype, "video/mpeg");elsestrcpy(filetype, "text/plain"); } /** serve_dynamic - run a CGI program on behalf of the client*/ void serve_dynamic(int fd, char *filename, char *cgiargs) {char buf[MAXLINE], *emptylist[] = { NULL };/* Return first part of HTTP response */sprintf(buf, "HTTP/1.0 200 OK\r\n");Rio_writen(fd, buf, strlen(buf));sprintf(buf, "Server: Tiny Web Server\r\n");Rio_writen(fd, buf, strlen(buf));if (Fork() == 0) { /* Child */ //line:netp:servedynamic:fork/* Real server would set all CGI vars here */setenv("QUERY_STRING", cgiargs, 1); //line:netp:servedynamic:setenvDup2(fd, STDOUT_FILENO); /* Redirect stdout to client */ //line:netp:servedynamic:dup2Execve(filename, emptylist, environ); /* Run CGI program */ //line:netp:servedynamic:execve}Wait(NULL); /* Parent waits for and reaps child */ //line:netp:servedynamic:wait } /** clienterror - returns an error message to the client*/ void clienterror(int fd, char *cause, char *errnum,char *shortmsg, char *longmsg) {char buf[MAXLINE], body[MAXBUF];/* Build the HTTP response body */sprintf(body, "<html><title>Tiny Error</title>");sprintf(body, "%s<body bgcolor=""ffffff"">\r\n", body);sprintf(body, "%s%s: %s\r\n", body, errnum, shortmsg);sprintf(body, "%s<p>%s: %s\r\n", body, longmsg, cause);sprintf(body, "%s<hr><em>The Tiny Web server</em>\r\n", body);/* Print the HTTP response */sprintf(buf, "HTTP/1.0 %s %s\r\n", errnum, shortmsg);Rio_writen(fd, buf, strlen(buf));sprintf(buf, "Content-type: text/html\r\n");Rio_writen(fd, buf, strlen(buf));sprintf(buf, "Content-length: %d\r\n\r\n", (int)strlen(body));Rio_writen(fd, buf, strlen(buf));Rio_writen(fd, body, strlen(body)); }以上是源代碼。如果不知道怎么跑關注私信我,我把整個工程文件夾發(fā)過去。
P8
#include "csapp.h" void doit(int fd); void read_requesthdrs(rio_t *rp); int parse_uri(char *uri, char *filename, char *cgiargs); void serve_static(int fd, char *filename, int filesize); void get_filetype(char *filename, char *filetype); void serve_dynamic(int fd, char *filename, char *cgiargs); void clienterror(int fd, char *cause, char *errnum,char *shortmsg, char *longmsg); void sigchild_handler(int sig); int main(int argc, char **argv) {int listenfd, connfd;char hostname[MAXLINE], port[MAXLINE];socklen_t clientlen;struct sockaddr_storage clientaddr;/* Check command line args */if (argc != 2) {fprintf(stderr, "usage: %s <port>\n", argv[0]);exit(1);}if (Signal(SIGCHLD, sigchild_handler) == SIG_ERR)unix_error("signal child handler error");listenfd = Open_listenfd(argv[1]);while (1) {clientlen = sizeof(clientaddr);connfd = Accept(listenfd, (SA *)&clientaddr, &clientlen); //line:netp:tiny:acceptGetnameinfo((SA *) &clientaddr, clientlen, hostname, MAXLINE,port, MAXLINE, 0);printf("Accepted connection from (%s, %s)\n", hostname, port);doit(connfd); //line:netp:tiny:doitClose(connfd); //line:netp:tiny:close} } void sigchild_handler(int sig) {int old_errno = errno;int status;pid_t pid;while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {}errno = old_errno; } /** doit - handle one HTTP request/response transaction*/ void doit(int fd) {int is_static;struct stat sbuf;char buf[MAXLINE], method[MAXLINE], uri[MAXLINE], version[MAXLINE];char filename[MAXLINE], cgiargs[MAXLINE];rio_t rio;/* Read request line and headers */Rio_readinitb(&rio, fd);if (!Rio_readlineb(&rio, buf, MAXLINE)) //line:netp:doit:readrequestreturn;printf("%s", buf);sscanf(buf, "%s %s %s", method, uri, version); //line:netp:doit:parserequestif (strcasecmp(method, "GET")) { //line:netp:doit:beginrequesterrclienterror(fd, method, "501", "Not Implemented","Tiny does not implement this method");return;} //line:netp:doit:endrequesterrread_requesthdrs(&rio); //line:netp:doit:readrequesthdrs/* Parse URI from GET request */is_static = parse_uri(uri, filename, cgiargs); //line:netp:doit:staticcheckif (stat(filename, &sbuf) < 0) { //line:netp:doit:beginnotfoundclienterror(fd, filename, "404", "Not found","Tiny couldn't find this file");return;} //line:netp:doit:endnotfoundif (is_static) { /* Serve static content */if (!(S_ISREG(sbuf.st_mode)) || !(S_IRUSR & sbuf.st_mode)) { //line:netp:doit:readableclienterror(fd, filename, "403", "Forbidden","Tiny couldn't read the file");return;}serve_static(fd, filename, sbuf.st_size); //line:netp:doit:servestatic}else { /* Serve dynamic content */if (!(S_ISREG(sbuf.st_mode)) || !(S_IXUSR & sbuf.st_mode)) { //line:netp:doit:executableclienterror(fd, filename, "403", "Forbidden","Tiny couldn't run the CGI program");return;}serve_dynamic(fd, filename, cgiargs); //line:netp:doit:servedynamic} } /** read_requesthdrs - read HTTP request headers*/ void read_requesthdrs(rio_t *rp) {char buf[MAXLINE];Rio_readlineb(rp, buf, MAXLINE);printf("%s", buf);while(strcmp(buf, "\r\n")) { //line:netp:readhdrs:checktermRio_readlineb(rp, buf, MAXLINE);printf("%s", buf);}return; } /** parse_uri - parse URI into filename and CGI args* return 0 if dynamic content, 1 if static*/ int parse_uri(char *uri, char *filename, char *cgiargs) {char *ptr;if (!strstr(uri, "cgi-bin")) { /* Static content */ //line:netp:parseuri:isstaticstrcpy(cgiargs, ""); //line:netp:parseuri:clearcgistrcpy(filename, "."); //line:netp:parseuri:beginconvert1strcat(filename, uri); //line:netp:parseuri:endconvert1if (uri[strlen(uri)-1] == '/') //line:netp:parseuri:slashcheckstrcat(filename, "home.html"); //line:netp:parseuri:appenddefaultreturn 1;}else { /* Dynamic content */ //line:netp:parseuri:isdynamicptr = index(uri, '?'); //line:netp:parseuri:beginextractif (ptr) {strcpy(cgiargs, ptr+1);*ptr = '\0';}elsestrcpy(cgiargs, ""); //line:netp:parseuri:endextractstrcpy(filename, "."); //line:netp:parseuri:beginconvert2strcat(filename, uri); //line:netp:parseuri:endconvert2return 0;} } /** serve_static - copy a file back to the client*/ void serve_static(int fd, char *filename, int filesize) {int srcfd;char *srcp, filetype[MAXLINE], buf[MAXBUF];/* Send response headers to client */get_filetype(filename, filetype); //line:netp:servestatic:getfiletypesprintf(buf, "HTTP/1.0 200 OK\r\n"); //line:netp:servestatic:beginservesprintf(buf, "%sServer: Tiny Web Server\r\n", buf);sprintf(buf, "%sConnection: close\r\n", buf);sprintf(buf, "%sContent-length: %d\r\n", buf, filesize);sprintf(buf, "%sContent-type: %s\r\n\r\n", buf, filetype);Rio_writen(fd, buf, strlen(buf)); //line:netp:servestatic:endserveprintf("Response headers:\n");printf("%s", buf);/* Send response body to client */srcfd = Open(filename, O_RDONLY, 0); //line:netp:servestatic:opensrcp = Mmap(0, filesize, PROT_READ, MAP_PRIVATE, srcfd, 0);//line:netp:servestatic:mmapClose(srcfd); //line:netp:servestatic:closeRio_writen(fd, srcp, filesize); //line:netp:servestatic:writeMunmap(srcp, filesize); //line:netp:servestatic:munmap } /** get_filetype - derive file type from file name*/ void get_filetype(char *filename, char *filetype) {if (strstr(filename, ".html"))strcpy(filetype, "text/html");else if (strstr(filename, ".gif"))strcpy(filetype, "image/gif");else if (strstr(filename, ".png"))strcpy(filetype, "image/png");else if (strstr(filename, ".jpg"))strcpy(filetype, "image/jpeg");elsestrcpy(filetype, "text/plain"); } /** serve_dynamic - run a CGI program on behalf of the client*/ void serve_dynamic(int fd, char *filename, char *cgiargs) {char buf[MAXLINE], *emptylist[] = { NULL };/* Return first part of HTTP response */sprintf(buf, "HTTP/1.0 200 OK\r\n");Rio_writen(fd, buf, strlen(buf));sprintf(buf, "Server: Tiny Web Server\r\n");Rio_writen(fd, buf, strlen(buf));if (Fork() == 0) { /* Child */ //line:netp:servedynamic:fork/* Real server would set all CGI vars here */setenv("QUERY_STRING", cgiargs, 1); //line:netp:servedynamic:setenvDup2(fd, STDOUT_FILENO); /* Redirect stdout to client */ //line:netp:servedynamic:dup2Execve(filename, emptylist, environ); /* Run CGI program */ //line:netp:servedynamic:execve} } /** clienterror - returns an error message to the client*/ void clienterror(int fd, char *cause, char *errnum,char *shortmsg, char *longmsg) {char buf[MAXLINE], body[MAXBUF];/* Build the HTTP response body */sprintf(body, "<html><title>Tiny Error</title>");sprintf(body, "%s<body bgcolor=""ffffff"">\r\n", body);sprintf(body, "%s%s: %s\r\n", body, errnum, shortmsg);sprintf(body, "%s<p>%s: %s\r\n", body, longmsg, cause);sprintf(body, "%s<hr><em>The Tiny Web server</em>\r\n", body);/* Print the HTTP response */sprintf(buf, "HTTP/1.0 %s %s\r\n", errnum, shortmsg);Rio_writen(fd, buf, strlen(buf));sprintf(buf, "Content-type: text/html\r\n");Rio_writen(fd, buf, strlen(buf));sprintf(buf, "Content-length: %d\r\n\r\n", (int)strlen(body));Rio_writen(fd, buf, strlen(buf));Rio_writen(fd, body, strlen(body)); }P9
@@ -152,12 +152,12 @@printf("Response headers:\n");printf("%s", buf);- /* Send response body to client */srcfd = Open(filename, O_RDONLY, 0); //line:netp:servestatic:open - srcp = Mmap(0, filesize, PROT_READ, MAP_PRIVATE, srcfd, 0);//line:netp:servestatic:mmap + srcp = (char*)Malloc(filesize); + Rio_readn(srcfd, srcp, filesize);Close(srcfd); //line:netp:servestatic:closeRio_writen(fd, srcp, filesize); //line:netp:servestatic:write - Munmap(srcp, filesize); //line:netp:servestatic:munmap + free(srcp);}P10
- A
- B
P11
tiny.c更改:
@@ -7,9 +7,9 @@void doit(int fd);void read_requesthdrs(rio_t *rp);int parse_uri(char *uri, char *filename, char *cgiargs); -void serve_static(int fd, char *filename, int filesize); +void serve_static(int fd, char *filename, int filesize, char *method);void get_filetype(char *filename, char *filetype); -void serve_dynamic(int fd, char *filename, char *cgiargs); +void serve_dynamic(int fd, char *filename, char *cgiargs, char *method);void clienterror(int fd, char *cause, char *errnum,char *shortmsg, char *longmsg);@@ -55,7 +55,7 @@return;printf("%s", buf);sscanf(buf, "%s %s %s", method, uri, version); //line:netp:doit:parserequest - if (strcasecmp(method, "GET")) { //line:netp:doit:beginrequesterr + if (!(strcasecmp(method, "GET") == 0 || strcasecmp(method, "HEAD") == 0)) {clienterror(fd, method, "501", "Not Implemented","Tiny does not implement this method");return; @@ -76,7 +76,7 @@"Tiny couldn't read the file");return;} - serve_static(fd, filename, sbuf.st_size); //line:netp:doit:servestatic + serve_static(fd, filename, sbuf.st_size, method); //line:netp:doit:servestatic}else { /* Serve dynamic content */if (!(S_ISREG(sbuf.st_mode)) || !(S_IXUSR & sbuf.st_mode)) { //line:netp:doit:executable @@ -84,7 +84,7 @@"Tiny couldn't run the CGI program");return;} - serve_dynamic(fd, filename, cgiargs); //line:netp:doit:servedynamic + serve_dynamic(fd, filename, cgiargs, method); //line:netp:doit:servedynamic}}@@ -136,7 +136,7 @@/** serve_static - copy a file back to the client*/ -void serve_static(int fd, char *filename, int filesize) +void serve_static(int fd, char *filename, int filesize, char *method){int srcfd;char *srcp, filetype[MAXLINE], buf[MAXBUF]; @@ -152,6 +152,9 @@printf("Response headers:\n");printf("%s", buf);+ if (strcasecmp(method, "HEAD") == 0) + return; +/* Send response body to client */srcfd = Open(filename, O_RDONLY, 0); //line:netp:servestatic:opensrcp = Mmap(0, filesize, PROT_READ, MAP_PRIVATE, srcfd, 0);//line:netp:servestatic:mmap @@ -180,7 +183,7 @@/** serve_dynamic - run a CGI program on behalf of the client*/ -void serve_dynamic(int fd, char *filename, char *cgiargs) +void serve_dynamic(int fd, char *filename, char *cgiargs, char *method){char buf[MAXLINE], *emptylist[] = { NULL };@@ -193,6 +196,7 @@if (Fork() == 0) { /* Child */ //line:netp:servedynamic:fork/* Real server would set all CGI vars here */setenv("QUERY_STRING", cgiargs, 1); //line:netp:servedynamic:setenv + setenv("REQUEST_METHOD", method, 1);Dup2(fd, STDOUT_FILENO); /* Redirect stdout to client */ //line:netp:servedynamic:dup2Execve(filename, emptylist, environ); /* Run CGI program */ //line:netp:servedynamic:execve}addr.c更改:
@@ -1,10 +1,10 @@/* - * adder.c - a minimal CGI program that adds two numbers together + * head-adder.c - a minimal CGI program that adds two numbers together*/#include "../csapp.h"int main(void) { - char *buf, *p; + char *buf, *p, *method;char arg1[MAXLINE], arg2[MAXLINE], content[MAXLINE];int n1=0, n2=0;@@ -18,6 +18,8 @@n2 = atoi(arg2);}+ method = getenv("REQUEST_METHOD"); +/* Make the response body */sprintf(content, "Welcome to add.com: ");sprintf(content, "%sTHE Internet addition portal.\r\n<p>", content); @@ -29,7 +31,10 @@printf("Connection: close\r\n");printf("Content-length: %d\r\n", (int)strlen(content));printf("Content-type: text/html\r\n\r\n"); - printf("%s", content); + + if (strcasecmp(method, "HEAD") != 0) + printf("%s", content); +fflush(stdout);exit(0);P12
tiny.c
@@ -5,7 +5,7 @@#include "csapp.h"void doit(int fd); -void read_requesthdrs(rio_t *rp); +int read_requesthdrs(rio_t *rp, char *method);int parse_uri(char *uri, char *filename, char *cgiargs);void serve_static(int fd, char *filename, int filesize);void get_filetype(char *filename, char *filetype); @@ -55,12 +55,14 @@return;printf("%s", buf);sscanf(buf, "%s %s %s", method, uri, version); //line:netp:doit:parserequest - if (strcasecmp(method, "GET")) { //line:netp:doit:beginrequesterr + if (!(strcasecmp(method, "GET") == 0 || strcasecmp(method, "POST") == 0)) {clienterror(fd, method, "501", "Not Implemented","Tiny does not implement this method");return;} //line:netp:doit:endrequesterr - read_requesthdrs(&rio); //line:netp:doit:readrequesthdrs + int param_len = read_requesthdrs(&rio, method); + + Rio_readnb(&rio, buf, param_len);/* Parse URI from GET request */is_static = parse_uri(uri, filename, cgiargs); //line:netp:doit:staticcheck @@ -84,24 +86,29 @@"Tiny couldn't run the CGI program");return;} - serve_dynamic(fd, filename, cgiargs); //line:netp:doit:servedynamic + if (strcasecmp(method, "GET") == 0) + serve_dynamic(fd, filename, cgiargs); + else + serve_dynamic(fd, filename, buf);}}/** read_requesthdrs - read HTTP request headers*/ -void read_requesthdrs(rio_t *rp) +int read_requesthdrs(rio_t *rp, char *method){char buf[MAXLINE]; + int len = 0;- Rio_readlineb(rp, buf, MAXLINE); - printf("%s", buf); - while(strcmp(buf, "\r\n")) { //line:netp:readhdrs:checkterm + do {Rio_readlineb(rp, buf, MAXLINE);printf("%s", buf); - } - return; + if (strcasecmp(method, "POST") == 0 && strncasecmp(buf, "Content-Length:", 15) == 0) + sscanf(buf, "Content-Length: %d", &len); + } while(strcmp(buf, "\r\n")); + + return len;post-addr
@@ -1,5 +1,5 @@/* - * adder.c - a minimal CGI program that adds two numbers together + * post-adder.c - a minimal CGI program that adds two numbers together*/#include "../csapp.h"@@ -12,10 +12,8 @@if ((buf = getenv("QUERY_STRING")) != NULL) {p = strchr(buf, '&');*p = '\0'; - strcpy(arg1, buf); - strcpy(arg2, p+1); - n1 = atoi(arg1); - n2 = atoi(arg2); + sscanf(buf, "first=%d", &n1); + sscanf(p+1, "second=%d", &n2);}P13
@@ -13,6 +13,17 @@void clienterror(int fd, char *cause, char *errnum,char *shortmsg, char *longmsg);+// improved rio written +void Im_rio_writen(int fd, void *usrbuf, size_t n) { + if (rio_writen(fd, usrbuf, n) != n) { + if (errno == EPIPE) + fprintf(stderr, "EPIPE error"); + + fprintf(stderr, "%s ", strerror(errno)); + unix_error("client side has ended connection"); + } +} +int main(int argc, char **argv){int listenfd, connfd; @@ -26,6 +37,9 @@exit(1);}+ if (Signal(SIGPIPE, SIG_IGN) == SIG_ERR) + unix_error("mask signal pipe error"); +listenfd = Open_listenfd(argv[1]);while (1) {clientlen = sizeof(clientaddr); @@ -148,7 +162,7 @@sprintf(buf, "%sConnection: close\r\n", buf);sprintf(buf, "%sContent-length: %d\r\n", buf, filesize);sprintf(buf, "%sContent-type: %s\r\n\r\n", buf, filetype); - Rio_writen(fd, buf, strlen(buf)); //line:netp:servestatic:endserve + Im_rio_writen(fd, buf, strlen(buf)); //line:netp:servestatic:endserveprintf("Response headers:\n");printf("%s", buf);@@ -156,7 +170,7 @@srcfd = Open(filename, O_RDONLY, 0); //line:netp:servestatic:opensrcp = Mmap(0, filesize, PROT_READ, MAP_PRIVATE, srcfd, 0);//line:netp:servestatic:mmapClose(srcfd); //line:netp:servestatic:close - Rio_writen(fd, srcp, filesize); //line:netp:servestatic:write + Im_rio_writen(fd, srcp, filesize); //line:netp:servestatic:writeMunmap(srcp, filesize); //line:netp:servestatic:munmap}@@ -186,11 +200,13 @@/* Return first part of HTTP response */sprintf(buf, "HTTP/1.0 200 OK\r\n"); - Rio_writen(fd, buf, strlen(buf)); + Im_rio_writen(fd, buf, strlen(buf));sprintf(buf, "Server: Tiny Web Server\r\n"); - Rio_writen(fd, buf, strlen(buf)); + Im_rio_writen(fd, buf, strlen(buf));if (Fork() == 0) { /* Child */ //line:netp:servedynamic:fork + if (Signal(SIGPIPE, SIG_DFL) == SIG_ERR) + unix_error("unmask signal pipe error");/* Real server would set all CGI vars here */setenv("QUERY_STRING", cgiargs, 1); //line:netp:servedynamic:setenvDup2(fd, STDOUT_FILENO); /* Redirect stdout to client */ //line:netp:servedynamic:dup2 @@ -216,10 +232,10 @@/* Print the HTTP response */sprintf(buf, "HTTP/1.0 %s %s\r\n", errnum, shortmsg); - Rio_writen(fd, buf, strlen(buf)); + Im_rio_writen(fd, buf, strlen(buf));sprintf(buf, "Content-type: text/html\r\n"); - Rio_writen(fd, buf, strlen(buf)); + Im_rio_writen(fd, buf, strlen(buf));sprintf(buf, "Content-length: %d\r\n\r\n", (int)strlen(body)); - Rio_writen(fd, buf, strlen(buf)); - Rio_writen(fd, body, strlen(body)); + Im_rio_writen(fd, buf, strlen(buf)); + Im_rio_writen(fd, body, strlen(body));}第十一章 完
總結(jié)
以上是生活随笔為你收集整理的《CSAPP》(第3版)答案(第十一章)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Thinkpad X201i笔记本电脑开
- 下一篇: 情绪管理---第二课:情绪包含四方面的反