| 314 | } |
| 315 | |
| 316 | static bool config_sync_parent_directory(const char *path) { |
| 317 | char directory[CBM_SZ_1K]; |
| 318 | if (!config_parent_directory(path, directory, sizeof(directory))) { |
| 319 | return false; |
| 320 | } |
| 321 | int flags = O_RDONLY; |
| 322 | #ifdef O_DIRECTORY |
| 323 | flags |= O_DIRECTORY; |
| 324 | #endif |
| 325 | int descriptor = open(directory, flags); |
| 326 | if (descriptor < 0) { |
| 327 | return false; |
| 328 | } |
| 329 | bool synced = config_sync_descriptor(descriptor); |
| 330 | int sync_error = synced ? 0 : errno; |
| 331 | (void)close(descriptor); |
| 332 | #ifdef ENOTSUP |
| 333 | if (!synced && sync_error == ENOTSUP) { |
| 334 | synced = true; |
| 335 | } |
| 336 | #endif |
| 337 | #ifdef EOPNOTSUPP |
| 338 | if (!synced && sync_error == EOPNOTSUPP) { |
| 339 | synced = true; |
| 340 | } |
| 341 | #endif |
| 342 | if (!synced && sync_error == EINVAL) { |
| 343 | /* Some POSIX filesystems do not implement directory fsync. The temp |
| 344 | * file itself was already synced and rename publication is atomic. */ |
| 345 | synced = true; |
| 346 | } |
| 347 | return synced; |
| 348 | } |
| 349 | |
| 350 | static bool config_write_atomic(const char *path, const char *json, size_t json_length) { |
| 351 | char temporary[CBM_SZ_2K]; |
no test coverage detected