#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include int parser(int len, char *command, queueT *queue, long fd_c, taglia_t* taglia, pthread_mutex_t *lock, waiting_t **waiting); // funzione eseguita dal Worker thread del pool void threadF(void *arg) { if(!arg){ errno = EINVAL; return; } threadT *argl = (threadT *) arg; int connfd = *argl->connfd; volatile int *quit = argl->quit; int request_pipe = argl->request_pipe; queueT *q = argl->q; taglia_t *taglia = argl->taglia; // threadpool_t *pool = argl->pool; pthread_mutex_t *lock = argl->lock; waiting_t **waiting = argl->waiting; fd_set set, tmpset; FD_ZERO(&set); FD_SET(connfd, &set); while(*quit == 0) { tmpset=set; int r; // ogni tanto controllo se devo terminare struct timeval timeout={0, 100000}; // 100 milliseconds if ((r=select(connfd+1, &tmpset, NULL, NULL, &timeout)) < 0) { perror("Select"); break; } if (r==0) { if (*quit) goto _cleanup; continue; } break; // r!=0 and quit==0 } // comunicate with the client msg_t str; long n; // leggo la dimensione del messaggio if ((n=readn(connfd, &str.len, sizeof(long))) == -1) { perror("read1"); goto _cleanup; } if (n==0) goto _cleanup;; str.str = calloc(str.len+1, sizeof(char)); if (!str.str) { perror("calloc"); fprintf(stderr, "Calloc.\n"); goto _cleanup; } // leggo il messaggio if ((n=readn(connfd, str.str, str.len * sizeof(char))) == -1) { perror("read2"); free(str.str); goto _cleanup; } str.str[str.len] = '\0'; if(strncmp(str.str, "quit", 5)) { // il client vuole chiudere la connessione close(connfd); int close = -1; // comunico al manager che ho chiuso la connessione if (writen(request_pipe, &close, sizeof(int)) == -1) { perror("writen"); goto _cleanup; } // log chiusura connessione int n = 0; char buf[1024]; n = snprintf(buf, sizeof(buf), "Chiusa connessione con il client %d.\n", connfd); if( n<0 ) { perror("snprintf"); goto _cleanup; } if( taglia_log(taglia, buf) < 0 ) goto _cleanup; goto _cleanup; } // eseguo quello che mi chiede il client di fare if (parser(str.len, str.str, q, connfd, taglia, lock, waiting) == -1) { goto _cleanup; } // str.str non è più valido perchè parser fa free // comunico al manager che è stata servita la richiesta if (writen(request_pipe, &connfd, sizeof(int)) == -1) { perror("writen"); } // log int m = 0; char buf[1024]; m = snprintf(buf, sizeof(buf), "Servito una richiesta del client %d.\n", connfd); if( m<0 ) { perror("snprintf"); goto _cleanup; } if( taglia_log(taglia, buf) < 0 ) goto _cleanup; return; _cleanup: // nothing to do because no memory needs to be freed return; } int parser(int len, char *command, queueT *queue, long fd_c, taglia_t* taglia, pthread_mutex_t *lock, waiting_t **waiting) { if(len<0 || !command || !queue || !taglia || !waiting) { errno = EINVAL; return -1; } char *string = calloc(1, len); if(string == NULL) { perror("calloc"); return -1; } strncpy(string, command, len-1); // strlcpy is only bsd :( string[len-1] = '\0'; char *token = NULL; char *token2 = NULL; char *token3 = NULL; token = strsep(&string, "|"); token2 = strsep(&string, "|"); token3 = strsep(&string, "|"); if(!token) goto _parser_cleanup; if(strcmp(token, "openFile") == 0) { if(!token3 || !token2) goto _parser_cleanup; int arg = (int) strtol(token3, NULL, 10); openFile(token2, arg, queue, fd_c, taglia); goto _parser_end; } if (strcmp(token, "readFile") == 0) { if(!token2) goto _parser_cleanup; readFile(token2, queue, fd_c, taglia); goto _parser_end; } if (strcmp(token, "readNFiles") == 0) { if(!token2) goto _parser_cleanup; int n = (int) strtol(token2, NULL, 10); readNFiles(n, queue, fd_c, taglia); goto _parser_end; } if (strcmp(token, "writeFile") == 0) { if(!token3 || !token2) goto _parser_cleanup; size_t sz = (size_t) strtol(token3, NULL, 10); writeFile(token2, sz, queue, fd_c, taglia, 0); goto _parser_end; } if (strcmp(token, "appendToFile") == 0) { if(!token3 || !token2) goto _parser_cleanup; size_t sz = (size_t) strtol(token3, NULL, 10); writeFile(token2, sz, queue, fd_c, taglia, 1); goto _parser_end; } if (strcmp(token, "lockFile") == 0) { if(!token2) goto _parser_cleanup; lockFile(token2, queue, fd_c, taglia, lock, waiting); goto _parser_end; } if (strcmp(token, "unlockFile") == 0) { if(!token2) goto _parser_cleanup; unlockFile(token2, queue, fd_c, taglia, lock, waiting); goto _parser_end; } if (strcmp(token, "closeFile") == 0) { if(!token2) goto _parser_cleanup; closeFile(token2, queue, fd_c, taglia, lock, waiting); goto _parser_end; } if (strcmp(token, "removeFile") == 0) { if(!token2) goto _parser_cleanup; removeFile(token2, queue, fd_c, taglia, lock, waiting); goto _parser_end; } // se arrivo qui non ho riconosciuto il comando _parser_cleanup: free(command); return -1; _parser_end: free(command); return 0; }