writeFile function
This commit is contained in:
@ -18,6 +18,116 @@
|
|||||||
// #define ME "52" // not used
|
// #define ME "52" // not used
|
||||||
#define MESE "55" // server error
|
#define MESE "55" // server error
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
/* funzioni ausiliarie */
|
||||||
|
|
||||||
|
// invio il messaggio al client
|
||||||
|
void sendMessage(char *m, long fd_c, taglia_t *taglia, char *mlog) {
|
||||||
|
if(!m) {
|
||||||
|
m = MEOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(writen(fd_c, m, strnlen(m, MAXLENMESS)+1) < 0) {
|
||||||
|
perror("writen");
|
||||||
|
goto _sendM_cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(taglia_write(taglia, mlog) < 0)
|
||||||
|
goto _sendM_cleanup;
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
_sendM_cleanup:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// invio il messaggio al client e poi il file
|
||||||
|
void sendMessageFile(char *m, fileT *f, long fd_c, taglia_t *taglia, char *mlog) {
|
||||||
|
if(!f) {
|
||||||
|
errno = EINVAL;
|
||||||
|
serror(MESY, fd_c);
|
||||||
|
goto _sendMF_cleanup;
|
||||||
|
}
|
||||||
|
if(!m) {
|
||||||
|
m = MEPF;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(writen(fd_c, m, strnlen(m, MAXLENMESS)+1) < 0) {
|
||||||
|
perror("writen");
|
||||||
|
goto _sendMF_cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(sendFile(f, fd_c, taglia) < 0) {
|
||||||
|
perror("sendFile");
|
||||||
|
goto _sendMF_cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(taglia_write(taglia, mlog) < 0)
|
||||||
|
goto _sendMF_cleanup;
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
_sendMF_cleanup:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// invio il messaggio al client e poi n file
|
||||||
|
void sendMessageFileN(char *m, fileT **f, int n, long fd_c, taglia *taglia, char *mlog) {
|
||||||
|
if(!f) {
|
||||||
|
errno = EINVAL;
|
||||||
|
serror(MESY, fd_c);
|
||||||
|
goto _sendMFN_cleanup;
|
||||||
|
}
|
||||||
|
if(!m) {
|
||||||
|
m = MEPF;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(writen(fd_c, m, strnlen(m, MAXLENMESS)+1) < 0) {
|
||||||
|
perror("writen");
|
||||||
|
goto _sendMF_cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i=0; i<n && (f[i]!=NULL); ++i) {
|
||||||
|
if(sendFile(f[i], fd_c, taglia) < 0) {
|
||||||
|
perror("sendFile");
|
||||||
|
goto _sendMF_cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(taglia_write(taglia, mlog) < 0)
|
||||||
|
goto _sendMF_cleanup;
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
_sendMFN_cleanup:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// invio il messaggio al client e poi l'errno
|
||||||
|
void serror(char *m, long fd_c, taglia_t *taglia, char *mlog) {
|
||||||
|
if(!m) {
|
||||||
|
errno = EINVAL;
|
||||||
|
m = MESY;
|
||||||
|
}
|
||||||
|
if(writen(fd_c, m, strnlen(m, MAXLENMESS)+1) < 0) {
|
||||||
|
perror("writen");
|
||||||
|
goto _serror_cleanup;
|
||||||
|
}
|
||||||
|
if(writen(fd_c, &errno, sizeof(errno)) < 0) {
|
||||||
|
perror("writen");
|
||||||
|
goto _serror_cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(taglia_write(taglia, mlog) < 0)
|
||||||
|
goto _serror_cleanup;
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
_serror_cleanup:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
void openFile(char *filepath, int flags, queueT *q, long fd_c, taglia_t *taglia) {
|
void openFile(char *filepath, int flags, queueT *q, long fd_c, taglia_t *taglia) {
|
||||||
// messaggio da scrivere sul logfile
|
// messaggio da scrivere sul logfile
|
||||||
@ -120,88 +230,179 @@ void openFile(char *filepath, int flags, queueT *q, long fd_c, taglia_t *taglia)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// invio il messaggio al client
|
|
||||||
void sendMessage(char *m, long fd_c, taglia_t *taglia, char *mlog) {
|
void readFile(char *filepath, queueT *q, long fd_c, taglia_t *taglia) {
|
||||||
if(!m) {
|
// messaggio da scrivere sul logfile
|
||||||
m = MEOK;
|
char tmp_buf[2048];
|
||||||
|
int n = 0;
|
||||||
|
size_t m = sizeof(tmp_buf);
|
||||||
|
|
||||||
|
if(!filepath || !q || !taglia) {
|
||||||
|
n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una readFile (flags = %x) sul file \"%s\" e' terminata con errore\n", fd_c, flags, filepath);
|
||||||
|
errno = EINVAL;
|
||||||
|
serror(MESY, fd_c, taglia, tmp_buf);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(writen(fd_c, m, strnlen(m, MAXLENMESS)+1) < 0) {
|
fileT *f = NULL;
|
||||||
perror("writen");
|
f = find(q, filepath);
|
||||||
goto _sendM_cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(taglia_write(taglia, mlog) < 0)
|
|
||||||
goto _sendM_cleanup;
|
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
_sendM_cleanup:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// invio il messaggio al client e poi il file
|
|
||||||
void sendMessageFile(char *m, fileT *f, long fd_c, taglia_t *taglia, char *mlog) {
|
|
||||||
if(!f) {
|
if(!f) {
|
||||||
errno = EINVAL;
|
n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una readFile (flags = %x) sul file \"%s\" e' terminata con errore\n", fd_c, flags, filepath);
|
||||||
serror(MESY, fd_c);
|
errno = ENOENT;
|
||||||
goto _sendMF_cleanup;
|
serror(MESE, fd_c, taglia, tmp_buf);
|
||||||
}
|
return;
|
||||||
if(!m) {
|
|
||||||
m = MEPF;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(writen(fd_c, m, strnlen(m, MAXLENMESS)+1) < 0) {
|
if(f->open != 0) { // file already open
|
||||||
perror("writen");
|
n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una readFile (flags = %x) sul file \"%s\" e' terminata con errore\n", fd_c, flags, filepath);
|
||||||
goto _sendMF_cleanup;
|
errno = EPERM;
|
||||||
|
serror(MENT, fd_c, taglia, tmp_buf);
|
||||||
|
destroyFile(f); // f is a copy so we need to cleen up
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(sendFile(f, fd_c, taglia) < 0) {
|
n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una readFile (flags = %x) sul file \"%s\" e' terminata con successo\n", fd_c, flags, filepath);
|
||||||
perror("sendFile");
|
sendMessageFile(MEOK, f, fd_c, taglia, tmp_buf);
|
||||||
goto _sendMF_cleanup;
|
destroyFile(f); // f is a copy so we need to cleen up
|
||||||
}
|
|
||||||
|
|
||||||
if(taglia_write(taglia, mlog) < 0)
|
|
||||||
goto _sendMF_cleanup;
|
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
_sendMF_cleanup:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// invio il messaggio al client e poi l'errno
|
|
||||||
void serror(char *m, long fd_c, taglia_t *taglia, char *mlog) {
|
|
||||||
if(!m) {
|
|
||||||
errno = EINVAL;
|
|
||||||
m = MESY;
|
|
||||||
}
|
|
||||||
if(writen(fd_c, m, strnlen(m, MAXLENMESS)+1) < 0) {
|
|
||||||
perror("writen");
|
|
||||||
goto _serror_cleanup;
|
|
||||||
}
|
|
||||||
if(writen(fd_c, &errno, sizeof(errno)) < 0) {
|
|
||||||
perror("writen");
|
|
||||||
goto _serror_cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(taglia_write(taglia, mlog) < 0)
|
|
||||||
goto _serror_cleanup;
|
|
||||||
|
|
||||||
return;
|
|
||||||
|
|
||||||
_serror_cleanup:
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void readFile(char *filepath, queueT *q, long fd_c, taglia_t *taglia);
|
void readNFiles(char *numStr, queueT *q, long fd_c, taglia_t *taglia); // TODO
|
||||||
|
|
||||||
|
|
||||||
void readNFiles(char *numStr, queueT *q, long fd_c, taglia_t *taglia);
|
void writeFile(char *filepath, size_t size, queueT *q, long fd_c, taglia_t *taglia, int append) {
|
||||||
|
// messaggio da scrivere sul logfile
|
||||||
|
char tmp_buf[2048];
|
||||||
|
int n = 0;
|
||||||
|
size_t m = sizeof(tmp_buf);
|
||||||
|
|
||||||
|
if(!filepath || !q || !taglia) {
|
||||||
|
n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una writeFile (append = %x) sul file \"%s\" e' terminata con errore\n", fd_c, append, filepath);
|
||||||
|
errno = EINVAL;
|
||||||
|
serror(MESY, fd_c, taglia, tmp_buf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
void writeFile(char *filepath, size_t size, queueT *q, long fd_c, taglia_t *taglia, int append);
|
fileT *f = NULL;
|
||||||
|
f = find(q, filepath);
|
||||||
|
if(!f) { // file is not present
|
||||||
|
n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una writeFile (append = %x) sul file \"%s\", dimensione = %ld, e' terminata con errore\n", fd_c, append, filepath, size);
|
||||||
|
errno = ENOENT;
|
||||||
|
serror(MENT, fd_c, taglia, tmp_buf);
|
||||||
|
destroyFile(f);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// file non aperto || !append => locked || lock ma non si è proprietari
|
||||||
|
if(!f->open || (append || f->O_LOCK) || (f->O_LOCK && f->owner != fd_c)) {
|
||||||
|
n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una writeFile (append = %x) sul file \"%s\", dimensione = %ld, e' terminata con errore\n", fd_c, append, filepath, size);
|
||||||
|
errno = EPERM;
|
||||||
|
serror(MENT, fd_c, taglia, tmp_buf);
|
||||||
|
destroyFile(f);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int trueSizeAdded = 0; // we may have alredy some space allocated
|
||||||
|
if(append) {
|
||||||
|
trueSizeAdded = size - f->size + f->valid;
|
||||||
|
} else {
|
||||||
|
trueSizeAdded = (size>f->size)? size-f->size : 0;
|
||||||
|
}
|
||||||
|
destroyFile(f); // not needed anymore
|
||||||
|
|
||||||
|
fileT **removed = NULL; // array that may (worst case) hold all files to be sent to the client
|
||||||
|
|
||||||
|
if(trueSizeAdded + getSize(q) > q->maxSize) { // writing would be more than capacity
|
||||||
|
removed = dequeueN(q, filepath, trueSizeAdded);
|
||||||
|
if(!removed) { // internal error
|
||||||
|
n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una writeFile (append = %x) sul file \"%s\", dimensione = %ld, e' terminata con errore\n", fd_c, append, filepath, size);
|
||||||
|
errno = ENOENT;
|
||||||
|
serror(MESY, fd_c, taglia, tmp_buf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int ln = 0;
|
||||||
|
fileT *tmp = removed[ln];
|
||||||
|
n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una writeFile (append = %x) sul file \"%s\", dimensione = %ld, e' terminata con successo. Ha causato una capacity miss e ha fatto espellere i seguenti file:", fd_c, append, filepath, size);
|
||||||
|
while(tmp!=NULL) {
|
||||||
|
n += snprintf(tmp_buf+n, m-n, " \"%s\"", tmp->filepath);
|
||||||
|
++ln;
|
||||||
|
tmp=removed[ln];
|
||||||
|
}
|
||||||
|
n += snprintf(tmp_buf+n, m-n, "\n");
|
||||||
|
taglia_update(taglia, q, ln);
|
||||||
|
|
||||||
|
sendMessageFileN(MEFP, removed, ln, fd_c, taglia, tmp_buf);
|
||||||
|
for(int i=0;i<ln && (removed[i]!=NULL);++i) {
|
||||||
|
destroyFile(removed[i]);
|
||||||
|
}
|
||||||
|
free(removed);
|
||||||
|
// now we can write the actual file
|
||||||
|
|
||||||
|
void *content = NULL;
|
||||||
|
content = malloc(size);
|
||||||
|
if(!content) {
|
||||||
|
perror("malloc");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if((readn(fd_c, content, size)) == -1) {
|
||||||
|
perror("readn");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(append) {
|
||||||
|
if(appendFileInQueue(q, filepath, content, size, fd_c) == -1) {
|
||||||
|
perror("appendFileInQueue");
|
||||||
|
free(content)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(writeFileInQueue(q, filepath, content, size, fd_c) == -1) {
|
||||||
|
perror("writeFileInQueue");
|
||||||
|
free(content)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
taglia_update(taglia, q, 0);
|
||||||
|
free(content)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// non c'è ancora bisogno di rimuovere file
|
||||||
|
void *content = NULL;
|
||||||
|
content = malloc(size);
|
||||||
|
if(!content) {
|
||||||
|
perror("malloc");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(readn(fd_c, content, size) == -1) {
|
||||||
|
perror("readn");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
n += snprintf(tmp_buf+n, m-n, "Client %ld ha richiesto una writeFile (append = %x) sul file \"%s\", dimensione = %ld, e' terminata con successo\n", fd_c, append, filepath, size);
|
||||||
|
|
||||||
|
if(append) {
|
||||||
|
if(appendFileInQueue(q, filepath, content, size, fd_c) == -1) {
|
||||||
|
perror("appendFileInQueue");
|
||||||
|
free(content)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if(writeFileInQueue(q, filepath, content, size, fd_c) == -1) {
|
||||||
|
perror("writeFileInQueue");
|
||||||
|
free(content)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
taglia_write(taglia, mlog);
|
||||||
|
|
||||||
|
taglia_update(taglia, q, 0);
|
||||||
|
|
||||||
|
free(content)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void lockFile(char *filepath, queueT *q, long fd_c, taglia_t *taglia, pthread_mutex_t *lock, waitingT **waiting);
|
void lockFile(char *filepath, queueT *q, long fd_c, taglia_t *taglia, pthread_mutex_t *lock, waitingT **waiting);
|
||||||
|
|||||||
@ -21,6 +21,7 @@ fileT* createFileT(char *f, int O_LOCK, int client, int open){
|
|||||||
f->owner = client;
|
f->owner = client;
|
||||||
f->open = (open == 0)? 0 : 1;
|
f->open = (open == 0)? 0 : 1;
|
||||||
f->size = 0;
|
f->size = 0;
|
||||||
|
f->valid = 0;
|
||||||
|
|
||||||
if ((f->filepath = malloc(sizeof(char)*NAMELEN)) == NULL) {
|
if ((f->filepath = malloc(sizeof(char)*NAMELEN)) == NULL) {
|
||||||
perror("Malloc filepath");
|
perror("Malloc filepath");
|
||||||
@ -44,13 +45,14 @@ int writeFileT(fileT *f, void *data, size_t size) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((f->data = realloc(f->data, f->size + size)) == NULL) {
|
if ((f->data = realloc(f->data, f->valid + size)) == NULL) {
|
||||||
perror("Realloc content");
|
perror("Realloc content");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy((char*) f->data + f->size, data, size);
|
memcpy((char*) f->data + f->valid, data, size);
|
||||||
f->size = f->size + size;
|
f->valid = f->valid + size;
|
||||||
|
f->size = (f->valid>f->size)?f->valid:f->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
// destroy fileT
|
// destroy fileT
|
||||||
@ -158,6 +160,8 @@ fileT* dequeue(queueT *q) {
|
|||||||
|
|
||||||
LOCK_RETURN(&q->m, NULL); // begin me
|
LOCK_RETURN(&q->m, NULL); // begin me
|
||||||
|
|
||||||
|
// TODO: altri oltre fifo
|
||||||
|
|
||||||
if (q->head == NULL || q->len == 0) { // coda vuota
|
if (q->head == NULL || q->len == 0) { // coda vuota
|
||||||
errno = ENOENT;
|
errno = ENOENT;
|
||||||
goto _end_dequeue;
|
goto _end_dequeue;
|
||||||
@ -185,6 +189,91 @@ _end_dequeue:
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// dequeue until we have s free space and expand the file by s
|
||||||
|
fileT ** dequeueN(queueT *q, char *filepath, size_t s) {
|
||||||
|
if(!q) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if(s<=0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOCK_RETURN(&q->m, NULL); // begin me
|
||||||
|
|
||||||
|
/* TODO: altri oltre a fifo */
|
||||||
|
|
||||||
|
if (q->head == NULL || q->len == 0) { // coda vuota
|
||||||
|
errno = ENOENT;
|
||||||
|
goto _end_dequeueN;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(q->maxSize > s) {
|
||||||
|
errno = EINVAL;
|
||||||
|
goto _end_dequeueN;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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_dequeueN;
|
||||||
|
}
|
||||||
|
|
||||||
|
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_dequeueN;
|
||||||
|
}
|
||||||
|
|
||||||
|
fileT **returnList = NULL; // lista dei file rimossi
|
||||||
|
nodeT *tmp = NULL;
|
||||||
|
|
||||||
|
returnList = calloc(1, sizeof(fileT*));
|
||||||
|
returnList[0] = NULL;
|
||||||
|
|
||||||
|
int purged = 0;
|
||||||
|
while(q->size + s > q->maxSize) {
|
||||||
|
purged++;
|
||||||
|
returnList = realloc(purged, sizeof(fileT*));
|
||||||
|
if(!returnList) {
|
||||||
|
perror("realloc");
|
||||||
|
goto _end_dequeueN;
|
||||||
|
}
|
||||||
|
tmp = q->head;
|
||||||
|
q->head = (q->head)->next;
|
||||||
|
|
||||||
|
returnList[purged-1] = tmp->data;
|
||||||
|
--q->len;
|
||||||
|
q->size -= tmp->data->size;
|
||||||
|
|
||||||
|
if (q->head == NULL) { // coda diventa vuota
|
||||||
|
q->tail = NULL;
|
||||||
|
break; // we eliminated everything so we must have enought space
|
||||||
|
}
|
||||||
|
}
|
||||||
|
returnList = realloc(purged+1, sizeof(fileT*));
|
||||||
|
returnList[purged] = NULL; // null terminated
|
||||||
|
|
||||||
|
tmp->data->size += size;
|
||||||
|
q->size += size;
|
||||||
|
|
||||||
|
UNLOCK_RETURN(&q->m, NULL); // end me
|
||||||
|
return data;
|
||||||
|
|
||||||
|
_end_dequeueN:
|
||||||
|
UNLOCK_RETURN(&q->m, NULL);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
void voidDequeue(queueT *q) {
|
void voidDequeue(queueT *q) {
|
||||||
if(!q) {
|
if(!q) {
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
@ -217,8 +306,8 @@ void voidDequeue(queueT *q) {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
_end_void_dequeue:
|
_end_void_dequeue:
|
||||||
UNLOCK_RETURN(&q->m, NULL);
|
UNLOCK(&q->m);
|
||||||
return NULL;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// print queue
|
// print queue
|
||||||
@ -239,6 +328,7 @@ int printQueue(FILE *stream, queueT *q) {
|
|||||||
fprintf(stream, "[Nome File] -> Dimensione in MB");
|
fprintf(stream, "[Nome File] -> Dimensione in MB");
|
||||||
while (temp!=NULL) {
|
while (temp!=NULL) {
|
||||||
float res = ((float)(tmp->data)->size)/1000000; // in MB
|
float res = ((float)(tmp->data)->size)/1000000; // in MB
|
||||||
|
// float res = ((float)(tmp->data)->valid)/1000000; // in MB
|
||||||
fprintf(stream, "[%s]\t-> %f MB\n", (tmp->data)->filepath, res);
|
fprintf(stream, "[%s]\t-> %f MB\n", (tmp->data)->filepath, res);
|
||||||
temp = temp->next;
|
temp = temp->next;
|
||||||
}
|
}
|
||||||
@ -483,13 +573,14 @@ int writeFileInQueue(queueT *q, char *filepath, void *data, size_t size, int own
|
|||||||
}
|
}
|
||||||
|
|
||||||
// scrivo
|
// scrivo
|
||||||
if (((tmp->data)->data = realloc((tmp->data)->data, (tmp->data)->size + size)) == NULL) {
|
if (((tmp->data)->data = realloc((tmp->data)->data, size)) == NULL) {
|
||||||
perror("Realloc content");
|
perror("Realloc content");
|
||||||
goto _end_write_file_queue;
|
goto _end_write_file_queue;
|
||||||
}
|
}
|
||||||
memcpy((tmp->data)->data, data, size);
|
memcpy((tmp->data)->data, data, size);
|
||||||
|
|
||||||
q->size = (q->size) - ((tmp->data)->size) + size;
|
q->size = (q->size) - ((tmp->data)->size) + size;
|
||||||
|
(tmp->data)->valid = size;
|
||||||
(tmp->data)->size = size;
|
(tmp->data)->size = size;
|
||||||
|
|
||||||
UNLOCK_RETURN(&q->m, -1); // end me
|
UNLOCK_RETURN(&q->m, -1); // end me
|
||||||
@ -542,15 +633,17 @@ int appendFileInQueue(queueT *q, char *filepath, void *data, size_t size, int ow
|
|||||||
}
|
}
|
||||||
|
|
||||||
// scrivo
|
// scrivo
|
||||||
if (((tmp->data)->data = realloc((tmp->data)->data, (tmp->data)->size + size)) == NULL) {
|
if (((tmp->data)->data = realloc((tmp->data)->data, (tmp->data)->valid + size)) == NULL) {
|
||||||
perror("Realloc content");
|
perror("Realloc content");
|
||||||
goto _end_append_file_queue;
|
goto _end_append_file_queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(((tmp->data)->data) + (tmp->data)->size, data, size);
|
memcpy(((tmp->data)->data) + (tmp->data)->valid, data, size);
|
||||||
// memmove sarebbe un'alternativa
|
// memmove sarebbe un'alternativa
|
||||||
(tmp->data)->size += size;
|
(tmp->data)->valid += size;
|
||||||
q->size += size;
|
q->size -= (tmp->data)->size;
|
||||||
|
(tmp->data)->size = ((tmp->data)->size > (tmp->data)->valid) ? (tmp->data)->size : (tmp->data)->valid;
|
||||||
|
q->size += (tmp->data)->size;
|
||||||
|
|
||||||
UNLOCK_RETURN(&q->m, -1); // end me
|
UNLOCK_RETURN(&q->m, -1); // end me
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@ -11,6 +11,7 @@ typedef struct {
|
|||||||
int open; // 1 se il file e' aperto
|
int open; // 1 se il file e' aperto
|
||||||
void *data; // contenuto del file
|
void *data; // contenuto del file
|
||||||
size_t size; // dimensione del file in bytes
|
size_t size; // dimensione del file in bytes
|
||||||
|
size_t valid; // posizione fino a cui i dati sono validi
|
||||||
} fileT;
|
} fileT;
|
||||||
|
|
||||||
// nodo di una linked list
|
// nodo di una linked list
|
||||||
@ -88,6 +89,17 @@ int enqueue(queueT *q, fileT* data);
|
|||||||
*/
|
*/
|
||||||
fileT* dequeue(queueT *q);
|
fileT* dequeue(queueT *q);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Estrae fileT dalla coda fino ad ottenere abbastanza spazio in q.
|
||||||
|
* \param q: puntatore alla coda
|
||||||
|
* \param filepath: file a cui bisogna aggiungere s di spazio
|
||||||
|
* \param s: dimensione da aggiungere al file
|
||||||
|
*
|
||||||
|
* \retval puntatore alla lista di file estratti (NULL terminated), NULL se errore
|
||||||
|
*/
|
||||||
|
fileT ** dequeueN(queueT *q, char *filepath, size_t s);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Estrae un fileT dalla coda come la dequeue, ma invece di restituire il
|
* Estrae un fileT dalla coda come la dequeue, ma invece di restituire il
|
||||||
* file estratto lo distrugge immediatamente, liberandone la memoria.
|
* file estratto lo distrugge immediatamente, liberandone la memoria.
|
||||||
|
|||||||
Reference in New Issue
Block a user