#include "Include/server.h"
#include <fcntl.h>
#include <sys/stat.h>
#include "common.h"
#include "comandi.h"
#include "lista.h"
#include "../../../Fat/Src/Include/fat.h"
#include "../../../Fat/Src/Include/load_fat.h"
Vai al codice sorgente di questo file.
Funzioni | |
int | main (int argc, char **argv) |
void | gestore (int sig) |
This program is free software; you can redistribuite it and/or modify it under the terms of the GNU/General Pubblic License as published the Free software Foundation; either version 2 of the License, or (at your opinion) any later version.
Definizione nel file server.c.
int main | ( | int | argc, | |
char ** | argv | |||
) |
Main / Dispather
Definizione alla linea 30 del file server.c.
00030 { 00031 extern FILE * fs; 00032 extern struct fat_ctrl f_ctrl; 00033 extern int num_threads; 00034 extern pthread_mutex_t lock; 00035 extern serverChannel_t sk_ascolto; 00036 extern struct lista my_socket; 00037 struct sigaction action; 00038 pthread_attr_t pta; 00039 pthread_t tid=0; 00040 sigset_t set; 00041 channel_t sk_cl; 00042 char * path; 00043 struct stat buf; 00044 int err; 00045 00046 path = NULL; fs = NULL; f_ctrl.fat_ptr = NULL; 00047 sk_ascolto = 0; num_threads = 0; quitflag = 0; 00048 00049 /* ========= Gestione dei segnali ========= */ 00050 /* Blocco i segnali */ 00051 if (sigfillset(&set) == -1){ 00052 errore(__FILE__,__LINE__,"Server: error sigfillset",errno); 00053 return EXIT_FAILURE; 00054 } 00055 if (pthread_sigmask(SIG_SETMASK, &set, NULL) != 0) { 00056 errore(__FILE__,__LINE__,"Server: pthread_sigmask error 'sigsetmask'",errno); 00057 return EXIT_FAILURE; 00058 } 00059 /* Installo il nuovo gestore */ 00060 memset(&action, sizeof(action), 0); 00061 if (sigemptyset(&action.sa_mask) == -1){ 00062 errore(__FILE__,__LINE__,"Server: error sigemptyset",errno); 00063 return EXIT_FAILURE; 00064 } 00065 /* Ignoro il SIGPIPE */ 00066 action.sa_handler = SIG_IGN; 00067 if (sigaction(SIGPIPE, &action, NULL) == -1) { 00068 errore(__FILE__,__LINE__, "Server: sigaction error 'SIGPIPE'", errno); 00069 exit(EXIT_FAILURE); 00070 } 00071 action.sa_handler = gestore; 00072 action.sa_flags = 0; 00073 /* Definisco i segnali che voglio gestire */ 00074 if (sigaction(SIGINT, &action, NULL) < 0){ 00075 errore(__FILE__,__LINE__,"Server: sigaction error 'SIGINT'",errno); 00076 return EXIT_FAILURE; 00077 } 00078 if (sigaction(SIGTERM, &action, NULL) < 0){ 00079 errore(__FILE__,__LINE__,"Server: sigaction error 'SIGTERM'",errno); 00080 return EXIT_FAILURE;; 00081 } 00082 /* Installo la nuova maschera dei segnali */ 00083 if (pthread_sigmask(SIG_SETMASK, &action.sa_mask, NULL) != 0) { 00084 errore(__FILE__,__LINE__,"Server: pthread_sigmask error 'sigsetmask'",errno); 00085 return EXIT_FAILURE; 00086 } 00087 00088 /* ========= Filesystem ========= */ 00089 /* Argomento da riga di comando */ 00090 if (argc<2) { 00091 fprintf(stderr,"Server: errore non e' stato passato alcun filesystem\n"); 00092 return EXIT_FAILURE; 00093 } 00094 /* Esiste il file? */ 00095 if (lstat(argv[1], &buf) < 0) { 00096 errore(__FILE__,__LINE__, "Server: error filesystem",errno); 00097 return EXIT_FAILURE; 00098 } 00099 /* E' un file regolare? */ 00100 if (!(S_ISREG(buf.st_mode))) { 00101 fprintf(stderr,"Server: error %s is not a regular file\n",argv[1]); 00102 return EXIT_FAILURE; 00103 } 00104 /* Apro in lettura e scrittura il filesystem */ 00105 if (!(fs = fopen(argv[1], "r+"))) { 00106 errore(__FILE__,__LINE__, "Server: error on open filesystem",errno); 00107 return EXIT_FAILURE; 00108 } 00109 /* Monto il filesystem */ 00110 if ((err = mount_fat(fs, &f_ctrl)) != 0){ fclose(fs); return err; } 00111 00112 /* ========= Attributi dei thread ========= */ 00113 if (pthread_attr_init(&pta)!=0) { 00114 errore(__FILE__,__LINE__,"Server: error pthread_attr_init",errno); 00115 fclose(fs); 00116 return EXIT_FAILURE; 00117 } 00118 /* I nuovi thread che andro' a creare saranno' gia' nello stato 'DETACHED' */ 00119 if (pthread_attr_setdetachstate(&pta, PTHREAD_CREATE_DETACHED)!=0) { 00120 errore(__FILE__,__LINE__,"Server: error pthread_attr_setdetachstate",errno); 00121 fclose(fs); pthread_attr_destroy(&pta); 00122 return EXIT_FAILURE; 00123 } 00124 00125 /* Inizializzo la lista dei thread */ 00126 inizializza (&my_socket); 00127 00128 /* ========= Socket ========= */ 00129 if (!(path = calloc((strlen(TMP) + strlen(SKTNAME) + 1), sizeof(char)))) { 00130 errore(__FILE__,__LINE__, "Server: error on allocate memory for 'path'",errno); 00131 free(f_ctrl.fat_ptr); fclose(fs); pthread_attr_destroy(&pta); 00132 return EXIT_FAILURE; 00133 } 00134 strncpy(path,TMP,strlen(TMP)); 00135 strncat(path,SKTNAME,strlen(SKTNAME)); 00136 if ((lstat(path, &buf) == 0) && (unlink(path) < 0)) 00137 errore(__FILE__,__LINE__,"Server: socket unlink",errno); 00138 /* Creo la socket di ascolto del server */ 00139 if ((sk_ascolto = createServerChannel(path)) == -1) exit(-1); 00140 else if (sk_ascolto == SFATENAMETOOLONG) { 00141 fprintf(stderr,"Error Path Too Long (exceeding UNIX_PATH_MAX)\n"); 00142 free(f_ctrl.fat_ptr); free(path); fclose(fs); pthread_attr_destroy(&pta); 00143 return EXIT_FAILURE; 00144 } 00145 00146 /* ========= Ciclo di ascolto delle richieste ========= */ 00147 while (!quitflag) { 00148 /* Pongo il server in attesa di nuove connessioni da parte dei client */ 00149 if ((sk_cl = acceptConnection(sk_ascolto)) < 0) break; 00150 else { 00151 /* Solo se non ho gia' raggiunto il numero massimo di thread fissato */ 00152 pthread_mutex_lock(&lock); 00153 while (num_threads == THREAD_MAX) 00154 pthread_cond_wait(&wait_me, &lock); 00155 /* Creo un nuovo elemento della lista dei socket. 00156 * Il nuovo elemento verra' inserito alla testa della lista */ 00157 num_threads++; 00158 if (ins_new_elem(sk_cl, &my_socket)) break; 00159 pthread_mutex_unlock(&lock); 00160 /* Creo un nuovo thread */ 00161 if (pthread_create(&tid, &pta, thread_servernte, 00162 &(my_socket.top_elem->sk_cl))) { 00163 errore(__FILE__,__LINE__, "Server: error pthread_create",errno); 00164 break; 00165 } 00166 } 00167 } 00168 00169 /* Aspetto la chiusura di ogni thread aperto */ 00170 pthread_mutex_lock(&lock); 00171 while (num_threads != 0) 00172 pthread_cond_wait(&wait_me, &lock); 00173 pthread_mutex_unlock(&lock); 00174 00175 /* Chiudo la socket del server */ 00176 closeSocket(sk_ascolto); 00177 00178 /* Elimino la socket dal filesystem (se esiste) */ 00179 if ((lstat(path, &buf) == 0) && (unlink(path) < 0)) 00180 errore(__FILE__,__LINE__,"Server: socket unlink",errno); 00181 00182 /* Libero le risorse allocate */ 00183 free(path); free(f_ctrl.fat_ptr); fclose(fs); pthread_attr_destroy(&pta); 00184 00185 exit(EXIT_FAILURE); 00186 }
void gestore | ( | int | sig | ) |
Il mio gestore dei segnali
Stampa a monitor il codice del segnale ricevuto se questo e' SIGTERM o SIGINT e mette quitflag a 1, altrimenti se e' un SIGPIPE non fa nulla.
sig | codice del segnale ricevuto |