Files
progettoso/src/serverWorker.c

249 lines
5.5 KiB
C
Raw Normal View History

#include <stdio.h>
#include <stdlib.h>
2022-03-16 23:44:53 +01:00
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include <assert.h>
#include <sys/select.h>
#include <pthread.h>
#include <conn.h>
#include <message.h>
2022-04-04 22:31:14 +02:00
#include <fileQueue.h>
2022-03-16 23:44:53 +01:00
#include <apiFile.h>
2022-04-04 22:31:14 +02:00
#include <taglialegna.h>
2022-04-08 21:32:52 +02:00
#include <serverWorker.h>
#include <threadpool.h>
2022-04-11 18:40:32 +02:00
#include <strsep_gnu.h>
2022-04-08 21:32:52 +02:00
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) {
2022-03-16 23:44:53 +01:00
if(!arg){
errno = EINVAL;
return;
}
2022-03-12 10:05:58 +01:00
2022-04-08 21:32:52 +02:00
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;
2022-03-27 00:20:34 +01:00
2022-03-12 10:05:58 +01:00
fd_set set, tmpset;
FD_ZERO(&set);
2022-04-08 21:32:52 +02:00
FD_SET(connfd, &set);
2022-03-12 10:05:58 +01:00
2022-03-16 23:44:53 +01:00
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) {
2022-03-12 10:05:58 +01:00
perror("Select");
break;
}
if (r==0) {
2022-03-16 23:44:53 +01:00
if (*quit)
goto _cleanup;
continue;
}
2022-03-27 00:20:34 +01:00
break; // r!=0 and quit==0
2022-03-16 23:44:53 +01:00
}
2022-03-12 10:05:58 +01:00
2022-03-16 23:44:53 +01:00
// comunicate with the client
msg_t str;
long n;
2022-04-08 21:32:52 +02:00
// leggo la dimensione del messaggio
2022-03-16 23:44:53 +01:00
if ((n=readn(connfd, &str.len, sizeof(long))) == -1) {
perror("read1");
2022-04-08 21:32:52 +02:00
goto _cleanup;
2022-03-16 23:44:53 +01:00
}
2022-03-12 10:05:58 +01:00
2022-03-16 23:44:53 +01:00
if (n==0)
2022-04-08 21:32:52 +02:00
goto _cleanup;;
2022-03-16 23:44:53 +01:00
str.str = calloc(str.len+1, sizeof(char));
if (!str.str) {
perror("calloc");
fprintf(stderr, "Calloc.\n");
2022-04-08 21:32:52 +02:00
goto _cleanup;
2022-03-16 23:44:53 +01:00
}
2022-04-08 21:32:52 +02:00
// leggo il messaggio
2022-03-16 23:44:53 +01:00
if ((n=readn(connfd, str.str, str.len * sizeof(char))) == -1) {
perror("read2");
free(str.str);
2022-04-08 21:32:52 +02:00
goto _cleanup;
2022-03-16 23:44:53 +01:00
}
2022-04-08 21:32:52 +02:00
str.str[str.len] = '\0';
2022-03-16 23:44:53 +01:00
if(strncmp(str.str, "quit", 5)) { // il client vuole chiudere la connessione
2022-04-08 21:32:52 +02:00
close(connfd);
int close = -1;
2022-03-16 23:44:53 +01:00
// comunico al manager che ho chiuso la connessione
2022-04-08 21:32:52 +02:00
if (writen(request_pipe, &close, sizeof(int)) == -1) {
perror("writen");
goto _cleanup;
}
2022-03-16 23:44:53 +01:00
// log chiusura connessione
2022-04-08 21:32:52 +02:00
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;
2022-03-16 23:44:53 +01:00
goto _cleanup;
}
2022-03-16 23:44:53 +01:00
// eseguo quello che mi chiede il client di fare
2022-04-08 21:32:52 +02:00
if (parser(str.len, str.str, q, connfd, taglia, lock, waiting) == -1) {
goto _cleanup;
2022-03-16 23:44:53 +01:00
}
2022-04-08 21:32:52 +02:00
// str.str non è più valido perchè parser fa free
2022-03-16 23:44:53 +01:00
// comunico al manager che è stata servita la richiesta
2022-04-08 21:32:52 +02:00
if (writen(request_pipe, &connfd, sizeof(int)) == -1) {
perror("writen");
}
2022-03-16 23:44:53 +01:00
// log
2022-04-08 21:32:52 +02:00
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;
2022-03-16 23:44:53 +01:00
_cleanup:
2022-04-08 21:32:52 +02:00
// nothing to do because no memory needs to be freed
return;
}
2022-03-16 23:44:53 +01:00
2022-04-08 21:32:52 +02:00
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) {
2022-03-16 23:44:53 +01:00
errno = EINVAL;
return -1;
}
2022-04-08 21:32:52 +02:00
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';
2022-03-16 23:44:53 +01:00
char *token = NULL;
char *token2 = NULL;
char *token3 = NULL;
2022-04-11 18:38:04 +02:00
token = strsep_gnu(&string, "|");
token2 = strsep_gnu(&string, "|");
token3 = strsep_gnu(&string, "|");
2022-03-16 23:44:53 +01:00
if(!token)
goto _parser_cleanup;
if(strcmp(token, "openFile") == 0) {
if(!token3 || !token2)
goto _parser_cleanup;
int arg = (int) strtol(token3, NULL, 10);
2022-04-08 21:32:52 +02:00
openFile(token2, arg, queue, fd_c, taglia);
2022-03-16 23:44:53 +01:00
goto _parser_end;
}
if (strcmp(token, "readFile") == 0) {
if(!token2)
goto _parser_cleanup;
2022-04-08 21:32:52 +02:00
readFile(token2, queue, fd_c, taglia);
2022-03-16 23:44:53 +01:00
goto _parser_end;
}
if (strcmp(token, "readNFiles") == 0) {
if(!token2)
goto _parser_cleanup;
2022-04-09 22:43:26 +02:00
int n = (int) strtol(token2, NULL, 10);
readNFiles(n, queue, fd_c, taglia);
2022-03-16 23:44:53 +01:00
goto _parser_end;
}
if (strcmp(token, "writeFile") == 0) {
if(!token3 || !token2)
goto _parser_cleanup;
size_t sz = (size_t) strtol(token3, NULL, 10);
2022-04-08 21:32:52 +02:00
writeFile(token2, sz, queue, fd_c, taglia, 0);
2022-03-16 23:44:53 +01:00
goto _parser_end;
}
if (strcmp(token, "appendToFile") == 0) {
if(!token3 || !token2)
goto _parser_cleanup;
size_t sz = (size_t) strtol(token3, NULL, 10);
2022-04-08 21:32:52 +02:00
writeFile(token2, sz, queue, fd_c, taglia, 1);
2022-03-16 23:44:53 +01:00
goto _parser_end;
}
if (strcmp(token, "lockFile") == 0) {
if(!token2)
goto _parser_cleanup;
2022-04-08 21:32:52 +02:00
lockFile(token2, queue, fd_c, taglia, lock, waiting);
2022-03-16 23:44:53 +01:00
goto _parser_end;
}
if (strcmp(token, "unlockFile") == 0) {
if(!token2)
goto _parser_cleanup;
2022-04-08 21:32:52 +02:00
unlockFile(token2, queue, fd_c, taglia, lock, waiting);
2022-03-16 23:44:53 +01:00
goto _parser_end;
}
if (strcmp(token, "closeFile") == 0) {
if(!token2)
goto _parser_cleanup;
2022-04-08 21:32:52 +02:00
closeFile(token2, queue, fd_c, taglia, lock, waiting);
2022-03-16 23:44:53 +01:00
goto _parser_end;
}
if (strcmp(token, "removeFile") == 0) {
if(!token2)
goto _parser_cleanup;
2022-04-08 21:32:52 +02:00
removeFile(token2, queue, fd_c, taglia, lock, waiting);
2022-03-16 23:44:53 +01:00
goto _parser_end;
}
2022-03-18 20:49:28 +01:00
// se arrivo qui non ho riconosciuto il comando
2022-03-16 23:44:53 +01:00
2022-03-18 20:49:28 +01:00
_parser_cleanup:
free(command);
return -1;
2022-03-16 23:44:53 +01:00
_parser_end:
free(command);
return 0;
}