1 /* srltest.c */
2 
3 #include <unistd.h>
4 #include <sys/types.h>
5 #include <sys/time.h>
6 #include <sys/socket.h>
7 #include <sys/wait.h>
8 #include <netinet/in.h>
9 #include <arpa/inet.h>
10 #include <errno.h>
11 #include <stdio.h>
12 #include <string.h>
13 #include <stdlib.h>
14 #include <time.h>
15 #include <ctype.h>
16 #ifdef CAN_USE_SYS_SELECT_H
17 #	include <sys/select.h>
18 #endif
19 
20 #include "sio.h"
21 
22 static void
ServeOneClient(int sockfd,struct sockaddr_in * cliAddr)23 ServeOneClient(int sockfd, struct sockaddr_in *cliAddr)
24 {
25 	char buf[80], cliAddrStr[64];
26 	char bbuf[320];
27 	int nread, nwrote, i;
28 	SReadlineInfo srl;
29 
30 	printf("subserver[%d]: started, connected to %s.\n", (int) getpid(),
31 		AddrToAddrStr(cliAddrStr, sizeof(cliAddrStr), cliAddr, 1, "<%h:%p>")
32 	);
33 
34 	if (InitSReadlineInfo(&srl, sockfd, bbuf, sizeof(bbuf), 5) < 0) {
35 		fprintf(stderr, "subserver[%d]: InitSReadlineInfo error: %s\n",
36 			(int) getpid(), strerror(errno));
37 		exit(1);
38 	}
39 	for (;;) {
40 		nread = SReadline(&srl, buf, sizeof(buf));
41 		if (nread == 0) {
42 			break;
43 		} else if (nread == kTimeoutErr) {
44 			printf("subserver[%d]: idle\n", (int) getpid());
45 			continue;
46 		} else if (nread < 0) {
47 			fprintf(stderr, "subserver[%d]: read error: %s\n",
48 				(int) getpid(), strerror(errno));
49 			break;
50 		}
51 		for (i=0; i<nread; i++)
52 			if (islower(buf[i]))
53 				buf[i] = toupper(buf[i]);
54 		nwrote = SWrite(sockfd, buf, nread, 15);
55 		if (nwrote < 0) {
56 			fprintf(stderr, "subserver[%d]: write error: %s\n",
57 				(int) getpid(), strerror(errno));
58 			break;
59 		}
60 	}
61 	(void) SClose(sockfd, 10);
62 	printf("subserver[%d]: done.\n", (int) getpid());
63 	exit(0);
64 }	/* ServeOneClient */
65 
66 
67 
68 static void
Server(int port)69 Server(int port)
70 {
71 	int sockfd, newsockfd;
72 	struct sockaddr_in cliAddr;
73 	int pid;
74 
75 	sockfd = SNewStreamServer(port, 3, kReUseAddrYes, 3);
76 	if (sockfd < 0) {
77 		perror("Server setup failed");
78 		exit(1);
79 	}
80 
81 	printf("server[%d]: started.\n", (int) getpid());
82 	for(;;) {
83 		while (waitpid(-1, NULL, WNOHANG) > 0) ;
84 		newsockfd = SAccept(sockfd, &cliAddr, 5);
85 		if (newsockfd < 0) {
86 			if (newsockfd == kTimeoutErr)
87 				printf("server[%d]: idle\n", (int) getpid());
88 			else
89 				fprintf(stderr, "server[%d]: accept error: %s\n",
90 					(int) getpid(), strerror(errno));
91 		} else if ((pid = fork()) < 0) {
92 			fprintf(stderr, "server[%d]: fork error: %s\n",
93 				(int) getpid(), strerror(errno));
94 			exit(1);
95 		} else if (pid == 0) {
96 			ServeOneClient(newsockfd, &cliAddr);
97 			exit(0);
98 		} else {
99 			/* Parent doesn't need it now. */
100 			(void) close(newsockfd);
101 		}
102 	}
103 }	/* Server */
104 
105 
106 void
main(int argc,char ** argv)107 main(int argc, char **argv)
108 {
109 	int port;
110 
111 	if (argc < 2) {
112 		fprintf(stderr, "Usage: %s <port>\n", argv[0]);
113 		exit(2);
114 	}
115 	port = atoi(argv[1]);
116 	Server(port);
117 	exit(0);
118 }	/* main */
119