2222 #endif
2323#endif
2424
25- #include < limits >
25+ #include < cctype >
2626#include < cmath>
27+ #include < cstdio>
2728#include < cstring>
2829#include < fstream>
29- #include < iostream>
30- #include < cctype>
31- #include < cstdio>
30+ #include < limits>
31+
32+
33+ #if defined(_WIN32)
34+ #include < io.h>
35+ #else
36+ #include < unistd.h>
37+ #if defined(__APPLE__)
38+ #include < fcntl.h>
39+ #endif
40+ #endif
3241
3342static constexpr short TJ_MAX_NUMBER_OF_DIGGITS = 19 ;
3443static constexpr short TJ_DEFAULT_STRING_READ_SIZE = 10 ;
@@ -4198,8 +4207,8 @@ namespace TinyJSON
41984207 TJHelper::copy_string (journal_suffix, tmp_file_path + file_path_length, journal_length);
41994208 tmp_file_path[file_path_length + journal_length] = TJ_NULL_TERMINATOR ;
42004209
4201- // try and open the temporary file...
4202- std::ofstream outFile ((const char *)tmp_file_path, std::ios::out | std::ios::binary );
4210+ // try and open the temporary file using C-style FILE* for direct OS sync access
4211+ FILE * outFile = std::fopen ((const char *)tmp_file_path, " wb " );
42034212 if (!outFile)
42044213 {
42054214 write_result.assign_exception_message (" Unable to open file for writing." );
@@ -4211,39 +4220,59 @@ namespace TinyJSON
42114220 if (write_result.options ().byte_order_mark == write_options::utf8)
42124221 {
42134222 char utf8_marker[3 ]{ TJ_UTF8_BOM0 , TJ_UTF8_BOM1 , TJ_UTF8_BOM2 };
4214- outFile.write (utf8_marker, 3 );
4215- if (!outFile)
4223+ if (std::fwrite (utf8_marker, 1 , 3 , outFile) != 3 )
42164224 {
42174225 write_result.assign_exception_message (" Unable to write UTF-8 BOM." );
4226+ std::fclose (outFile);
42184227 delete[] tmp_file_path;
42194228 write_result.throw_if_exception ();
42204229 return false ;
42214230 }
42224231 }
42234232
42244233 auto length = TJHelper::string_length (json);
4225- outFile.write ((const char *)json, length * sizeof (TJCHAR ));
4226-
4227- if (!outFile)
4234+ if (std::fwrite (json, sizeof (TJCHAR ), length, outFile) != length)
42284235 {
42294236 write_result.assign_exception_message (" Unable to write to file." );
4237+ std::fclose (outFile);
42304238 delete[] tmp_file_path;
42314239 write_result.throw_if_exception ();
42324240 return false ;
42334241 }
42344242
4235- outFile. flush ();
4236- if (! outFile)
4243+ // Flush C-runtime buffers to the OS
4244+ if (std::fflush ( outFile) != 0 )
42374245 {
4238- write_result.assign_exception_message (" Unable to flush the file to disk." );
4246+ write_result.assign_exception_message (" Unable to flush the C-runtime buffer." );
4247+ std::fclose (outFile);
42394248 delete[] tmp_file_path;
42404249 write_result.throw_if_exception ();
42414250 return false ;
42424251 }
42434252
4244- outFile.close ();
4253+ // Force the OS to flush its buffers to physical disk (Hardware Sync)
4254+ int fd = -1 ;
4255+ #if defined(_WIN32)
4256+ fd = _fileno (outFile);
4257+ if (fd != -1 && _commit (fd) != 0 )
4258+ {
4259+ // Optional: log error if sync fails
4260+ }
4261+ #else
4262+ fd = fileno (outFile);
4263+ if (fd != -1 )
4264+ {
4265+ #if defined(__APPLE__)
4266+ // macOS specific: ensures data is physically written to the drive
4267+ if (fcntl (fd, F_FULLFSYNC ) == -1 ) { /* handle error if critical */ }
4268+ #else
4269+ // General POSIX
4270+ if (fsync (fd) == -1 ) { /* handle error if critical */ }
4271+ #endif
4272+ }
4273+ #endif
42454274
4246- if (! outFile)
4275+ if (std::fclose ( outFile) != 0 )
42474276 {
42484277 write_result.assign_exception_message (" Unable to close the file." );
42494278 delete[] tmp_file_path;
0 commit comments