| ... | ... | @@ -476,46 +476,28 @@ fn make(step: *Step, make_options: Step.MakeOptions) !void { |
| 476 | 476 | return; |
| 477 | 477 | } else |outer_err| switch (outer_err) { |
| 478 | 478 | error.FileNotFound => { |
| 479 | | const sub_dirname = fs.path.dirname(sub_path).?; |
| 480 | | b.cache_root.handle.createDirPath(io, sub_dirname) catch |e| |
| 481 | | return step.fail("unable to make path '{f}{s}': {t}", .{ b.cache_root, sub_dirname, e }); |
| 482 | | |
| 483 | | const rand_int = std.crypto.random.int(u64); |
| 484 | | const tmp_sub_path = "tmp" ++ fs.path.sep_str ++ |
| 485 | | std.fmt.hex(rand_int) ++ fs.path.sep_str ++ |
| 486 | | basename; |
| 487 | | const tmp_sub_path_dirname = fs.path.dirname(tmp_sub_path).?; |
| 488 | | |
| 489 | | b.cache_root.handle.createDirPath(io, tmp_sub_path_dirname) catch |err| { |
| 490 | | return step.fail("unable to make temporary directory '{f}{s}': {t}", .{ |
| 491 | | b.cache_root, tmp_sub_path_dirname, err, |
| 492 | | }); |
| 493 | | }; |
| 479 | var atomic_file = b.cache_root.handle.createFileAtomic(io, sub_path, .{ |
| 480 | .replace = false, |
| 481 | .make_path = true, |
| 482 | }) catch |err| return step.fail("failed to create temporary path for '{f}{s}': {t}", .{ |
| 483 | b.cache_root, sub_path, err, |
| 484 | }); |
| 485 | defer atomic_file.deinit(io); |
| 494 | 486 | |
| 495 | | b.cache_root.handle.writeFile(io, .{ .sub_path = tmp_sub_path, .data = options.contents.items }) catch |err| { |
| 496 | | return step.fail("unable to write options to '{f}{s}': {t}", .{ |
| 497 | | b.cache_root, tmp_sub_path, err, |
| 487 | atomic_file.file.writeStreamingAll(io, options.contents.items) catch |err| { |
| 488 | return step.fail("failed to write options to temporary path for '{f}{s}': {t}", .{ |
| 489 | b.cache_root, sub_path, err, |
| 498 | 490 | }); |
| 499 | 491 | }; |
| 500 | 492 | |
| 501 | | b.cache_root.handle.rename(tmp_sub_path, b.cache_root.handle, sub_path, io) catch |err| switch (err) { |
| 493 | atomic_file.link(io) catch |err| switch (err) { |
| 502 | 494 | error.PathAlreadyExists => { |
| 503 | | // Other process beat us to it. Clean up the temp file. |
| 504 | | b.cache_root.handle.deleteFile(io, tmp_sub_path) catch |e| { |
| 505 | | try step.addError("warning: unable to delete temp file '{f}{s}': {t}", .{ |
| 506 | | b.cache_root, tmp_sub_path, e, |
| 507 | | }); |
| 508 | | }; |
| 509 | 495 | step.result_cached = true; |
| 510 | 496 | return; |
| 511 | 497 | }, |
| 512 | | else => { |
| 513 | | return step.fail("unable to rename options from '{f}{s}' to '{f}{s}': {t}", .{ |
| 514 | | b.cache_root, tmp_sub_path, |
| 515 | | b.cache_root, sub_path, |
| 516 | | err, |
| 517 | | }); |
| 518 | | }, |
| 498 | else => return step.fail("failed to link temporary file into '{f}{s}': {t}", .{ |
| 499 | b.cache_root, sub_path, err, |
| 500 | }), |
| 519 | 501 | }; |
| 520 | 502 | }, |
| 521 | 503 | else => |e| return step.fail("unable to access options file '{f}{s}': {t}", .{ |