--- tiny.origin.c 2017-11-09 02:57:43.651936112 +0000 +++ tiny.13.c 2017-11-09 02:57:43.651936112 +0000 @@ -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:endserve printf("Response headers:\n"); printf("%s", buf); @@ -156,7 +170,7 @@ srcfd = Open(filename, O_RDONLY, 0); //line:netp:servestatic:open srcp = Mmap(0, filesize, PROT_READ, MAP_PRIVATE, srcfd, 0);//line:netp:servestatic:mmap Close(srcfd); //line:netp:servestatic:close - Rio_writen(fd, srcp, filesize); //line:netp:servestatic:write + Im_rio_writen(fd, srcp, filesize); //line:netp:servestatic:write Munmap(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:setenv Dup2(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)); }