Function pipeToFileSystem [src]

Saves tar file content to the file systems.

Prototype

pub fn pipeToFileSystem(dir: std.fs.Dir, reader: anytype, options: PipeOptions) !void

Parameters

dir: std.fs.Diroptions: PipeOptions

Example

test pipeToFileSystem { // Example tar file is created from this tree structure: // $ tree example // example // ├── a // │   └── file // ├── b // │   └── symlink -> ../a/file // └── empty // $ cat example/a/file // content // $ tar -cf example.tar example // $ tar -tvf example.tar // example/ // example/b/ // example/b/symlink -> ../a/file // example/a/ // example/a/file // example/empty/ const data = @embedFile("tar/testdata/example.tar"); var fbs = std.io.fixedBufferStream(data); const reader = fbs.reader(); var tmp = testing.tmpDir(.{ .no_follow = true }); defer tmp.cleanup(); const dir = tmp.dir; // Save tar from `reader` to the file system `dir` pipeToFileSystem(dir, reader, .{ .mode_mode = .ignore, .strip_components = 1, .exclude_empty_directories = true, }) catch |err| { // Skip on platform which don't support symlinks if (err == error.UnableToCreateSymLink) return error.SkipZigTest; return err; }; try testing.expectError(error.FileNotFound, dir.statFile("empty")); try testing.expect((try dir.statFile("a/file")).kind == .file); try testing.expect((try dir.statFile("b/symlink")).kind == .file); // statFile follows symlink var buf: [32]u8 = undefined; try testing.expectEqualSlices( u8, "../a/file", normalizePath(try dir.readLink("b/symlink", &buf)), ); }

Source

pub fn pipeToFileSystem(dir: std.fs.Dir, reader: anytype, options: PipeOptions) !void { var file_name_buffer: [std.fs.max_path_bytes]u8 = undefined; var link_name_buffer: [std.fs.max_path_bytes]u8 = undefined; var iter = iterator(reader, .{ .file_name_buffer = &file_name_buffer, .link_name_buffer = &link_name_buffer, .diagnostics = options.diagnostics, }); while (try iter.next()) |file| { const file_name = stripComponents(file.name, options.strip_components); if (file_name.len == 0 and file.kind != .directory) { const d = options.diagnostics orelse return error.TarComponentsOutsideStrippedPrefix; try d.errors.append(d.allocator, .{ .components_outside_stripped_prefix = .{ .file_name = try d.allocator.dupe(u8, file.name), } }); continue; } if (options.diagnostics) |d| { try d.findRoot(file_name); } switch (file.kind) { .directory => { if (file_name.len > 0 and !options.exclude_empty_directories) { try dir.makePath(file_name); } }, .file => { if (createDirAndFile(dir, file_name, fileMode(file.mode, options))) |fs_file| { defer fs_file.close(); try file.writeAll(fs_file); } else |err| { const d = options.diagnostics orelse return err; try d.errors.append(d.allocator, .{ .unable_to_create_file = .{ .code = err, .file_name = try d.allocator.dupe(u8, file_name), } }); } }, .sym_link => { const link_name = file.link_name; createDirAndSymlink(dir, link_name, file_name) catch |err| { const d = options.diagnostics orelse return error.UnableToCreateSymLink; try d.errors.append(d.allocator, .{ .unable_to_create_sym_link = .{ .code = err, .file_name = try d.allocator.dupe(u8, file_name), .link_name = try d.allocator.dupe(u8, link_name), } }); }; }, } } }