authorgravatar for der.teufel.mail@gmail.comKrzysztof Wolicki <der.teufel.mail@gmail.com> 2023-10-12 00:16:02+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-10-11 20:28:07-07:00
log8c6b0271cc55d4c9ae2793340419df3fd3d2c1d7
tree34e2c7dacf2a90bca7422b08a4f8321fd09c0af0
parent4e188dd66c289a5a6f1e0438360111d5c20a761e

Package.Fetch: wrap operations involving tmp_directory in a block

This makes tmp_directory close before calling renameTmpIntoCache which fixes occurences of those AccessDenied errors that aren't synonymous with PathAlreadyExists on Windows

1 files changed, 41 insertions(+), 39 deletions(-)

src/Package/Fetch.zig+41-39
......@@ -354,53 +354,55 @@ fn runResource(
354354 const rand_int = std.crypto.random.int(u64);
355355 const tmp_dir_sub_path = "tmp" ++ s ++ Manifest.hex64(rand_int);
356356
357 const tmp_directory_path = try cache_root.join(arena, &.{tmp_dir_sub_path});
358 var tmp_directory: Cache.Directory = .{
359 .path = tmp_directory_path,
360 .handle = handle: {
361 const dir = cache_root.handle.makeOpenPathIterable(tmp_dir_sub_path, .{}) catch |err| {
362 try eb.addRootErrorMessage(.{
363 .msg = try eb.printString("unable to create temporary directory '{s}': {s}", .{
364 tmp_directory_path, @errorName(err),
365 }),
366 });
367 return error.FetchFailed;
368 };
369 break :handle dir.dir;
370 },
371 };
372 defer tmp_directory.handle.close();
357 {
358 const tmp_directory_path = try cache_root.join(arena, &.{tmp_dir_sub_path});
359 var tmp_directory: Cache.Directory = .{
360 .path = tmp_directory_path,
361 .handle = handle: {
362 const dir = cache_root.handle.makeOpenPathIterable(tmp_dir_sub_path, .{}) catch |err| {
363 try eb.addRootErrorMessage(.{
364 .msg = try eb.printString("unable to create temporary directory '{s}': {s}", .{
365 tmp_directory_path, @errorName(err),
366 }),
367 });
368 return error.FetchFailed;
369 };
370 break :handle dir.dir;
371 },
372 };
373 defer tmp_directory.handle.close();
373374
374 try unpackResource(f, resource, uri_path, tmp_directory);
375 try unpackResource(f, resource, uri_path, tmp_directory);
375376
376 // Load, parse, and validate the unpacked build.zig.zon file. It is allowed
377 // for the file to be missing, in which case this fetched package is
378 // considered to be a "naked" package.
379 try loadManifest(f, .{ .root_dir = tmp_directory });
377 // Load, parse, and validate the unpacked build.zig.zon file. It is allowed
378 // for the file to be missing, in which case this fetched package is
379 // considered to be a "naked" package.
380 try loadManifest(f, .{ .root_dir = tmp_directory });
380381
381 // Apply the manifest's inclusion rules to the temporary directory by
382 // deleting excluded files. If any error occurred for files that were
383 // ultimately excluded, those errors should be ignored, such as failure to
384 // create symlinks that weren't supposed to be included anyway.
382 // Apply the manifest's inclusion rules to the temporary directory by
383 // deleting excluded files. If any error occurred for files that were
384 // ultimately excluded, those errors should be ignored, such as failure to
385 // create symlinks that weren't supposed to be included anyway.
385386
386 // Empty directories have already been omitted by `unpackResource`.
387 // Empty directories have already been omitted by `unpackResource`.
387388
388 const filter: Filter = .{
389 .include_paths = if (f.manifest) |m| m.paths else .{},
390 };
389 const filter: Filter = .{
390 .include_paths = if (f.manifest) |m| m.paths else .{},
391 };
391392
392 // Compute the package hash based on the remaining files in the temporary
393 // directory.
393 // Compute the package hash based on the remaining files in the temporary
394 // directory.
394395
395 if (builtin.os.tag == .linux and f.job_queue.work_around_btrfs_bug) {
396 // https://github.com/ziglang/zig/issues/17095
397 tmp_directory.handle.close();
398 const iterable_dir = cache_root.handle.makeOpenPathIterable(tmp_dir_sub_path, .{}) catch
399 @panic("btrfs workaround failed");
400 tmp_directory.handle = iterable_dir.dir;
401 }
396 if (builtin.os.tag == .linux and f.job_queue.work_around_btrfs_bug) {
397 // https://github.com/ziglang/zig/issues/17095
398 tmp_directory.handle.close();
399 const iterable_dir = cache_root.handle.makeOpenPathIterable(tmp_dir_sub_path, .{}) catch
400 @panic("btrfs workaround failed");
401 tmp_directory.handle = iterable_dir.dir;
402 }
402403
403 f.actual_hash = try computeHash(f, tmp_directory, filter);
404 f.actual_hash = try computeHash(f, tmp_directory, filter);
405 }
404406
405407 // Rename the temporary directory into the global zig package cache
406408 // directory. If the hash already exists, delete the temporary directory