| 261 | } |
| 262 | |
| 263 | static bool diag_directory_prepare(void) { |
| 264 | char tmp_base[CBM_PATH_MAX]; |
| 265 | char directory_template[CBM_PATH_MAX]; |
| 266 | int written = |
| 267 | snprintf(directory_template, sizeof(directory_template), "%s/cbm-diagnostics-%d-XXXXXX", |
| 268 | diag_tmp_base(tmp_base, sizeof(tmp_base)), (int)getpid()); |
| 269 | if (written <= 0 || (size_t)written >= sizeof(directory_template) || |
| 270 | !cbm_mkdtemp(directory_template)) { |
| 271 | return false; |
| 272 | } |
| 273 | written = |
| 274 | snprintf(g_diag_directory_path, sizeof(g_diag_directory_path), "%s", directory_template); |
| 275 | if (written <= 0 || (size_t)written >= sizeof(g_diag_directory_path)) { |
| 276 | (void)cbm_rmdir(directory_template); |
| 277 | return false; |
| 278 | } |
| 279 | |
| 280 | #ifdef _WIN32 |
| 281 | wchar_t *wide_directory = cbm_path_to_wide(g_diag_directory_path); |
| 282 | HANDLE handle = |
| 283 | wide_directory |
| 284 | ? CreateFileW(wide_directory, FILE_READ_ATTRIBUTES | READ_CONTROL, |
| 285 | FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, |
| 286 | OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, |
| 287 | NULL) |
| 288 | : INVALID_HANDLE_VALUE; |
| 289 | free(wide_directory); |
| 290 | cbm_private_file_lock_status_t status = CBM_PRIVATE_FILE_LOCK_IO; |
| 291 | if (handle != INVALID_HANDLE_VALUE) { |
| 292 | status = cbm_private_lock_directory_adopt_windows(handle, g_diag_directory_path, |
| 293 | &g_diag_directory); |
| 294 | if (status != CBM_PRIVATE_FILE_LOCK_OK) { |
| 295 | (void)CloseHandle(handle); |
| 296 | } |
| 297 | } |
| 298 | #else |
| 299 | int flags = O_RDONLY | O_DIRECTORY | O_CLOEXEC | O_NOFOLLOW; |
| 300 | int validation_fd = open(g_diag_directory_path, flags); |
| 301 | int output_fd = open(g_diag_directory_path, flags); |
| 302 | struct stat validation_state; |
| 303 | struct stat output_state; |
| 304 | bool same_directory = |
| 305 | validation_fd >= 0 && output_fd >= 0 && fstat(validation_fd, &validation_state) == 0 && |
| 306 | fstat(output_fd, &output_state) == 0 && validation_state.st_dev == output_state.st_dev && |
| 307 | validation_state.st_ino == output_state.st_ino; |
| 308 | cbm_private_file_lock_status_t status = CBM_PRIVATE_FILE_LOCK_IO; |
| 309 | if (same_directory) { |
| 310 | status = cbm_private_lock_directory_adopt_posix(validation_fd, g_diag_directory_path, |
| 311 | &g_diag_directory); |
| 312 | if (status == CBM_PRIVATE_FILE_LOCK_OK) { |
| 313 | validation_fd = -1; |
| 314 | g_diag_directory_fd = output_fd; |
| 315 | output_fd = -1; |
| 316 | } |
| 317 | } |
| 318 | if (validation_fd >= 0) { |
| 319 | (void)close(validation_fd); |
| 320 | } |
no test coverage detected