authorgravatar for kubkon@jakubkonka.comJakub Konka <kubkon@jakubkonka.com> 2022-08-18 15:32:15+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-08-18 15:54:09-04:00
logb12992cb0172bc2de1f1aae3da57b952dbaf70cd
tree934f13f933e4bbf4c20d5b86624f4775da6419f8
parentf6459721e549e91858edc2e93de398e3e3cae45e

macho: do not open file handle when building static archive

Firstly, opening a file handle is not really needed since we won't even use it, and secondly, this can cause AccessDenied errors on Windows when trying to move a directory from zig-cache/tmp/ to zig-cache/o/ since, without POSIX semantics, it is illegal to move directories with open handles to any of its resources.

2 files changed, 14 insertions(+), 11 deletions(-)

src/link.zig+5-2
...@@ -772,12 +772,15 @@ pub const File = struct {...@@ -772,12 +772,15 @@ pub const File = struct {
772 error.FileNotFound => {},772 error.FileNotFound => {},
773 else => |e| return e,773 else => |e| return e,
774 }774 }
775 try std.fs.rename(775 std.fs.rename(
776 cache_directory.handle,776 cache_directory.handle,
777 tmp_dir_sub_path,777 tmp_dir_sub_path,
778 cache_directory.handle,778 cache_directory.handle,
779 o_sub_path,779 o_sub_path,
780 );780 ) catch |err| switch (err) {
781 error.AccessDenied => unreachable, // We are most likely trying to move a dir with open handles to its resources
782 else => |e| return e,
783 };
781 break;784 break;
782 } else {785 } else {
783 std.fs.rename(786 std.fs.rename(
src/link/MachO.zig+9-9
...@@ -276,22 +276,14 @@ pub fn openPath(allocator: Allocator, options: link.Options) !*MachO {...@@ -276,22 +276,14 @@ pub fn openPath(allocator: Allocator, options: link.Options) !*MachO {
276 if (use_stage1 or options.emit == null) {276 if (use_stage1 or options.emit == null) {
277 return createEmpty(allocator, options);277 return createEmpty(allocator, options);
278 }278 }
279 const emit = options.emit.?;
280 const file = try emit.directory.handle.createFile(emit.sub_path, .{
281 .truncate = false,
282 .read = true,
283 .mode = link.determineMode(options),
284 });
285 errdefer file.close();
286279
280 const emit = options.emit.?;
287 const self = try createEmpty(allocator, options);281 const self = try createEmpty(allocator, options);
288 errdefer {282 errdefer {
289 self.base.file = null;283 self.base.file = null;
290 self.base.destroy();284 self.base.destroy();
291 }285 }
292286
293 self.base.file = file;
294
295 if (build_options.have_llvm and options.use_llvm and options.module != null) {287 if (build_options.have_llvm and options.use_llvm and options.module != null) {
296 // TODO this intermediary_basename isn't enough; in the case of `zig build-exe`,288 // TODO this intermediary_basename isn't enough; in the case of `zig build-exe`,
297 // we also want to put the intermediary object file in the cache while the289 // we also want to put the intermediary object file in the cache while the
...@@ -307,6 +299,14 @@ pub fn openPath(allocator: Allocator, options: link.Options) !*MachO {...@@ -307,6 +299,14 @@ pub fn openPath(allocator: Allocator, options: link.Options) !*MachO {
307 return self;299 return self;
308 }300 }
309301
302 const file = try emit.directory.handle.createFile(emit.sub_path, .{
303 .truncate = false,
304 .read = true,
305 .mode = link.determineMode(options),
306 });
307 errdefer file.close();
308 self.base.file = file;
309
310 if (!options.strip and options.module != null) blk: {310 if (!options.strip and options.module != null) blk: {
311 // TODO once I add support for converting (and relocating) DWARF info from relocatable311 // TODO once I add support for converting (and relocating) DWARF info from relocatable
312 // object files, this check becomes unnecessary.312 // object files, this check becomes unnecessary.