summaryrefslogtreecommitdiff
path: root/app/v3_c/src/myhttpd.c
diff options
context:
space:
mode:
Diffstat (limited to 'app/v3_c/src/myhttpd.c')
-rw-r--r--app/v3_c/src/myhttpd.c94
1 files changed, 81 insertions, 13 deletions
diff --git a/app/v3_c/src/myhttpd.c b/app/v3_c/src/myhttpd.c
index 1e0c3e8..9d77949 100644
--- a/app/v3_c/src/myhttpd.c
+++ b/app/v3_c/src/myhttpd.c
@@ -2,25 +2,44 @@
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
-
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <errno.h>
+#include <unistd.h>
+#include <signal.h>
#include "myhttpd.h"
+#include "process.h"
#include "utils.h"
+int end=0;
+
+void signals(int signum) {
+ static int force=0;
+
+ if (0) printf("signal %i\n");
+
+ if(!force) {
+ end=1;
+ force=1;
+ logs("Tentative d'arrêt soft du serveur...");
+ } else {
+ logs("Arrêt d'urgence du serveur");
+ exit(1);
+ }
+}
+
+
int main() {
int res;
int sockServ, sockCli;
struct sockaddr_in servAddr, cliAddr;
- size_t cliAddrLen;
- int ending;
+ socklen_t cliAddrLen;
// Création socket
sockServ = socket(AF_INET, SOCK_STREAM, 0);
- if (sockServ < 0) { perror("socket"); exit(1); }
+ if (sockServ < 0) { perror("socket"); return(2); }
// Accrochage du socket (adresse et port locaux)
bzero((char *) &servAddr, sizeof(servAddr));
@@ -28,21 +47,70 @@ int main() {
servAddr.sin_addr.s_addr = INADDR_ANY;
servAddr.sin_port = htons(LISTEN_PORT);
res=bind(sockServ, (struct sockaddr *) &servAddr, sizeof(servAddr));
- if (res < 0) { perror("bind"); exit(2); }
+ if (res < 0) { perror("bind"); return(3); }
- // On la:nce l'écoute
+ // On lance l'écoute
listen(sockServ,LISTEN_BACKLOG);
- if (res < 0) { perror("listen"); exit(3); }
+ if (res < 0) { perror("listen"); return(4); }
+
+ // On active la gestion des signaux
+ signal(2,signals);
+
+ res=initProcess();
+ if (res != 0 ) {
+#ifdef DEBUG
+ logs("initProcess() error");
+#endif
+ return(5);
+ }
// Boucle d'acceptation des clients
cliAddrLen = sizeof(cliAddr);
- ending=0;
- while ( ! ending ) {
+ while ( ! end ) {
+ // Appel bloquant d'acceptation d'un nouveau client
sockCli=accept(sockServ, (struct sockaddr *) &cliAddr, &cliAddrLen);
- #ifdef DEBUG
- logs("Client accepté");
- #endif
-
+
+ // Il y plein de raisons pour qu'un accept echoue
+ if (sockCli < 0) {
+ switch(errno) {
+ case EAGAIN:
+ case EINTR:
+ // Cas qui ne sont pas des erreurs, mais nécessitent de rappeler accept
+#ifdef DEBUG
+ perror("accept (info)");
+#endif
+ break;
+ case EMFILE:
+ case ENFILE:
+ case ENOBUFS:
+ case ENOMEM:
+ // Cas d'erreur transitoire (attente d'une seconde histoire d'attendre un peu si ressources fichiers, ram épuisés
+#ifdef DEBUG
+ perror("accept (warn)");
+ sleep(1);
+#endif
+ break;
+ default:
+ // Cas d'erreur fatales
+ perror("accept (err)");
+ end=2;
+ }
+ } else {
+ // Cas nominal : un nouveau socket est disponible avec un client au bout
+#ifdef HEAVYDEBUG
+ logs("Client accepté");
+#endif
+ end=requestProcess(sockCli, &cliAddr, &cliAddrLen);
+ }
+ }
+
+ freeProcess();
+
+ if ( end != 1 ) {
+#ifdef DEBUG
+ logs("Fin anormale du serveur");
+#endif
+ return(6);
}
return 0;