*
* Usage: echod -h give all info
*
- * $Id: select_echod.c,v 1.1 2003/12/25 17:31:09 piccardi Exp $
- *
****************************************************************/
/*
* Include needed headers
*/
-#include <sys/types.h> /* predefined types */
-#include <unistd.h> /* include unix standard library */
-#include <arpa/inet.h> /* IP addresses conversion utiliites */
-#include <sys/socket.h> /* socket library */
-#include <stdio.h> /* include standard I/O library */
-#include <time.h>
+#include <sys/types.h> /* primitive system data types */
+#include <unistd.h> /* unix standard library */
+#include <arpa/inet.h> /* IP addresses conversion utilities */
+#include <sys/socket.h> /* socket constants, types and functions */
+#include <stdio.h> /* standard I/O library */
+#include <time.h> /* date and time constants, types and functions */
#include <syslog.h> /* syslog system functions */
-#include <signal.h> /* signal functions */
-#include <errno.h> /* error code */
-#include <string.h> /* error strings */
-#include <stdlib.h>
+#include <signal.h> /* signal constants, types and functions */
+#include <errno.h> /* error definitions and routines */
+#include <string.h> /* C strings library */
+#include <stdlib.h> /* C standard library */
+#include "macros.h"
#include "Gapil.h"
#define BACKLOG 10
*/
int waiting = 0;
int compat = 0;
- struct sockaddr_in serv_add, cli_add;
+ struct sockaddr_in s_addr, c_addr;
socklen_t len;
char buffer[MAXLINE];
char fd_open[FD_SETSIZE];
exit(1);
}
/* initialize address */
- memset((void *)&serv_add, 0, sizeof(serv_add)); /* clear server address */
- serv_add.sin_family = AF_INET; /* address type is INET */
- serv_add.sin_port = htons(7); /* echo port is 7 */
- serv_add.sin_addr.s_addr = htonl(INADDR_ANY); /* connect from anywhere */
+ memset((void *)&s_addr, 0, sizeof(s_addr)); /* clear server address */
+ s_addr.sin_family = AF_INET; /* address type is INET */
+ s_addr.sin_port = htons(7); /* echo port is 7 */
+ s_addr.sin_addr.s_addr = htonl(INADDR_ANY); /* connect from anywhere */
/* bind socket */
- if (bind(list_fd, (struct sockaddr *)&serv_add, sizeof(serv_add)) < 0) {
+ if (bind(list_fd, (struct sockaddr *)&s_addr, sizeof(s_addr)) < 0) {
perror("bind error");
exit(1);
}
if (waiting) sleep(waiting);
/* initialize all needed variables */
memset(fd_open, 0, FD_SETSIZE); /* clear array of open files */
- max_fd = list_fd; /* set maximum fd to look */
+ max_fd = list_fd; /* maximum now is listening socket */
fd_open[max_fd] = 1;
/* main loop, wait for connection and data inside a select */
while (1) {
FD_ZERO(&fset); /* clear fd_set */
- for (i = list_fd; i <= max_fd; i++) {
- if (fd_open[i]) FD_SET(i, &fset); /* initialize open sockets */
+ for (i = list_fd; i <= max_fd; i++) { /* initialize fd_set */
+ if (fd_open[i] != 0) FD_SET(i, &fset);
}
while ( ((n = select(max_fd + 1, &fset, NULL, NULL, NULL)) < 0)
- && (errno == EINTR));
- /* there are data */
- if (n < 0) {
+ && (errno == EINTR)); /* wait for data or connection */
+ if (n < 0) { /* on real error exit */
PrintErr("select error");
exit(1);
- }
- if (FD_ISSET(list_fd, &fset)) { /* if data on listening socket */
- len = sizeof(cli_add);
- fd = accept(list_fd, (struct sockaddr *)&cli_add, &len);
- if (fd < 0) {
+ }
+ /* on activity */
+ debug("Trovati %d socket attivi\n", n);
+ if (FD_ISSET(list_fd, &fset)) { /* if new connection */
+ n--; /* decrement active */
+ len = sizeof(c_addr); /* and call accept */
+ if ((fd = accept(list_fd, (struct sockaddr *)&c_addr, &len)) < 0) {
PrintErr("accept error");
exit(1);
}
- fd_open[fd] = 1;
- if (max_fd < fd) max_fd = fd;
- FD_SET(fd, &fset);
- n--;
+ debug("Connessione su fd %d restano %d socket attivi\n", fd, n);
+ fd_open[fd] = 1; /* set new connection socket */
+ if (max_fd < fd) max_fd = fd; /* if needed set new maximum */
+ debug("max_fd=%d\n", max_fd);
}
- for (i = list_fd + 1; i <= max_fd; i++) {
- if (fd_open[i] == 0) continue;
- if (FD_ISSET(i, &fset)) {
- n--;
- nread = read(fd, buffer, MAXLINE);
+ /* loop on open connections */
+ i = list_fd; /* first socket to look */
+ while (n != 0) { /* loop until active */
+ i++; /* start after listening socket */
+ debug("restano %d socket, fd %d\n", n, fd);
+ if (fd_open[i] == 0) continue; /* closed, go next */
+ if (FD_ISSET(i, &fset)) { /* if active process it*/
+ n--; /* decrease active */
+ debug("dati su fd %d\n", i);
+ nread = read(i, buffer, MAXLINE); /* read operations */
if (nread < 0) {
PrintErr("Errore in lettura");
exit(1);
}
- if (nread == 0) {
- fd_open[i] = 0;
- if (max_fd == i) {
- while (fd_open[i] == 0) {
- i--;
- }
- max_fd = i;
- break;
+ if (nread == 0) { /* if closed connection */
+ debug("fd %d chiuso\n", i);
+ close(i); /* close file */
+ fd_open[i] = 0; /* mark as closed in table */
+ if (max_fd == i) { /* if was the maximum */
+ while (fd_open[--i] == 0); /* loop down */
+ max_fd = i; /* set new maximum */
+ debug("nuovo max_fd %d\n", max_fd);
+ break; /* and go back to select */
}
- continue;
+ continue; /* continue loop on open */
}
- nwrite = FullWrite(fd, buffer, nread);
+ nwrite = FullWrite(i, buffer, nread); /* write data */
if (nwrite) {
PrintErr("Errore in scrittura");
exit(1);
}
}
}
- if (n != 0) {
- PrintErr("Errore nella gestione dei file descriptor");
- }
}
/* normal exit, never reached */
exit(0);