727 lines
14 KiB
C
727 lines
14 KiB
C
|
|
#include <fileQueue.h>
|
||
|
|
#include <util.h>
|
||
|
|
|
||
|
|
#define NAMELEN 256
|
||
|
|
|
||
|
|
// creazione di un fileT
|
||
|
|
fileT* createFileT(char *f, int O_LOCK, int client, int open){
|
||
|
|
if(!f){
|
||
|
|
errno = EINVAL;
|
||
|
|
return NULL;
|
||
|
|
}
|
||
|
|
|
||
|
|
fileT *file = malloc(sizeof(fileT));
|
||
|
|
|
||
|
|
if (f == NULL) {
|
||
|
|
perror("Malloc createFileT");
|
||
|
|
return NULL;
|
||
|
|
}
|
||
|
|
|
||
|
|
f->O_LOCK = (O_LOCK == 0)? 0 : 1;
|
||
|
|
f->owner = client;
|
||
|
|
f->open = (open == 0)? 0 : 1;
|
||
|
|
f->size = 0;
|
||
|
|
|
||
|
|
if ((f->filepath = malloc(sizeof(char)*NAMELEN)) == NULL) {
|
||
|
|
perror("Malloc filepath");
|
||
|
|
destroyFile(f);
|
||
|
|
return NULL;
|
||
|
|
}
|
||
|
|
|
||
|
|
strncpy(f->filepath, f, NAMELEN);
|
||
|
|
|
||
|
|
if ((f->data = malloc(1)) == NULL) { // così semplicemente facciamo realloc
|
||
|
|
perror("Malloc content");
|
||
|
|
return NULL;
|
||
|
|
}
|
||
|
|
return f;
|
||
|
|
}
|
||
|
|
|
||
|
|
// append su fileT
|
||
|
|
int writeFileT(fileT *f, void *data, size_t size) {
|
||
|
|
if(!f || !data || size < 0){
|
||
|
|
errno = EINVAL;
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
if ((f->data = realloc(f->data, f->size + size)) == NULL) {
|
||
|
|
perror("Realloc content");
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
memcpy((char*) f->data + f->size, data, size);
|
||
|
|
f->size = f->size + size;
|
||
|
|
}
|
||
|
|
|
||
|
|
// destroy fileT
|
||
|
|
void destroyFile(fileT *f) {
|
||
|
|
if(!f)
|
||
|
|
return;
|
||
|
|
if(f->filepath)
|
||
|
|
free(f->filepath);
|
||
|
|
if(f->data)
|
||
|
|
free(f->data);
|
||
|
|
free(f);
|
||
|
|
}
|
||
|
|
|
||
|
|
// --------------
|
||
|
|
|
||
|
|
// creazione queue
|
||
|
|
queueT* createQueue(size_t maxLen, size_t maxSize) {
|
||
|
|
if(maxLen<0 || maxSize<0){
|
||
|
|
errno = EINVAL;
|
||
|
|
return NULL;
|
||
|
|
}
|
||
|
|
|
||
|
|
queueT *q = malloc(sizeof(queueT));
|
||
|
|
if(q==NULL){
|
||
|
|
perror("Malloc createQueue");
|
||
|
|
return NULL;
|
||
|
|
}
|
||
|
|
|
||
|
|
// creazione lock
|
||
|
|
if (pthread_mutex_init(&q->m, NULL) != 0) {
|
||
|
|
perror("pthread_mutex_init createQueue");
|
||
|
|
destroyQueue(q);
|
||
|
|
return NULL;
|
||
|
|
}
|
||
|
|
|
||
|
|
q->head = NULL;
|
||
|
|
q->tail = NULL;
|
||
|
|
q->maxLen = maxLen;
|
||
|
|
q->len = 0;
|
||
|
|
q->maxSize = maxSize;
|
||
|
|
q->size = 0;
|
||
|
|
|
||
|
|
return q;
|
||
|
|
}
|
||
|
|
|
||
|
|
// insert
|
||
|
|
int enqueue(queueT *q, fileT* data) {
|
||
|
|
if(!q || !data){
|
||
|
|
errno = EINVAL;
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
LOCK_RETURN(&q->m, -1); // begin me
|
||
|
|
|
||
|
|
if (q->len == q->maxLen) { // too many files
|
||
|
|
errno = ENFILE;
|
||
|
|
goto _end_enqueue;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (q->size + data->size > q->maxSize) {
|
||
|
|
errno = EFBIG;
|
||
|
|
goto _end_enqueue;
|
||
|
|
}
|
||
|
|
|
||
|
|
// inserisco l'elemento
|
||
|
|
nodeT *newNode = malloc(sizeof(nodeT));
|
||
|
|
if (newNode == NULL) {
|
||
|
|
perror("malloc newNode");
|
||
|
|
goto _end_enqueue;
|
||
|
|
}
|
||
|
|
|
||
|
|
newNode->data = data;
|
||
|
|
newNode->next = NULL;
|
||
|
|
nodeT *tmp = queue->head;
|
||
|
|
|
||
|
|
if (q->head == NULL)
|
||
|
|
q->head = newNode;
|
||
|
|
else {
|
||
|
|
while (tmp->next)
|
||
|
|
tmp = temp->next;
|
||
|
|
|
||
|
|
temp->next = newNode;
|
||
|
|
}
|
||
|
|
|
||
|
|
q->tail = newNode;
|
||
|
|
|
||
|
|
++q->len;
|
||
|
|
q->size += data->size;
|
||
|
|
|
||
|
|
|
||
|
|
UNLOCK_RETURN(&q->m, -1); // end me
|
||
|
|
return 0;
|
||
|
|
|
||
|
|
_end_enqueue:
|
||
|
|
UNLOCK_RETURN(&q->m, -1);
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
// remove
|
||
|
|
fileT* dequeue(queueT *q) {
|
||
|
|
if(!q) {
|
||
|
|
errno = EINVAL;
|
||
|
|
return NULL;
|
||
|
|
}
|
||
|
|
|
||
|
|
LOCK_RETURN(&q->m, NULL); // begin me
|
||
|
|
|
||
|
|
if (q->head == NULL || q->len == 0) { // coda vuota
|
||
|
|
errno = ENOENT;
|
||
|
|
goto _end_dequeue;
|
||
|
|
}
|
||
|
|
|
||
|
|
fileT *data = (q->head)->data;
|
||
|
|
|
||
|
|
nodeT *tmp = NULL;
|
||
|
|
tmp = q->head;
|
||
|
|
q->head = (q->head)->next;
|
||
|
|
|
||
|
|
if (q->head == NULL) { // coda diventa vuota
|
||
|
|
q->tail = NULL;
|
||
|
|
}
|
||
|
|
|
||
|
|
--q->len;
|
||
|
|
q->size -= data->size;
|
||
|
|
free(tmp); // free del nodo
|
||
|
|
|
||
|
|
UNLOCK_RETURN(&q->m, NULL); // end me
|
||
|
|
return data;
|
||
|
|
|
||
|
|
_end_dequeue:
|
||
|
|
UNLOCK_RETURN(&q->m, NULL);
|
||
|
|
return NULL;
|
||
|
|
}
|
||
|
|
|
||
|
|
void voidDequeue(queueT *q) {
|
||
|
|
if(!q) {
|
||
|
|
errno = EINVAL;
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
LOCK(&q->m); // begin me
|
||
|
|
|
||
|
|
if (q->head == NULL || q->len == 0) { // coda vuota
|
||
|
|
errno = ENOENT;
|
||
|
|
goto _end_void_dequeue;
|
||
|
|
}
|
||
|
|
|
||
|
|
nodeT *tmp = NULL;
|
||
|
|
tmp = q->head;
|
||
|
|
|
||
|
|
q->head = (q->head)->next;
|
||
|
|
|
||
|
|
if (q->head == NULL) { // coda diventa vuota
|
||
|
|
q->tail = NULL;
|
||
|
|
}
|
||
|
|
|
||
|
|
--q->len;
|
||
|
|
q->size -= data->size;
|
||
|
|
|
||
|
|
destroyFile(tmp->data); // free fileT
|
||
|
|
free(tmp); // free nodo
|
||
|
|
|
||
|
|
UNLOCK(&q->m); // end me
|
||
|
|
return;
|
||
|
|
|
||
|
|
_end_void_dequeue:
|
||
|
|
UNLOCK_RETURN(&q->m, NULL);
|
||
|
|
return NULL;
|
||
|
|
}
|
||
|
|
|
||
|
|
// print queue
|
||
|
|
int printQueue(FILE *stream, queueT *q) {
|
||
|
|
if(!q || !stream) {
|
||
|
|
errno = EINVAL;
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
LOCK_RETURN(&q->m, -1); // begin me
|
||
|
|
|
||
|
|
UNLOCK_RETURN(&q->m, -1);
|
||
|
|
return 0;
|
||
|
|
|
||
|
|
nodeT *tmp = q->head;
|
||
|
|
|
||
|
|
fprintf(stream, "Lista file:");
|
||
|
|
fprintf(stream, "[Nome File] -> Dimensione in MB");
|
||
|
|
while (temp!=NULL) {
|
||
|
|
float res = ((float)(tmp->data)->size)/1000000; // in MB
|
||
|
|
fprintf(stream, "[%s]\t-> %f MB\n", (tmp->data)->filepath, res);
|
||
|
|
temp = temp->next;
|
||
|
|
}
|
||
|
|
|
||
|
|
UNLOCK_RETURN(&q->m, -1); // end me
|
||
|
|
return 0;
|
||
|
|
|
||
|
|
_end_print_queue:
|
||
|
|
UNLOCK_RETURN(&q->m, -1);
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
// acquisizione lock
|
||
|
|
int lockFileInQueue(queueT *q, char *filepath, int owner) {
|
||
|
|
if(!q || !filepath) {
|
||
|
|
errno = EINVAL;
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
LOCK_RETURN(&q->m, -1); // begin me
|
||
|
|
|
||
|
|
if (q->len == 0) {
|
||
|
|
errno = ENOENT;
|
||
|
|
goto _end_lock_file_queue;
|
||
|
|
}
|
||
|
|
|
||
|
|
// scorro la queue per trovare l'elemento
|
||
|
|
nodeT *tmp = q->head;
|
||
|
|
|
||
|
|
while (tmp) {
|
||
|
|
if (strcmp(filepath, (tmp->data)->filepath) == 0) { // trovato
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
tmp = tmp->next;
|
||
|
|
}
|
||
|
|
|
||
|
|
if(!tmp) { // non trovato
|
||
|
|
errno = ENOENT;
|
||
|
|
goto _end_lock_file_queue;
|
||
|
|
}
|
||
|
|
|
||
|
|
if ((tmp->data)->O_LOCK && (tmp->data)->owner != owner) { // lock non del owner
|
||
|
|
errno = EPERM;
|
||
|
|
goto _end_lock_file_queue;
|
||
|
|
}
|
||
|
|
|
||
|
|
// acquisisco lock sul file
|
||
|
|
(temp->data)->O_LOCK = 1;
|
||
|
|
(temp->data)->owner = owner;
|
||
|
|
|
||
|
|
UNLOCK_RETURN(&q->m, -1); // end me
|
||
|
|
return 0;
|
||
|
|
|
||
|
|
_end_lock_file_queue:
|
||
|
|
UNLOCK_RETURN(&q->m, -1);
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
int unlockFileInQueue(queueT *q, char *filepath, int owner) {
|
||
|
|
if(!q || !filepath) {
|
||
|
|
errno = EINVAL;
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
LOCK_RETURN(&q->m, -1); // begin me
|
||
|
|
|
||
|
|
if (q->len == 0) {
|
||
|
|
errno = ENOENT;
|
||
|
|
goto _end_unlock_file_queue;
|
||
|
|
}
|
||
|
|
|
||
|
|
// scorro la queue per trovare l'elemento
|
||
|
|
nodeT *tmp = q->head;
|
||
|
|
|
||
|
|
while (tmp) {
|
||
|
|
if (strcmp(filepath, (tmp->data)->filepath) == 0) { // trovato
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
tmp = tmp->next;
|
||
|
|
}
|
||
|
|
|
||
|
|
if(!tmp) { // non trovato
|
||
|
|
errno = ENOENT;
|
||
|
|
goto _end_lock_file_queue;
|
||
|
|
}
|
||
|
|
|
||
|
|
if((tmp->data)->O_LOCK == 0) { // nessuno ha il lock
|
||
|
|
UNLOCK_RETURN(&q->m, -1);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
if((tmp->data)->O_LOCK == 1 && (tmp->data)->owner != owner) { // lock non del owner
|
||
|
|
errno = EPERM;
|
||
|
|
goto _end_unlock_file_queue;
|
||
|
|
}
|
||
|
|
|
||
|
|
(tmp->data)->O_LOCK = 0;
|
||
|
|
|
||
|
|
UNLOCK_RETURN(&q->m, -1); // end me
|
||
|
|
return 0;
|
||
|
|
|
||
|
|
_end_unlock_file_queue:
|
||
|
|
UNLOCK_RETURN(&q->m, -1);
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
// open file
|
||
|
|
int openFileInQueue(queueT *q, char *filepath, int O_LOCK, int owner) {
|
||
|
|
if(!q || !filepath) {
|
||
|
|
errno = EINVAL;
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
LOCK_RETURN(&q->m, -1); // begin me
|
||
|
|
|
||
|
|
if (q->len == 0) {
|
||
|
|
errno = ENOENT;
|
||
|
|
goto _end_open_file_queue;
|
||
|
|
}
|
||
|
|
|
||
|
|
// scorro la queue per trovare l'elemento
|
||
|
|
nodeT *tmp = q->head;
|
||
|
|
while (tmp) {
|
||
|
|
if (strcmp(filepath, (tmp->data)->filepath) == 0) { // trovato
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
tmp = tmp->next;
|
||
|
|
}
|
||
|
|
|
||
|
|
if(!tmp) { // non trovato
|
||
|
|
errno = ENOENT;
|
||
|
|
goto _end_open_file_queue;
|
||
|
|
}
|
||
|
|
|
||
|
|
if((tmp->data)->O_LOCK == 1 && (tmp->data)->owner != owner) { // lock non del owner
|
||
|
|
errno = EPERM;
|
||
|
|
goto _end_open_file_queue;
|
||
|
|
}
|
||
|
|
|
||
|
|
(tmp->data)->open = 1;
|
||
|
|
(tmp->data)->O_LOCK = (O_LOCK==0)?0:1;
|
||
|
|
|
||
|
|
if(O_LOCK!=0) {
|
||
|
|
(tmp->data)->owner = client;
|
||
|
|
}
|
||
|
|
|
||
|
|
UNLOCK_RETURN(&q->m, -1); // end me
|
||
|
|
return 0;
|
||
|
|
|
||
|
|
_end_open_file_queue:
|
||
|
|
UNLOCK_RETURN(&q->m, -1);
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
// close and relese lock
|
||
|
|
int closeFileInQueue(queueT *q, char *filepath, int owner) {
|
||
|
|
if(!q || !filepath) {
|
||
|
|
errno = EINVAL;
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
LOCK_RETURN(&q->m, -1); // begin me
|
||
|
|
|
||
|
|
if (q->len == 0) {
|
||
|
|
errno = ENOENT;
|
||
|
|
goto _end_close_file_queue;
|
||
|
|
}
|
||
|
|
|
||
|
|
// scorro la queue per trovare l'elemento
|
||
|
|
nodeT *tmp = q->head;
|
||
|
|
while (tmp) {
|
||
|
|
if (strcmp(filepath, (tmp->data)->filepath) == 0) { // trovato
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
tmp = tmp->next;
|
||
|
|
}
|
||
|
|
|
||
|
|
if(!tmp) { // non trovato
|
||
|
|
errno = ENOENT;
|
||
|
|
goto _end_close_file_queue;
|
||
|
|
}
|
||
|
|
|
||
|
|
if((tmp->data)->O_LOCK == 1 && (tmp->data)->owner != owner) { // lock non del owner
|
||
|
|
errno = EPERM;
|
||
|
|
goto _end_close_file_queue;
|
||
|
|
}
|
||
|
|
|
||
|
|
(tmp->data)->open = 0;
|
||
|
|
(tmp->data)->O_LOCK = 0;
|
||
|
|
(tmp->data)->owner = owner;
|
||
|
|
|
||
|
|
UNLOCK_RETURN(&q->m, -1); // end me
|
||
|
|
return 0;
|
||
|
|
|
||
|
|
_end_open_file_queue:
|
||
|
|
UNLOCK_RETURN(&q->m, -1);
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
int writeFileInQueue(queueT *q, char *filepath, void *data, size_t size, int owner) {
|
||
|
|
if(!q || !filepath || !data) {
|
||
|
|
errno = EINVAL;
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
if(size == 0)
|
||
|
|
return 0;
|
||
|
|
|
||
|
|
LOCK_RETURN(&q->m, -1); // begin me
|
||
|
|
|
||
|
|
if (q->len == 0) { // coda vuota
|
||
|
|
errno = ENOENT;
|
||
|
|
goto _end_write_file_queue;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (q->size + size > q->maxSize) { // non c'e' abbastanza spazio
|
||
|
|
errno = EFBIG;
|
||
|
|
goto _end_write_file_queue;
|
||
|
|
}
|
||
|
|
|
||
|
|
// scorro la queue per trovare l'elemento
|
||
|
|
nodeT *tmp = q->head;
|
||
|
|
while (tmp) {
|
||
|
|
if (strcmp(filepath, (tmp->data)->filepath) == 0) { // trovato
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
tmp = tmp->next;
|
||
|
|
}
|
||
|
|
|
||
|
|
if(!tmp) { // non trovato
|
||
|
|
errno = ENOENT;
|
||
|
|
goto _end_write_file_queue;
|
||
|
|
}
|
||
|
|
|
||
|
|
if ((tmp->data)->open == 0 || ((tmp->data)->O_LOCK && (tmp->data)->owner != owner)) {
|
||
|
|
// if file non è aperto o la lock non è del owner
|
||
|
|
errno = EPERM;
|
||
|
|
goto _end_write_file_queue;
|
||
|
|
}
|
||
|
|
|
||
|
|
// scrivo
|
||
|
|
if (((tmp->data)->data = realloc((tmp->data)->data, (tmp->data)->size + size)) == NULL) {
|
||
|
|
perror("Realloc content");
|
||
|
|
goto _end_write_file_queue;
|
||
|
|
}
|
||
|
|
memcpy((tmp->data)->data, data, size);
|
||
|
|
|
||
|
|
q->size = (q->size) - ((tmp->data)->size) + size;
|
||
|
|
(tmp->data)->size = size;
|
||
|
|
|
||
|
|
UNLOCK_RETURN(&q->m, -1); // end me
|
||
|
|
return 0;
|
||
|
|
|
||
|
|
_end_write_file_queue:
|
||
|
|
UNLOCK_RETURN(&q->m, -1);
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
int appendFileInQueue(queueT *q, char *filepath, void *data, size_t size, int owner) {
|
||
|
|
if (!q || !filepath || !data) {
|
||
|
|
errno = EINVAL;
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
if (size == 0)
|
||
|
|
return 0;
|
||
|
|
|
||
|
|
LOCK_RETURN(&q->m, -1); // begin me
|
||
|
|
|
||
|
|
if (q->len == 0) { // coda vuota
|
||
|
|
errno = ENOENT;
|
||
|
|
goto _end_append_file_queue;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (q->size + size > q->maxSize) { // non c'e' abbastanza spazio
|
||
|
|
errno = EFBIG;
|
||
|
|
goto _end_append_file_queue;
|
||
|
|
}
|
||
|
|
|
||
|
|
// scorro la queue per trovare l'elemento
|
||
|
|
nodeT *tmp = q->head;
|
||
|
|
while (tmp) {
|
||
|
|
if (strcmp(filepath, (tmp->data)->filepath) == 0) { // trovato
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
tmp = tmp->next;
|
||
|
|
}
|
||
|
|
|
||
|
|
if(!tmp) { // non trovato
|
||
|
|
errno = ENOENT;
|
||
|
|
goto _end_append_file_queue;
|
||
|
|
}
|
||
|
|
|
||
|
|
if ((tmp->data)->open == 0 || ((tmp->data)->O_LOCK && (tmp->data)->owner != owner)) {
|
||
|
|
// if file non è aperto o la lock non è del owner
|
||
|
|
errno = EPERM;
|
||
|
|
goto _end_append_file_queue;
|
||
|
|
}
|
||
|
|
|
||
|
|
// scrivo
|
||
|
|
if (((tmp->data)->data = realloc((tmp->data)->data, (tmp->data)->size + size)) == NULL) {
|
||
|
|
perror("Realloc content");
|
||
|
|
goto _end_append_file_queue;
|
||
|
|
}
|
||
|
|
|
||
|
|
memcpy(((tmp->data)->data) + (tmp->data)->size, data, size);
|
||
|
|
// memmove sarebbe un'alternativa
|
||
|
|
(tmp->data)->size += size;
|
||
|
|
q->size += size;
|
||
|
|
|
||
|
|
UNLOCK_RETURN(&q->m, -1); // end me
|
||
|
|
return 0;
|
||
|
|
|
||
|
|
_end_append_file_queue:
|
||
|
|
UNLOCK_RETURN(&q->m, -1);
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
int removeFileFromQueue(queueT *q, char *filepath, int owner) {
|
||
|
|
if(!q || !filepath) {
|
||
|
|
errno = EINVAL;
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
LOCK_RETURN(&q->m, -1); // begin me
|
||
|
|
|
||
|
|
if (q->len == 0) { // coda vuota
|
||
|
|
errno = ENOENT;
|
||
|
|
goto _end_remove_file_queue;
|
||
|
|
}
|
||
|
|
|
||
|
|
// scorro la queue per trovare l'elemento
|
||
|
|
nodeT *tmp = q->head;
|
||
|
|
nodeT *pre = q->head;
|
||
|
|
while (tmp) {
|
||
|
|
if (strcmp(filepath, (tmp->data)->filepath) == 0) { // trovato
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
if(prc!=tmp)
|
||
|
|
prc = prc->next;
|
||
|
|
tmp = tmp->next;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!tmp) { // non trovato
|
||
|
|
errno = ENOENT;
|
||
|
|
goto _end_remove_file_queue;
|
||
|
|
}
|
||
|
|
|
||
|
|
if ((tmp->data)->open != 0 || ((tmp->data)->O_LOCK && (tmp->data)->owner != owner)) {
|
||
|
|
// if file è aperto o la lock non è del owner
|
||
|
|
errno = EPERM;
|
||
|
|
goto _end_append_file_queue;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (tmp == prc) { // file è il primo
|
||
|
|
q->head = tmp->next;
|
||
|
|
|
||
|
|
if (tmp->next == NULL) {
|
||
|
|
q->tail = tmp;
|
||
|
|
}
|
||
|
|
} else { // file non è il primo
|
||
|
|
prc->next = tmp->next;
|
||
|
|
|
||
|
|
if (prc->next == NULL) {
|
||
|
|
q->tail = prc;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
--q->len;
|
||
|
|
q->size -= (tmp->data)->size;
|
||
|
|
destroyFile(tmp->data); // free file
|
||
|
|
free(tmp); // free node
|
||
|
|
|
||
|
|
UNLOCK_RETURN(&q->m, -1); // end me
|
||
|
|
return 0;
|
||
|
|
|
||
|
|
_end_remove_file_queue:
|
||
|
|
UNLOCK_RETURN(&q->m, -1);
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
// ----------------
|
||
|
|
|
||
|
|
// cerco e ritorno una copia
|
||
|
|
fileT* find(queueT *q, char *filepath) {
|
||
|
|
if(!q || !filepath) {
|
||
|
|
errno = EINVAL;
|
||
|
|
return NULL;
|
||
|
|
}
|
||
|
|
|
||
|
|
LOCK_RETURN(&q->m, NULL); // begin me
|
||
|
|
|
||
|
|
if (q->len == 0)
|
||
|
|
goto _end_find_in_queue;
|
||
|
|
|
||
|
|
fileT *res = NULL;
|
||
|
|
nodeT *tmp = q->head;
|
||
|
|
|
||
|
|
while (tmp) {
|
||
|
|
if (strcmp(filepath, (tmp->data)->filepath) == 0) { // trovato
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
tmp = tmp->next;
|
||
|
|
}
|
||
|
|
|
||
|
|
if(!tmp)
|
||
|
|
goto _end_find_in_queue;
|
||
|
|
|
||
|
|
// creo una nuova istanza
|
||
|
|
res = createFileT((tmp->data)->filepath, (tmp->data)->O_LOCK, (tmp->data)->owner, (tmp->data)->open);
|
||
|
|
|
||
|
|
if (!res) {
|
||
|
|
perror("createFileT res");
|
||
|
|
goto _end_find_in_queue;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (writeFileT(res, (tmp->data)->data, (tmp->data)->size) == -1) {
|
||
|
|
perror("writeFileT res");
|
||
|
|
goto _end_find_in_queue;
|
||
|
|
}
|
||
|
|
|
||
|
|
UNLOCK_RETURN(&q->m, NULL); // end me
|
||
|
|
return res;
|
||
|
|
|
||
|
|
_end_find_in_queue:
|
||
|
|
UNLOCK_RETURN(&q->m, NULL);
|
||
|
|
return NULL;
|
||
|
|
}
|
||
|
|
|
||
|
|
// numero di elementi della queue
|
||
|
|
size_t getLen(queueT *q) {
|
||
|
|
if(!q) {
|
||
|
|
errno = EINVAL;
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
size_t len = -1;
|
||
|
|
|
||
|
|
LOCK_RETURN(&q->m, -1); // begin me
|
||
|
|
|
||
|
|
len = queue->len;
|
||
|
|
|
||
|
|
UNLOCK_RETURN(&q->m, -1); // end me
|
||
|
|
return len;
|
||
|
|
}
|
||
|
|
|
||
|
|
// dimensione in byte
|
||
|
|
size_t getSize(queueT *q) {
|
||
|
|
if(!q) {
|
||
|
|
errno = EINVAL;
|
||
|
|
return -1;
|
||
|
|
}
|
||
|
|
size_t size = -1;
|
||
|
|
|
||
|
|
LOCK_RETURN(&q->m, -1); // begin me
|
||
|
|
|
||
|
|
size = q->size;
|
||
|
|
|
||
|
|
UNLOCK_RETURN(&q->m, -1); // end me
|
||
|
|
return size;
|
||
|
|
}
|
||
|
|
|
||
|
|
void destroyQueue(queueT *q) {
|
||
|
|
if(!q)
|
||
|
|
return;
|
||
|
|
|
||
|
|
// no need for lock over queue
|
||
|
|
while (q->len > 0) {
|
||
|
|
errno = 0;
|
||
|
|
voiDequeue(q);
|
||
|
|
if (errno) {
|
||
|
|
perror("voiDequeue");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (&queue->m) {
|
||
|
|
pthread_mutex_destroy(&q->m);
|
||
|
|
}
|
||
|
|
|
||
|
|
free(queue);
|
||
|
|
}
|