#include #include #include #include #include #include /* For O_* constants */ #include /* For mode constants */ #include #include #include "quicksort.h" /* ***D01*** (simile a esercizio C06, che però usa un file in formato testo) è dato un file che contiene un array di int, in formato binario. scrivere un programma che effettua il sort crescente dell'array di int contenuto nel file e che poi prosegue così: versione A: il file originale viene modificato con l'array di int ordinato versione B: il file originale non viene modificato e l'array di int ordinato viene scritto in un nuovo file */ // restituisce la dimensione del file, -1 in caso di errore __off_t get_fd_size(int fd) { struct stat sb; int res; res = fstat(fd, &sb); if (res == -1) { perror("fstat()"); return -1; } return sb.st_size; } char * filename = "prova.dat"; int main() { // proviamo ad accedere al file con mmap int fd; //char * addr; int * array; // ipotesi: il file esiste fd = open(filename, O_RDWR); if (fd == -1) { perror("open"); exit(1); } __off_t filesize; filesize = get_fd_size(fd); if (filesize == -1) exit(1); printf("filesize = %ld bytes\n", filesize); // array di int: ci aspettiamo che il file abbia dimensione multiplo di // sizeof(int) if (filesize % sizeof(int) != 0) { printf("la dimensione del file non è un multiplo di sizeof(int).\n"); exit(1); } int array_len = filesize / sizeof(int); // creiamo una memory map di tutto il file // mmap restituisce l'indirizzo della zona di memoria dove // è mappato tutto il file (o una sua parte) array = mmap(NULL, // NULL: è il kernel a scegliere l'indirizzo filesize, // dimensione della memory map PROT_READ | PROT_WRITE, // memory map leggibile e scrivibile MAP_SHARED, // memory map condivisibile con altri processi fd, 0); // offset nel file // mmap è definito come una funzione che restituisce un puntatore generico // quindi il valore restituito può essere assegnato // ad una variabile puntatore di qualsiasi tipo close(fd); if (array == MAP_FAILED) { perror("mmap()"); return 1; } // versione A: modifichiamo il file // usiamo quicksort per ordinare l'array di int // scriviamo i primi N elementi dell'array non ordinato: // 0000000 0e 22 8f 1c 83 fa bf 1b 0b 9f 49 39 73 0f 0e 3f // 0000020 ec f3 e0 48 f5 10 a5 3c 4b 21 ca 3c 4a f2 4e 04 // 0000040 74 04 1e 7a 35 34 b0 7a e7 8d b3 13 f1 2d 6b 21 /* il file originale dovrebbe iniziare così: array[0] = 1c8f220e array[1] = 1bbffa83 array[2] = 39499f0b array[3] = 3f0e0f73 array[4] = 48e0f3ec array[5] = 3ca510f5 array[6] = 3cca214b array[7] = 44ef24a array[8] = 7a1e0474 array[9] = 7ab03435 .... */ printf("prima di fare il sort:\n"); for (int i = 0; i < 10; i++) { printf("array[%d] = %x\n", i, array[i]); } quick_sort(array, array_len); printf("\n\ndopo aver fatto il sort:\n"); for (int i = 0; i < 10; i++) { printf("array[%d] = %x\n", i, array[i]); } /* * il file modificato dovrebbe iniziare così: * array[0] = 3d896f array[1] = b75270 array[2] = c0df89 array[3] = e97e47 array[4] = 10b5ff9 array[5] = 1138514 array[6] = 116fcb2 array[7] = 1694a88 array[8] = 1a2d582 array[9] = 1bf94a4 .... * */ // rilasciamo la memory map if (munmap(array, filesize) == -1) { perror("munmap"); } // od -t x1 prova.dat /* * per verifica: * * file non ordinato (dimensione file: 4096 bytes) sha256sum prova.dat ff8878b7a942f94263f6ee0f5b24d587a9df89b8f556544efdbc774020267e83 prova.dat file ordinato: sha256sum prova.dat 78298946f5f846eaaf79613ddb064bcd11f17ee513c507aa1541f08c991701a7 prova.dat * */ printf("bye\n"); return 0; }