Server 3

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 6

C:\Users\dinar\Downloads\server-concurrent-td-connreuse (3).

c 1
1 #define _POSIX_C_SOURCE 200809L
2 #include <netdb.h>
3 #include <signal.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <unistd.h>
8 #include "rxb.h"
9 #include "utils.h"
10
11 #define MAX_REQUEST_SIZE 4096
12
13
14 void sigchld_handler(int signo)
15 {
16 int status;
17
18 (void)signo;
19
20 while(waitpid(-1, &status, WNOHANG) > 0)
21 continue;
22 }
23
24
25 int main (int argc, char *argv[])
26 {
27 int err, sd, on;
28 struct sigaction sa;
29 struct addrinfo hints, *res;
30
31 if (argc != 2) {
32 fprintf(stderr, "Usage: %s porta\n", argv[0]);
33 exit(EXIT_FAILURE);
34 }
35
36 /* Cambio semantica write su pipe/socket */
37 signal(SIGPIPE, SIG_IGN);
38
39 sigemptyset(&sa.sa_mask);
40 sa.sa_flags = SA_RESTART;
41 sa.sa_handler = sigchld_handler;
42
43 err = sigaction(SIGCHLD, &sa, NULL);
44 if (err < 0) {
45 perror("sigaction");
46 exit(EXIT_FAILURE);
47 }
48
49 memset(&hints, 0, sizeof(hints));
50 hints.ai_family = AF_UNSPEC;
51 hints.ai_socktype = SOCK_STREAM;
52 hints.ai_flags = AI_PASSIVE;
53
C:\Users\dinar\Downloads\server-concurrent-td-connreuse (3).c 2
54 err = getaddrinfo(NULL, argv[1], &hints, &res);
55 if (err != 0) {
56 fprintf(stderr, "Errore getaddrinfo: %s\n" , gai_strerror(err));
57 exit(EXIT_FAILURE);
58 }
59
60 sd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
61 if (sd < 0) {
62 perror("socket");
63 exit(EXIT_FAILURE);
64 }
65
66 on = 1;
67 err = setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
68 if (err < 0) {
69 perror("setsockopt");
70 exit(EXIT_FAILURE);
71 }
72
73 err = bind(sd, res->ai_addr, res->ai_addrlen);
74 if (err < 0) {
75 perror("bind");
76 exit(EXIT_FAILURE);
77 }
78
79 err = listen(sd, SOMAXCONN);
80 if (err < 0) {
81 perror("listen");
82 exit(EXIT_FAILURE);
83 }
84
85 freeaddrinfo(res);
86
87 while(1) {
88 int ns, pid_f;
89
90 ns = accept(sd, NULL, NULL);
91 if (ns < 0) {
92 perror("accept");
93 exit(EXIT_FAILURE);
94 }
95
96 pid_f = fork();
97 if (pid_f < 0) {
98 perror("fork");
99 exit(EXIT_FAILURE);
100 }
101
102 if (pid_f == 0) { /* FIGLIO */
103 rxb_t rxb;
104
105 rxb_init(&rxb, MAX_REQUEST_SIZE * 2);
106 signal(SIGCHLD, SIG_DFL);
C:\Users\dinar\Downloads\server-concurrent-td-connreuse (3).c 3
107
108 while (1) {
109 int pipe_n1n2[2];
110 int pid_n1, pid_n2;
111 char mese[1024];
112 char categoria[1024];
113 char numero[1024];
114 size_t mese_len, categoria_len, numero_len;
115 int status;
116 char *end_request = "--- END REQUEST ---\n";
117
118 memset(mese, 0, sizeof(mese));
119 mese_len = sizeof(mese)-1;
120
121 err = rxb_readline(&rxb, ns, mese, &mese_len);
122 if (err < 0) {
123 fputs("Errore rxb_readline!", stderr);
124 rxb_destroy(&rxb);
125 close(ns);
126 exit(EXIT_FAILURE);
127 }
128
129 #ifdef HAVE_LIBUNISTRING
130 if (u8_check((uint8_t *)mese, mese_len) != NULL) {
131 fputs("Testo non UTF-8 valido!", stderr);
132 rxb_destroy(&rxb);
133 close(ns);
134 exit(EXIT_FAILURE);
135 }
136 #endif
137
138 memset(categoria, 0, sizeof(categoria));
139 categoria_len = sizeof(categoria)-1;
140
141 err = rxb_readline(&rxb, ns, categoria, &categoria_len);
142 if (err < 0) {
143 fputs("Errore rxb_readline!", stderr);
144 rxb_destroy(&rxb);
145 close(ns);
146 exit(EXIT_FAILURE);
147 }
148
149 #ifdef HAVE_LIBUNISTRING
150 if (u8_check((uint8_t *)categoria, categoria_len) != NULL) {
151 fputs("Testo non UTF-8 valido!", stderr);
152 rxb_destroy(&rxb);
153 close(ns);
154 exit(EXIT_FAILURE);
155 }
156 #endif
157
158 memset(numero, 0, sizeof(numero));
159 numero_len = sizeof(numero)-1;
C:\Users\dinar\Downloads\server-concurrent-td-connreuse (3).c 4
160
161 err = rxb_readline(&rxb, ns, numero, &numero_len);
162 if (err < 0) {
163 fputs("Errore rxb_readline!", stderr);
164 rxb_destroy(&rxb);
165 close(ns);
166 exit(EXIT_FAILURE);
167 }
168
169 #ifdef HAVE_LIBUNISTRING
170 if (u8_check((uint8_t *)numero, numero_len) != NULL) {
171 fputs("Testo non UTF-8 valido!", stderr);
172 rxb_destroy(&rxb);
173 close(ns);
174 exit(EXIT_FAILURE);
175 }
176 #endif
177
178 if (pipe(pipe_n1n2) < 0) {
179 perror("pipe");
180 exit(EXIT_FAILURE);
181 }
182
183 pid_n1 = fork();
184 if (pid_n1 < 0) {
185 perror("fork");
186 exit(EXIT_FAILURE);
187 }
188
189 if (pid_n1 == 0) { /* NIPOTE 1 */
190 char filename[1024];
191
192 snprintf(filename, sizeof(filename),
193 /* "/var/local/expenses/%s/%s.txt", mese,
categoria); */
194 "./expenses/%s/%s.txt", mese, categoria);
195
196 /* Redirezione output su pipe */
197 close(1);
198 if (dup(pipe_n1n2[1]) < 0) {
199 perror("dup");
200 exit(EXIT_FAILURE);
201 }
202 close(pipe_n1n2[1]);
203
204 /* Chiusura estremo non usato */
205 close(pipe_n1n2[0]);
206
207 /* Chiusura socket non usata */
208 close(ns);
209
210 execlp("sort", "sort", "-r", "-n", filename, NULL);
211 perror("execlp");
C:\Users\dinar\Downloads\server-concurrent-td-connreuse (3).c 5
212 exit(EXIT_FAILURE);
213 }
214
215 pid_n2 = fork();
216 if (pid_n2 < 0) {
217 perror("fork");
218 exit(EXIT_FAILURE);
219 }
220
221 if (pid_n2 == 0) { /* NIPOTE 2 */
222 /* Redirezione input da pipe */
223 close(0);
224 if (dup(pipe_n1n2[0]) < 0) {
225 perror("dup");
226 exit(EXIT_FAILURE);
227 }
228 close(pipe_n1n2[0]);
229
230 /* Chiusura estremo non usato */
231 close(pipe_n1n2[1]);
232
233 /* Redirezione output su socket */
234 close(1);
235 if (dup(ns) < 0) {
236 perror("dup");
237 exit(EXIT_FAILURE);
238 }
239 close(ns);
240
241 execlp("head", "head", "-n", numero, NULL);
242 perror("execlp");
243 exit(EXIT_FAILURE);
244 }
245
246 /* FIGLIO */
247
248 /* Chiudo estremi pipe non usati */
249 close(pipe_n1n2[0]);
250 close(pipe_n1n2[1]);
251
252 /* Attendo terminazione nipoti */
253 waitpid(pid_n1, &status, 0);
254 waitpid(pid_n2, &status, 0);
255
256 /* Mando stringa terminazione richiesta */
257 err = write_all(ns, end_request, strlen(end_request));
258 if (err < 0) {
259 perror("write");
260 exit(EXIT_FAILURE);
261 }
262 }
263
264 exit(0);
C:\Users\dinar\Downloads\server-concurrent-td-connreuse (3).c 6
265 }
266
267 /* PADRE */
268 close(ns);
269 }
270
271 close(sd);
272
273 return 0;
274 }
275

You might also like