void dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen) { int icmpfd, maxfdp1; char sendline[MAXLINE], recvline[MAXLINE + 1]; fd_set rset; ssize_t n; struct timeval tv; struct icmpd_err icmpd_err; struct sockaddr_un sun; Sock_bind_wild(sockfd, pservaddr->sa_family); icmpfd = Socket(AF_LOCAL, SOCK_STREAM, 0); sun.sun_family = AF_LOCAL; strcpy(sun.sun_path, ICMPD_PATH); Connect(icmpfd, (SA *)&sun, sizeof(sun)); Write_fd(icmpfd, "1", 1, sockfd); n = Read(icmpfd, recvline, 1); if (n != 1 || recvline[0] != '1') err_quit("error creating icmp socket, n = %d, char = %c", n, recvline[0]); FD_ZERO(&rset); maxfdp1 = max(sockfd, icmpfd) + 1; while (Fgets(sendline, MAXLINE, fp) != NULL) { Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen); tv.tv_sec = 5; tv.tv_usec = 0; FD_SET(sockfd, &rset); FD_SET(icmpfd, &rset); if ((n = Select(maxfdp1, &rset, NULL, NULL, &tv)) == 0) { fprintf(stderr, "socket timeout\n"); continue; } if (FD_ISSET(sockfd, &rset)) { n = Recvfrom(sockfd, recvline, MAXLINE, 0, NULL, NULL); recvline[n] = 0; Fputs(recvline, stdout); } if (FD_ISSET(icmpfd, &rset)) { if ((n = Read(icmpfd, &icmpd_err, sizeof(icmpd_err))) == 0) err_quit("ICMP daemon terminate"); else if (n != sizeof(icmpd_err)) err_quit("n = %d, expected %d", n, sizeof(icmpd_err)); printf("ICMP error: dest = %s, %s, type = %d," " code = %d\n", Sock_ntop((SA *)&icmpd_err.icmpd_dest, icmpd_err.icmpd_len), strerror(icmpd_err.icmpd_errno), icmpd_err.icmpd_type, icmpd_err.icmpd_code); } } }
int main(int argc, char **argv) { int listenfd, i, navail, maxfd, nsel, connfd, rc; void sig_int(int); pid_t child_make(int, int, int); ssize_t n; fd_set rset, masterset; socklen_t addrlen, clilen; struct sockaddr *cliaddr; if (argc == 3) listenfd = Tcp_listen(NULL, argv[1], &addrlen); else if (argc == 4) listenfd = Tcp_listen(argv[1], argv[2], &addrlen); else err_quit("usage: serv05 [ <host> ] <port#> <#children>"); FD_ZERO(&masterset); FD_SET(listenfd, &masterset); maxfd = listenfd; cliaddr = Malloc(addrlen); nchildren = atoi(argv[argc-1]); navail = nchildren; cptr = Calloc(nchildren, sizeof(Child)); /* 4prefork all the children */ for (i = 0; i < nchildren; i++) { child_make(i, listenfd, addrlen); /* parent returns */ FD_SET(cptr[i].child_pipefd, &masterset); maxfd = max(maxfd, cptr[i].child_pipefd); } Signal(SIGINT, sig_int); for ( ; ; ) { rset = masterset; if (navail <= 0) FD_CLR(listenfd, &rset); /* turn off if no available children */ nsel = Select(maxfd, &rset, NULL, NULL, NULL); /* 4check for new connections */ if (FD_ISSET(listenfd, &rset)) { clilen = addrlen; connfd = Accept(listenfd, cliaddr, &clilen); for (i = 0; i < nchildren; i++) if (cptr[i].child_status == 0) break; /* available */ if (i == nchildren) err_quit("no available children"); cptr[i].child_status = 1; /* mark child as busy */ cptr[i].child_count++; navail--; n = Write_fd(cptr[i].child_pipefd, "", 1, connfd); Close(connfd); if (--nsel == 0) continue; /* all done with select() results */ } /* 4find any newly-available children */ for (i = 0; i < nchildren; i++) { if (FD_ISSET(cptr[i].child_pipefd, &rset)) { if ( (n = Read(cptr[i].child_pipefd, &rc, 1)) == 0) err_quit("child %d terminated unexpectedly", i); cptr[i].child_status = 0; navail++; if (--nsel == 0) break; /* all done with select() results */ } } } }
int main(int argc, char* argv[]) { int listenfd, i, navail, maxfd, nsel, connfd, rc; void sig_int(int); pid_t child_make(int,int,int); ssize_t n; fd_set rset, masterset; socklen_t addrlen,clilen; struct sockaddr* cliaddr; listenfd = Tcp_listen(argv[1], argv[2], &addrlen); FD_ZERO(&masterset); FD_SET(listenfd, &masterset); maxfd = listenfd; cliaddr = Malloc(addrlen); nchildren = atoi(argv[argc - 1]); navail = nchildren; cptr = Calloc(nchildren, sizeof(Child)); for (i = 0; i < nchildren; ++i) { child_make(i, listenfd, addrlen); FD_SET(cptr[i].child_pipefd, &masterset); maxfd = max(maxfd, cptr[i].child_pipefd); } Signal(SIGINT, sig_int); for(;;){ rset = masterset ; if(navail <= 0) FD_CLR(listenfd, &rset); nsel = Select(maxfd+1, &rset, NULL, NULL, NULL); if(FD_ISSET(listenfd, &rset)){ clilen = addrlen; connfd = Accept(listenfd, cliaddr, &clilen); for (i = 0; i < nchildren; ++i) { if(cptr[i].child_status == 0) break; } if(i == nchildren) err_quit("no available children"); cptr[i].child_status = 1; cptr[i].child_count++; navail--; n = Write_fd(cptr[i].child_pipefd, "", 1, connfd); Close(connfd); if(--nsel==0) continue; } for(i = 0; i <nchildren ;++i){ if(FD_ISSET(cptr[i].child_pipefd, &rset)){ if((n = Read(cptr[i].child_pipefd, &rc, 1)) == 0){ err_quit("child %d terminated unexpectd",i); } cptr[i].child_status = 0; navail++; if(--nsel ==0)break; } } } }