LCA2011 version
[tridge/junkcode.git] / blocking.c
1 #include <sys/time.h>
2 #include <sys/types.h>
3 #include <stdio.h>
4 #include <unistd.h>
5 #include <fcntl.h>
6 #include <errno.h>
7 #include <sys/socket.h>
8 #include <netinet/in.h>
9 #include <netdb.h>
10
11 #define PORT 8999
12
13 int open_socket_out(char *host, int port)
14 {
15         int type = SOCK_STREAM;
16         struct sockaddr_in sock_out;
17         int res;
18         struct hostent *hp;
19
20         res = socket(PF_INET, type, 0);
21         if (res == -1) {
22                 return -1;
23         }
24
25         hp = gethostbyname(host);
26         if (!hp) {
27                 fprintf(stderr,"unknown host: %s\n", host);
28                 close(res);
29                 return -1;
30         }
31
32         memcpy(&sock_out.sin_addr, hp->h_addr, hp->h_length);
33         sock_out.sin_port = htons(port);
34         sock_out.sin_family = PF_INET;
35
36         if (connect(res,(struct sockaddr *)&sock_out,sizeof(sock_out))) {
37                 fprintf(stderr,"failed to connect to %s - %s\n", host, strerror(errno));
38                 close(res);
39                 return -1;
40         }
41
42         return res;
43 }
44
45
46 static int open_socket_in(int type, int port, struct in_addr *address)
47 {
48         struct hostent *hp;
49         struct sockaddr_in sock;
50         char host_name[1000];
51         int res;
52         int one=1;
53
54         /* get my host name */
55         if (gethostname(host_name, sizeof(host_name)) == -1) { 
56                 fprintf(stderr,"gethostname failed\n"); 
57                 return -1; 
58         } 
59
60         /* get host info */
61         if ((hp = gethostbyname(host_name)) == 0) {
62                 fprintf(stderr,"gethostbyname: Unknown host %s\n",host_name);
63                 return -1;
64         }
65   
66         memset((char *)&sock,0,sizeof(sock));
67         memcpy((char *)&sock.sin_addr,(char *)hp->h_addr, hp->h_length);
68         sock.sin_port = htons(port);
69         sock.sin_family = hp->h_addrtype;
70         if (address) {
71                 sock.sin_addr = *address;
72         } else {
73                 sock.sin_addr.s_addr = INADDR_ANY;
74         }
75         res = socket(hp->h_addrtype, type, 0);
76         if (res == -1) { 
77                 fprintf(stderr,"socket failed\n"); 
78                 return -1; 
79         }
80
81         setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one));
82
83         /* now we've got a socket - we need to bind it */
84         if (bind(res, (struct sockaddr * ) &sock,sizeof(sock)) == -1) { 
85                 fprintf(stderr,"bind failed on port %d\n", port);
86                 close(res); 
87                 return -1;
88         }
89
90         return res;
91 }
92
93 void set_nonblocking(int fd)
94 {
95         unsigned v = fcntl(fd, F_GETFL, 0);
96         fcntl(fd, F_SETFL, v | O_NONBLOCK);
97 }
98
99 static void child(int fd_in)
100 {
101         int fd;
102         struct sockaddr addr;
103         int in_addrlen = sizeof(addr);
104
105         if (listen(fd_in, 5) == -1) {
106                 close(fd_in);
107                 exit(1);
108         }
109
110         fd = accept(fd_in,&addr,&in_addrlen);
111         
112         sleep(20);
113         exit(0);
114 }
115
116 static void parent(void)
117 {
118         int fd = open_socket_out("localhost", PORT);
119         fd_set fset;
120         char c=0;
121         int count=0;
122
123         set_nonblocking(fd);
124
125         while (1) {
126                 FD_ZERO(&fset);
127                 FD_SET(fd, &fset);
128                 if (select(8, NULL, &fset, NULL, NULL) == 1) {
129                         if (write(fd, &c, 1) == -1 && 
130                             (errno == EAGAIN || errno == EWOULDBLOCK)) {
131                                 printf("select returns when write would block\n");
132                                 exit(1);
133                         }
134                         count++;
135                         if (count % 1024 == 0) {
136                                 printf("%d\n", count);
137                         }
138                 }
139         }
140 }
141
142
143 int main(void)
144 {
145         int fd_in;
146
147         fd_in = open_socket_in(SOCK_STREAM, PORT, NULL);
148
149         fork() ? parent() : child(fd_in);
150
151         return 0;
152 }