mirror of
https://github.com/ziglang/zig.git
synced 2026-01-20 22:35:24 +00:00
std.tar: fix creation of symlinks with omit_empty_directories
This commit is contained in:
parent
e5c2a7dbca
commit
7b25d050e6
@ -31,6 +31,10 @@ pub const Options = struct {
|
||||
file_name: []const u8,
|
||||
link_name: []const u8,
|
||||
},
|
||||
unable_to_create_file: struct {
|
||||
code: anyerror,
|
||||
file_name: []const u8,
|
||||
},
|
||||
unsupported_file_type: struct {
|
||||
file_name: []const u8,
|
||||
file_type: Header.FileType,
|
||||
@ -44,6 +48,9 @@ pub const Options = struct {
|
||||
d.allocator.free(info.file_name);
|
||||
d.allocator.free(info.link_name);
|
||||
},
|
||||
.unable_to_create_file => |info| {
|
||||
d.allocator.free(info.file_name);
|
||||
},
|
||||
.unsupported_file_type => |info| {
|
||||
d.allocator.free(info.file_name);
|
||||
},
|
||||
@ -211,18 +218,34 @@ pub fn pipeToFileSystem(dir: std.fs.Dir, reader: anytype, options: Options) !voi
|
||||
if (file_size == 0 and unstripped_file_name.len == 0) return;
|
||||
const file_name = try stripComponents(unstripped_file_name, options.strip_components);
|
||||
|
||||
if (std.fs.path.dirname(file_name)) |dir_name| {
|
||||
try dir.makePath(dir_name);
|
||||
}
|
||||
var file = try dir.createFile(file_name, .{});
|
||||
defer file.close();
|
||||
var file = dir.createFile(file_name, .{}) catch |err| switch (err) {
|
||||
error.FileNotFound => again: {
|
||||
const code = code: {
|
||||
if (std.fs.path.dirname(file_name)) |dir_name| {
|
||||
dir.makePath(dir_name) catch |code| break :code code;
|
||||
break :again dir.createFile(file_name, .{}) catch |code| {
|
||||
break :code code;
|
||||
};
|
||||
}
|
||||
break :code err;
|
||||
};
|
||||
const d = options.diagnostics orelse return error.UnableToCreateFile;
|
||||
try d.errors.append(d.allocator, .{ .unable_to_create_file = .{
|
||||
.code = code,
|
||||
.file_name = try d.allocator.dupe(u8, file_name),
|
||||
} });
|
||||
break :again null;
|
||||
},
|
||||
else => |e| return e,
|
||||
};
|
||||
defer if (file) |f| f.close();
|
||||
|
||||
var file_off: usize = 0;
|
||||
while (true) {
|
||||
const temp = try buffer.readChunk(reader, @intCast(rounded_file_size + 512 - file_off));
|
||||
if (temp.len == 0) return error.UnexpectedEndOfStream;
|
||||
const slice = temp[0..@intCast(@min(file_size - file_off, temp.len))];
|
||||
try file.writeAll(slice);
|
||||
if (file) |f| try f.writeAll(slice);
|
||||
|
||||
file_off += slice.len;
|
||||
buffer.advance(slice.len);
|
||||
@ -275,13 +298,26 @@ pub fn pipeToFileSystem(dir: std.fs.Dir, reader: anytype, options: Options) !voi
|
||||
},
|
||||
.hard_link => return error.TarUnsupportedFileType,
|
||||
.symbolic_link => {
|
||||
// The file system path of the symbolic link.
|
||||
const file_name = try stripComponents(unstripped_file_name, options.strip_components);
|
||||
// The data inside the symbolic link.
|
||||
const link_name = header.linkName();
|
||||
|
||||
dir.symLink(link_name, file_name, .{}) catch |err| {
|
||||
dir.symLink(link_name, file_name, .{}) catch |err| again: {
|
||||
const code = code: {
|
||||
if (err == error.FileNotFound) {
|
||||
if (std.fs.path.dirname(file_name)) |dir_name| {
|
||||
dir.makePath(dir_name) catch |code| break :code code;
|
||||
break :again dir.symLink(link_name, file_name, .{}) catch |code| {
|
||||
break :code code;
|
||||
};
|
||||
}
|
||||
}
|
||||
break :code err;
|
||||
};
|
||||
const d = options.diagnostics orelse return error.UnableToCreateSymLink;
|
||||
try d.errors.append(d.allocator, .{ .unable_to_create_sym_link = .{
|
||||
.code = err,
|
||||
.code = code,
|
||||
.file_name = try d.allocator.dupe(u8, file_name),
|
||||
.link_name = try d.allocator.dupe(u8, link_name),
|
||||
} });
|
||||
|
||||
@ -1041,6 +1041,13 @@ fn unpackTarball(f: *Fetch, out_dir: fs.Dir, reader: anytype) RunError!void {
|
||||
}),
|
||||
}));
|
||||
},
|
||||
.unable_to_create_file => |info| {
|
||||
eb.extra.items[note_i] = @intFromEnum(try eb.addErrorMessage(.{
|
||||
.msg = try eb.printString("unable to create file '{s}': {s}", .{
|
||||
info.file_name, @errorName(info.code),
|
||||
}),
|
||||
}));
|
||||
},
|
||||
.unsupported_file_type => |info| {
|
||||
eb.extra.items[note_i] = @intFromEnum(try eb.addErrorMessage(.{
|
||||
.msg = try eb.printString("file '{s}' has unsupported type '{c}'", .{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user