authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-03-26 20:53:29-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2026-03-27 01:27:26-07:00
log79b5433da713a1d60b8651c34a2459833900f4fa
tree0e18662819695b17dafc2b56c6f0e0dea9155c05
parent0d25302d43557d89b868b8925b2e98395d1ebe60

std.tar: rename pipeToFileSystem to extract


1 files changed, 22 insertions(+), 16 deletions(-)

lib/std/tar.zig+22-16
...@@ -120,8 +120,10 @@ pub const Diagnostics = struct {...@@ -120,8 +120,10 @@ pub const Diagnostics = struct {
120 }120 }
121};121};
122122
123/// pipeToFileSystem options123/// Deprecated, renamed to `ExtractOptions`.
124pub const PipeOptions = struct {124pub const PipeOptions = ExtractOptions;
125
126pub const ExtractOptions = struct {
125 /// Number of directory levels to skip when extracting files.127 /// Number of directory levels to skip when extracting files.
126 strip_components: u32 = 0,128 strip_components: u32 = 0,
127 /// How to handle the "mode" property of files from within the tar file.129 /// How to handle the "mode" property of files from within the tar file.
...@@ -580,8 +582,12 @@ pub const PaxIterator = struct {...@@ -580,8 +582,12 @@ pub const PaxIterator = struct {
580 }582 }
581};583};
582584
583/// Saves tar file content to the file systems.585/// Deprecated, renamed to `extract`.
584pub fn pipeToFileSystem(io: Io, dir: Io.Dir, reader: *Io.Reader, options: PipeOptions) !void {586pub const pipeToFileSystem = extract;
587
588/// Ingests tar file from `reader`, populating file contents within `dir`. If
589/// any file would be extracted outside of `dir`, an error is return instead.
590pub fn extract(io: Io, dir: Io.Dir, reader: *Io.Reader, options: ExtractOptions) !void {
585 var file_name_buffer: [std.fs.max_path_bytes]u8 = undefined;591 var file_name_buffer: [std.fs.max_path_bytes]u8 = undefined;
586 var link_name_buffer: [std.fs.max_path_bytes]u8 = undefined;592 var link_name_buffer: [std.fs.max_path_bytes]u8 = undefined;
587 var file_contents_buffer: [1024]u8 = undefined;593 var file_contents_buffer: [1024]u8 = undefined;
...@@ -958,7 +964,7 @@ test Iterator {...@@ -958,7 +964,7 @@ test Iterator {
958 }964 }
959}965}
960966
961test pipeToFileSystem {967test extract {
962 const io = testing.io;968 const io = testing.io;
963 // Example tar file is created from this tree structure:969 // Example tar file is created from this tree structure:
964 // $ tree example970 // $ tree example
...@@ -987,7 +993,7 @@ test pipeToFileSystem {...@@ -987,7 +993,7 @@ test pipeToFileSystem {
987 const dir = tmp.dir;993 const dir = tmp.dir;
988994
989 // Save tar from reader to the file system `dir`995 // Save tar from reader to the file system `dir`
990 pipeToFileSystem(io, dir, &reader, .{996 extract(io, dir, &reader, .{
991 .mode_mode = .ignore,997 .mode_mode = .ignore,
992 .strip_components = 1,998 .strip_components = 1,
993 .exclude_empty_directories = true,999 .exclude_empty_directories = true,
...@@ -1009,7 +1015,7 @@ test pipeToFileSystem {...@@ -1009,7 +1015,7 @@ test pipeToFileSystem {
1009 );1015 );
1010}1016}
10111017
1012test "pipeToFileSystem root_dir" {1018test "extract root_dir" {
1013 const io = testing.io;1019 const io = testing.io;
1014 const data = @embedFile("tar/testdata/example.tar");1020 const data = @embedFile("tar/testdata/example.tar");
1015 var reader: Io.Reader = .fixed(data);1021 var reader: Io.Reader = .fixed(data);
...@@ -1021,7 +1027,7 @@ test "pipeToFileSystem root_dir" {...@@ -1021,7 +1027,7 @@ test "pipeToFileSystem root_dir" {
1021 var diagnostics: Diagnostics = .{ .allocator = testing.allocator };1027 var diagnostics: Diagnostics = .{ .allocator = testing.allocator };
1022 defer diagnostics.deinit();1028 defer diagnostics.deinit();
10231029
1024 pipeToFileSystem(io, tmp.dir, &reader, .{1030 extract(io, tmp.dir, &reader, .{
1025 .strip_components = 1,1031 .strip_components = 1,
1026 .diagnostics = &diagnostics,1032 .diagnostics = &diagnostics,
1027 }) catch |err| {1033 }) catch |err| {
...@@ -1043,7 +1049,7 @@ test "pipeToFileSystem root_dir" {...@@ -1043,7 +1049,7 @@ test "pipeToFileSystem root_dir" {
1043 var diagnostics: Diagnostics = .{ .allocator = testing.allocator };1049 var diagnostics: Diagnostics = .{ .allocator = testing.allocator };
1044 defer diagnostics.deinit();1050 defer diagnostics.deinit();
10451051
1046 pipeToFileSystem(io, tmp.dir, &reader, .{1052 extract(io, tmp.dir, &reader, .{
1047 .strip_components = 0,1053 .strip_components = 0,
1048 .diagnostics = &diagnostics,1054 .diagnostics = &diagnostics,
1049 }) catch |err| {1055 }) catch |err| {
...@@ -1068,7 +1074,7 @@ test "findRoot with single file archive" {...@@ -1068,7 +1074,7 @@ test "findRoot with single file archive" {
10681074
1069 var diagnostics: Diagnostics = .{ .allocator = testing.allocator };1075 var diagnostics: Diagnostics = .{ .allocator = testing.allocator };
1070 defer diagnostics.deinit();1076 defer diagnostics.deinit();
1071 try pipeToFileSystem(io, tmp.dir, &reader, .{ .diagnostics = &diagnostics });1077 try extract(io, tmp.dir, &reader, .{ .diagnostics = &diagnostics });
10721078
1073 try testing.expectEqualStrings("", diagnostics.root_dir);1079 try testing.expectEqualStrings("", diagnostics.root_dir);
1074}1080}
...@@ -1083,12 +1089,12 @@ test "findRoot without explicit root dir" {...@@ -1083,12 +1089,12 @@ test "findRoot without explicit root dir" {
10831089
1084 var diagnostics: Diagnostics = .{ .allocator = testing.allocator };1090 var diagnostics: Diagnostics = .{ .allocator = testing.allocator };
1085 defer diagnostics.deinit();1091 defer diagnostics.deinit();
1086 try pipeToFileSystem(io, tmp.dir, &reader, .{ .diagnostics = &diagnostics });1092 try extract(io, tmp.dir, &reader, .{ .diagnostics = &diagnostics });
10871093
1088 try testing.expectEqualStrings("root", diagnostics.root_dir);1094 try testing.expectEqualStrings("root", diagnostics.root_dir);
1089}1095}
10901096
1091test "pipeToFileSystem strip_components" {1097test "extract strip_components" {
1092 const io = testing.io;1098 const io = testing.io;
1093 const data = @embedFile("tar/testdata/example.tar");1099 const data = @embedFile("tar/testdata/example.tar");
1094 var reader: Io.Reader = .fixed(data);1100 var reader: Io.Reader = .fixed(data);
...@@ -1098,7 +1104,7 @@ test "pipeToFileSystem strip_components" {...@@ -1098,7 +1104,7 @@ test "pipeToFileSystem strip_components" {
1098 var diagnostics: Diagnostics = .{ .allocator = testing.allocator };1104 var diagnostics: Diagnostics = .{ .allocator = testing.allocator };
1099 defer diagnostics.deinit();1105 defer diagnostics.deinit();
11001106
1101 pipeToFileSystem(io, tmp.dir, &reader, .{1107 extract(io, tmp.dir, &reader, .{
1102 .strip_components = 3,1108 .strip_components = 3,
1103 .diagnostics = &diagnostics,1109 .diagnostics = &diagnostics,
1104 }) catch |err| {1110 }) catch |err| {
...@@ -1120,7 +1126,7 @@ fn normalizePath(bytes: []u8) []u8 {...@@ -1120,7 +1126,7 @@ fn normalizePath(bytes: []u8) []u8 {
1120}1126}
11211127
1122// File system mode based on tar header mode and mode_mode options.1128// File system mode based on tar header mode and mode_mode options.
1123fn filePermissions(mode: u32, options: PipeOptions) Io.File.Permissions {1129fn filePermissions(mode: u32, options: ExtractOptions) Io.File.Permissions {
1124 return if (!Io.File.Permissions.has_executable_bit or options.mode_mode == .ignore or (mode & 0o100) == 0)1130 return if (!Io.File.Permissions.has_executable_bit or options.mode_mode == .ignore or (mode & 0o100) == 0)
1125 .default_file1131 .default_file
1126 else1132 else
...@@ -1142,13 +1148,13 @@ test "executable bit" {...@@ -1142,13 +1148,13 @@ test "executable bit" {
1142 const S = std.posix.S;1148 const S = std.posix.S;
1143 const data = @embedFile("tar/testdata/example.tar");1149 const data = @embedFile("tar/testdata/example.tar");
11441150
1145 for ([_]PipeOptions.ModeMode{ .ignore, .executable_bit_only }) |opt| {1151 for ([_]ExtractOptions.ModeMode{ .ignore, .executable_bit_only }) |opt| {
1146 var reader: Io.Reader = .fixed(data);1152 var reader: Io.Reader = .fixed(data);
11471153
1148 var tmp = testing.tmpDir(.{ .follow_symlinks = false });1154 var tmp = testing.tmpDir(.{ .follow_symlinks = false });
1149 //defer tmp.cleanup();1155 //defer tmp.cleanup();
11501156
1151 pipeToFileSystem(io, tmp.dir, &reader, .{1157 extract(io, tmp.dir, &reader, .{
1152 .strip_components = 1,1158 .strip_components = 1,
1153 .exclude_empty_directories = true,1159 .exclude_empty_directories = true,
1154 .mode_mode = opt,1160 .mode_mode = opt,