authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-02-29 00:30:34-08:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-02-29 00:30:34-08:00
log3e292e5fc12304148b35d6d60762e9b383d02133
treeb7dea63d1bf0189861a9732e6cc1990d59375dcd
parent83d2eef3e0a8ac3832903631e84f176c68b97425
parentbeca85e644b2bce45143d20df6cf0f1388d37568
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #19128 from ziglang/tar

std.tar: avoid dependency on file system

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

lib/std/tar.zig+34-13
...@@ -231,12 +231,27 @@ fn nullStr(str: []const u8) []const u8 {...@@ -231,12 +231,27 @@ fn nullStr(str: []const u8) []const u8 {
231 return str;231 return str;
232}232}
233233
234pub const IteratorOptions = struct {
235 /// Use a buffer with length `std.fs.MAX_PATH_BYTES` to match file system capabilities.
236 file_name_buffer: []u8,
237 /// Use a buffer with length `std.fs.MAX_PATH_BYTES` to match file system capabilities.
238 link_name_buffer: []u8,
239 diagnostics: ?*Diagnostics = null,
240
241 pub const Diagnostics = Options.Diagnostics;
242};
243
234/// Iterates over files in tar archive.244/// Iterates over files in tar archive.
235/// `next` returns each file in `reader` tar archive.245/// `next` returns each file in `reader` tar archive.
236pub fn iterator(reader: anytype, diagnostics: ?*Options.Diagnostics) Iterator(@TypeOf(reader)) {246pub fn iterator(reader: anytype, options: IteratorOptions) Iterator(@TypeOf(reader)) {
237 return .{247 return .{
238 .reader = reader,248 .reader = reader,
239 .diagnostics = diagnostics,249 .diagnostics = options.diagnostics,
250 .header_buffer = undefined,
251 .file_name_buffer = options.file_name_buffer,
252 .link_name_buffer = options.link_name_buffer,
253 .padding = 0,
254 .file = undefined,
240 };255 };
241}256}
242257
...@@ -246,14 +261,14 @@ fn Iterator(comptime ReaderType: type) type {...@@ -246,14 +261,14 @@ fn Iterator(comptime ReaderType: type) type {
246 diagnostics: ?*Options.Diagnostics,261 diagnostics: ?*Options.Diagnostics,
247262
248 // buffers for heeader and file attributes263 // buffers for heeader and file attributes
249 header_buffer: [Header.SIZE]u8 = undefined,264 header_buffer: [Header.SIZE]u8,
250 file_name_buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined,265 file_name_buffer: []u8,
251 link_name_buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined,266 link_name_buffer: []u8,
252267
253 // bytes of padding to the end of the block268 // bytes of padding to the end of the block
254 padding: usize = 0,269 padding: usize,
255 // current tar file270 // current tar file
256 file: File = undefined,271 file: File,
257272
258 pub const File = struct {273 pub const File = struct {
259 name: []const u8, // name of file, symlink or directory274 name: []const u8, // name of file, symlink or directory
...@@ -305,7 +320,7 @@ fn Iterator(comptime ReaderType: type) type {...@@ -305,7 +320,7 @@ fn Iterator(comptime ReaderType: type) type {
305 }320 }
306321
307 fn initFile(self: *Self) void {322 fn initFile(self: *Self) void {
308 self.file = File{323 self.file = .{
309 .name = self.file_name_buffer[0..0],324 .name = self.file_name_buffer[0..0],
310 .link_name = self.link_name_buffer[0..0],325 .link_name = self.link_name_buffer[0..0],
311 .size = 0,326 .size = 0,
...@@ -357,10 +372,10 @@ fn Iterator(comptime ReaderType: type) type {...@@ -357,10 +372,10 @@ fn Iterator(comptime ReaderType: type) type {
357 },372 },
358 // Prefix header types373 // Prefix header types
359 .gnu_long_name => {374 .gnu_long_name => {
360 self.file.name = try self.readString(@intCast(size), &self.file_name_buffer);375 self.file.name = try self.readString(@intCast(size), self.file_name_buffer);
361 },376 },
362 .gnu_long_link => {377 .gnu_long_link => {
363 self.file.link_name = try self.readString(@intCast(size), &self.link_name_buffer);378 self.file.link_name = try self.readString(@intCast(size), self.link_name_buffer);
364 },379 },
365 .extended_header => {380 .extended_header => {
366 // Use just attributes from last extended header.381 // Use just attributes from last extended header.
...@@ -370,10 +385,10 @@ fn Iterator(comptime ReaderType: type) type {...@@ -370,10 +385,10 @@ fn Iterator(comptime ReaderType: type) type {
370 while (try rdr.next()) |attr| {385 while (try rdr.next()) |attr| {
371 switch (attr.kind) {386 switch (attr.kind) {
372 .path => {387 .path => {
373 self.file.name = try attr.value(&self.file_name_buffer);388 self.file.name = try attr.value(self.file_name_buffer);
374 },389 },
375 .linkpath => {390 .linkpath => {
376 self.file.link_name = try attr.value(&self.link_name_buffer);391 self.file.link_name = try attr.value(self.link_name_buffer);
377 },392 },
378 .size => {393 .size => {
379 var buf: [pax_max_size_attr_len]u8 = undefined;394 var buf: [pax_max_size_attr_len]u8 = undefined;
...@@ -536,7 +551,13 @@ pub fn pipeToFileSystem(dir: std.fs.Dir, reader: anytype, options: Options) !voi...@@ -536,7 +551,13 @@ pub fn pipeToFileSystem(dir: std.fs.Dir, reader: anytype, options: Options) !voi
536 },551 },
537 }552 }
538553
539 var iter = iterator(reader, options.diagnostics);554 var file_name_buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined;
555 var link_name_buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined;
556 var iter = iterator(reader, .{
557 .file_name_buffer = &file_name_buffer,
558 .link_name_buffer = &link_name_buffer,
559 .diagnostics = options.diagnostics,
560 });
540 while (try iter.next()) |file| {561 while (try iter.next()) |file| {
541 switch (file.kind) {562 switch (file.kind) {
542 .directory => {563 .directory => {
lib/std/tar/test.zig+7-1
...@@ -323,9 +323,15 @@ test "tar run Go test cases" {...@@ -323,9 +323,15 @@ test "tar run Go test cases" {
323 },323 },
324 };324 };
325325
326 var file_name_buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined;
327 var link_name_buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined;
328
326 for (cases) |case| {329 for (cases) |case| {
327 var fsb = std.io.fixedBufferStream(case.data);330 var fsb = std.io.fixedBufferStream(case.data);
328 var iter = tar.iterator(fsb.reader(), null);331 var iter = tar.iterator(fsb.reader(), .{
332 .file_name_buffer = &file_name_buffer,
333 .link_name_buffer = &link_name_buffer,
334 });
329 var i: usize = 0;335 var i: usize = 0;
330 while (iter.next() catch |err| {336 while (iter.next() catch |err| {
331 if (case.err) |e| {337 if (case.err) |e| {