#tgz decompress
1 messages · Page 1 of 1 (latest)
const allocator = std.heap.c_allocator;
// Open the file
const handle = try std.fs.cwd().openFile("my.tar.gz", .{});
defer handle.close();
// Create a decompresser
const decompresser = try std.compress.gzip.decompress(allocator, handle.reader());
defer decompresser.deinit();
// Untar the archive using the decompresser
try std.tar.pipeToFileSystem(std.fs.cwd(), decompresser.reader(), .{});
this will decompress the archive and extract the files into the CWD
i am getting this error
tar.zig:15:60: error: expected type '*compress.gzip.Decompress(io.reader.Reader(fs.file.File,error{AccessDenied,BrokenPipe,ConnectionResetByPeer,ConnectionTimedOut,InputOutput,IsDir,NetNameDeleted,NotOpenForReading,OperationAborted,SystemResources,Unexpected,WouldBlock},(function 'read')))', found '*const compress.gzip.Decompress(io.reader.Reader(fs.file.File,error{AccessDenied,BrokenPipe,ConnectionResetByPeer,ConnectionTimedOut,InputOutput,IsDir,NetNameDeleted,NotOpenForReading,OperationAborted,SystemResources,Unexpected,WouldBlock},(function 'read')))' try std.tar.pipeToFileSystem(std.fs.cwd(), decompresser.reader(), .{}); ~~~~~~~~~~~~^~~~~~~ tar.zig:15:60: note: cast discards const qualifier
@dry wolf
now getting this
thread 9916 panic: TODO: unimplemented: tar ModeMode.executable_bit_only C:\zig\lib\std\tar.zig:95:13: 0x7ff67dff7a0d in pipeToFileSystem__anon_3818 (tar.exe.obj) @panic("TODO: unimplemented: tar ModeMode.executable_bit_only"); ^ D:\zig\unzipping\tar.zig:15:67: 0x7ff67dff9885 in main (tar.exe.obj) try std.tar.pipeToFileSystem(std.fs.cwd(), decompresser.reader(), .{}); ^ C:\zig\lib\std\start.zig:518:80: 0x7ff67dff9f20 in main (tar.exe.obj) return @call(.always_inline, callMainWithArgs, .{ @intCast(usize, c_argc), @ptrCast([*][*:0]u8, c_argv), envp }); ^ Unable to dump stack trace: InvalidDebugInfo
@dry wolf
the extension of file which i am trying to decompress is tgz
aight change
try std.tar.pipeToFileSystem(std.fs.cwd(), decompresser.reader(), .{});
to
try std.tar.pipeToFileSystem(std.fs.cwd(), decompresser.reader(), .{ .mode = .ignore });
now this
tar.zig:15:75: error: no field named 'mode' in struct 'tar.Options' try std.tar.pipeToFileSystem(std.fs.cwd(), decompresser.reader(), .{ .mode = .ignore }); ^~~~ C:\zig\lib\std\tar.zig:1:21: note: struct declared here pub const Options = struct { ^~~~~~ referenced by: comptime_0: C:\zig\lib\std\start.zig:61:50 remaining reference traces hidden; use '-freference-trace' to see all reference traces
soory for inconvenience but now i am getting this error
error: InvalidCharacter C:\zig\lib\std\fmt.zig:1927:17: 0x7ff7cd96dfd1 in charToDigit (tar.exe.obj) else => return error.InvalidCharacter, ^ C:\zig\lib\std\fmt.zig:1855:23: 0x7ff7cd934614 in parseWithSign__anon_4751 (tar.exe.obj) const digit = try charToDigit(c, buf_radix); ^ C:\zig\lib\std\fmt.zig:1754:5: 0x7ff7cd926e17 in parseInt__anon_3977 (tar.exe.obj) return parseWithSign(T, buf, radix, .Pos); ^ C:\zig\lib\std\tar.zig:40:9: 0x7ff7cd9266d6 in fileSize (tar.exe.obj) return std.fmt.parseInt(u64, rtrimmed, 8); ^ C:\zig\lib\std\tar.zig:117:27: 0x7ff7cd9281bf in pipeToFileSystem__anon_3818 (tar.exe.obj) const file_size = try header.fileSize(); ^ D:\zig\unzipping\tar.zig:15:5: 0x7ff7cd9298aa in main (tar.exe.obj) try std.tar.pipeToFileSystem(std.fs.cwd(), decompresser.reader(), .{ .mode_mode = .ignore });
hmm, im not entirely sure about that, let me do some local testing and get back to you
okay fine
Hey @dry wolf do you find any work around?
are you sure the tar file is good?
do you mind sending it?
ah lovely, yeah, this is a bug in std.tar
oh
you should file an issue
okay
it trims \x00 from the end of numbers but not spaces
just wondering why is it so
anyway i will file an issue
@vast urchin we have this error because of std.tar.pipeToFileSystem or std.compress.gzip.decompress
it's a std.tar issue
Okay thanks
Should i mark this question as completed
As i have filed the issue
@vast urchin
up to you if you want to wait for that issue to be resolved
Okay then I'll wait
i found the definition of fileSize method
pub fn fileSize(header: Header) !u64 {
const raw = header.bytes[124..][0..12];
const ltrimmed = std.mem.trimLeft(u8, raw, "0");
const rtrimmed = std.mem.trimRight(u8, ltrimmed, "\x00"); <----
if (rtrimmed.len == 0) return 0;
return std.fmt.parseInt(u64, rtrimmed, 8);
}
do we have problem in the 4th line?
if random internet person is correct, it'd be a matter of adding (an empty space) before the \x00
edit the file, place cursor between " and \, press space bar, save and exit; recompile app run see if errors
no adding space starts showing those wiggling lines under it
it needs to be " \x00"
now we have another error
error: FileNotFound
C:\zig\lib\std\os\windows.zig:131:39: 0x7ff67794abef in OpenFile (tar.exe.obj)
.OBJECT_PATH_NOT_FOUND => return error.FileNotFound,
^
C:\zig\lib\std\fs.zig:1385:23: 0x7ff67791579e in createFileW (tar.exe.obj)
.handle = try os.windows.OpenFile(sub_path_w, .{
^
C:\zig\lib\std\fs.zig:1268:13: 0x7ff677909496 in createFile (tar.exe.obj)
return self.createFileW(path_w.span(), flags);
^
C:\zig\lib\std\tar.zig:133:28: 0x7ff6779085cd in pipeToFileSystem__anon_3818 (tar.exe.obj)
var file = try dir.createFile(file_name, .{});
^
D:\zig\unzipping\tar.zig:14:5: 0x7ff67790989a in main (tar.exe.obj)
try std.tar.pipeToFileSystem(std.fs.cwd(), decompresser.reader(), .{ .mode_mode = .ignore });
@vast urchin @frosty herald any idea?
seems like the path isn't being created. could use makePath() for that.
i was able to get the tar file from above decompressed with these changes:
--- ~/Code/zig/zig/lib/std/tar.zig 2023-04-09 14:57:50.227554929 -0700
+++ ~/Code/zig/zig/download/0.11.0-dev.2213+515e1c93e/files/lib/std/tar.zig 2023-04-09 14:57:06.687171566 -0700
@@ -35,7 +35,7 @@
pub fn fileSize(header: Header) !u64 {
const raw = header.bytes[124..][0..12];
const ltrimmed = std.mem.trimLeft(u8, raw, "0");
- const rtrimmed = std.mem.trimRight(u8, ltrimmed, "\x00");
+ const rtrimmed = std.mem.trimRight(u8, ltrimmed, " \x00");
if (rtrimmed.len == 0) return 0;
return std.fmt.parseInt(u64, rtrimmed, 8);
}
@@ -128,8 +128,10 @@
.normal => {
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)) |dirname|
+ try dir.makePath(dirname);
var file = try dir.createFile(file_name, .{});
+
defer file.close();
var file_off: usize = 0;
not sure this is correct, but it does allow it to succeed.
note: i also tried replacing line 132 with try dir.makeDir(dirname); (as is done a few lines above) but it fails if the directory already exists. so i think makePath() is the better alternative.
this is probably the solution, makeDir is also problematic because the parent directory isn't guaranteed to exist or be defined above a child
is there already an open issue?
do you think that the makeDir() is potentially problematic a few lines above too?
this one i mean: https://github.com/ziglang/zig/blob/master/lib/std/tar.zig#L125
yes
looks like this is the issue https://github.com/ziglang/zig/issues/15222. i'll create a pr for this.
created a pr here https://github.com/ziglang/zig/pull/15228
thanks @vale matrix @vast urchin @frosty herald @dry wolf for discussion and help
its working!!
The PR or your code?
btw, i created a much more comprehensive pr for std.tar https://github.com/ziglang/zig/pull/15382
@timid kelp my code