diff --git a/c-programming/reverse-ramdisk.c b/c-programming/reverse-ramdisk.c index f99fce9..aca186c 100644 --- a/c-programming/reverse-ramdisk.c +++ b/c-programming/reverse-ramdisk.c @@ -5,11 +5,12 @@ C programming idea: Handling temporary files like memory allocations (allocating Warning: The current result is quick and dirty. Not for educational or production purposes. +Warning: The functions are not thread-safe. GCC/Clang/TCC: Compile with -DTEST to set macro TEST as defined, with -DDEBUG to enable debug mode -To-Do: error handling on line 184, function fread() +To-Do: Add thread-safe versions of functions (use postfix `_r`) */ #include @@ -40,11 +41,19 @@ To-Do: error handling on line 184, function fread() exit(EXIT_FAILURE); \ } while (0) +#if IS_POSIX +typedef struct { + int ID; + char* file_path; + int file; +} TempFile; +#else typedef struct { int ID; char* file_path; FILE* file; } TempFile; +#endif TempFile* temp_files = NULL; size_t num_temp_files = 0; @@ -74,9 +83,13 @@ int tf_alloc(size_t n, size_t type_size) { return -1; } - // Open the file +#if IS_POSIX + int file = open(file_path, O_RDWR | O_CREAT); + if (file == -1) { +#else FILE* file = fopen(file_path, "w+b"); if (file == NULL) { +#endif line_fail(-2); return -1; } @@ -113,7 +126,11 @@ int tf_alloc(size_t n, size_t type_size) { int tf_free(int ID) { size_t index = (size_t) ID; +#if IS_POSIX + close(temp_files[index].file); +#else fclose(temp_files[index].file); +#endif // Delete the file if (remove(temp_files[index].file_path) != 0) { @@ -142,53 +159,105 @@ int tf_free(int ID) { int tf_write(int ID, size_t offset, void* data, size_t data_size) { size_t index = (size_t) ID; +#if IS_POSIX + // Check file handler for -1 + int file = temp_files[index].file; + if (file == -1) +#else // Check file handler for NULL FILE* file = temp_files[index].file; if (file == NULL) +#endif return -1; // Set the position - fseek(file, offset, SEEK_SET); - - // Write the data to the file - size_t bytes_written = fwrite(data, 1, data_size, file); - - if (bytes_written != data_size) - return -1; - - if (fdatasync(file) == -1) { +#if IS_POSIX + if (lseek(file, offset, SEEK_SET) == -1) { +#else + if (fseek(file, offset, SEEK_SET) == -1) { +#endif line_fail(-1); return -1; } + // Write the data to the file +#if IS_POSIX + ssize_t bytes_written = write(file, data, data_size); +#else + size_t bytes_written = fwrite(data, 1, data_size, file); +#endif + + if ( +#if IS_POSIX + (size_t) +#endif + bytes_written != data_size) { + errno = EIO; + return -1; + } + +#if IS_POSIX + if (fsync(file) == -1) { + line_fail(-1); + return -1; + } +#else + fflush(file); +#endif + return 0; } int tf_read(int ID, size_t offset, void* dest, size_t data_size) { size_t index = (size_t) ID; - // Open the file in read mode +#if IS_POSIX + int file = temp_files[index].file; + if (file == -1) +#else FILE* file = temp_files[index].file; if (file == NULL) +#endif return -1; // Read the data from the file void* data = malloc(data_size); if (data == NULL) { +#if IS_POSIX + close(file); +#else fclose(file); - line_fail(-3); +#endif + line_fail(-7); return -1; } - // Initialize the memory in the data buffer memset(data, 0, data_size); // clear destination - fseek(file, offset, SEEK_SET); // set position - size_t bytes_read = fread(data, 1, data_size, file); // read bytes + // Set the position +#if IS_POSIX + if (lseek(file, offset, SEEK_SET) == -1) { +#else + if (fseek(file, offset, SEEK_SET) == -1) { +#endif + line_fail(-1); + return -1; + } + + // read bytes +#if IS_POSIX + ssize_t bytes_read = read(file, data, data_size); +#else + size_t bytes_read = fread(data, 1, data_size, file); +#endif memcpy(dest, data, data_size); free(data); // Free the allocated memory - if (bytes_read != data_size) { + if ( +#if IS_POSIX + (size_t) +#endif + bytes_read != data_size) { errno = EIO; return -1; }