| ... | @@ -476,46 +476,28 @@ fn make(step: *Step, make_options: Step.MakeOptions) !void { | ... | @@ -476,46 +476,28 @@ fn make(step: *Step, make_options: Step.MakeOptions) !void { |
| 476 | return; | 476 | return; |
| 477 | } else |outer_err| switch (outer_err) { | 477 | } else |outer_err| switch (outer_err) { |
| 478 | error.FileNotFound => { | 478 | error.FileNotFound => { |
| 479 | const sub_dirname = fs.path.dirname(sub_path).?; | 479 | var atomic_file = b.cache_root.handle.createFileAtomic(io, sub_path, .{ |
| 480 | b.cache_root.handle.createDirPath(io, sub_dirname) catch |e| | 480 | .replace = false, |
| 481 | return step.fail("unable to make path '{f}{s}': {t}", .{ b.cache_root, sub_dirname, e }); | 481 | .make_path = true, |
| 482 | | 482 | }) catch |err| return step.fail("failed to create temporary path for '{f}{s}': {t}", .{ |
| 483 | const rand_int = std.crypto.random.int(u64); | 483 | b.cache_root, sub_path, err, |
| 484 | const tmp_sub_path = "tmp" ++ fs.path.sep_str ++ | 484 | }); |
| 485 | std.fmt.hex(rand_int) ++ fs.path.sep_str ++ | 485 | defer atomic_file.deinit(io); |
| 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 | }; | | |
| 494 | | 486 | |
| 495 | b.cache_root.handle.writeFile(io, .{ .sub_path = tmp_sub_path, .data = options.contents.items }) catch |err| { | 487 | atomic_file.file.writeStreamingAll(io, options.contents.items) catch |err| { |
| 496 | return step.fail("unable to write options to '{f}{s}': {t}", .{ | 488 | return step.fail("failed to write options to temporary path for '{f}{s}': {t}", .{ |
| 497 | b.cache_root, tmp_sub_path, err, | 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 | error.PathAlreadyExists => { | 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 | step.result_cached = true; | 495 | step.result_cached = true; |
| 510 | return; | 496 | return; |
| 511 | }, | 497 | }, |
| 512 | else => { | 498 | else => return step.fail("failed to link temporary file into '{f}{s}': {t}", .{ |
| 513 | return step.fail("unable to rename options from '{f}{s}' to '{f}{s}': {t}", .{ | 499 | b.cache_root, sub_path, err, |
| 514 | b.cache_root, tmp_sub_path, | 500 | }), |
| 515 | b.cache_root, sub_path, | | |
| 516 | err, | | |
| 517 | }); | | |
| 518 | }, | | |
| 519 | }; | 501 | }; |
| 520 | }, | 502 | }, |
| 521 | else => |e| return step.fail("unable to access options file '{f}{s}': {t}", .{ | 503 | else => |e| return step.fail("unable to access options file '{f}{s}': {t}", .{ |