Commit 6b84c8e04c
Changed files (1)
lib
compiler
lib/compiler/std-docs.zig
@@ -1,6 +1,7 @@
const builtin = @import("builtin");
const std = @import("std");
const Allocator = std.mem.Allocator;
+const assert = std.debug.assert;
pub fn main() !void {
var arena_instance = std.heap.ArenaAllocator.init(std.heap.page_allocator);
@@ -140,7 +141,6 @@ fn serveSourcesTar(request: *std.http.Server.Request, context: *Context) !void {
},
});
const w = response.writer();
- try w.writeAll("tar header");
var std_dir = try context.lib_dir.openDir("std", .{ .iterate = true });
defer std_dir.close();
@@ -159,13 +159,27 @@ fn serveSourcesTar(request: *std.http.Server.Request, context: *Context) !void {
else => continue,
}
- try w.writeAll(entry.path);
-
var file = try std_dir.openFile(entry.path, .{});
defer file.close();
+ const stat = try file.stat();
+ const padding = p: {
+ const remainder = stat.size % 512;
+ break :p if (remainder > 0) 512 - remainder else 0;
+ };
+ comptime assert(@sizeOf(TarHeader) == 512);
+
+ var file_header = TarHeader.init();
+ file_header.typeflag = .regular;
+ try file_header.setPath("std", entry.path);
+ try file_header.setSize(stat.size);
+ try file_header.updateChecksum();
+ try w.writeAll(std.mem.asBytes(&file_header));
try w.writeFile(file);
+ try w.writeByteNTimes(0, padding);
}
+ // intentionally omitting the pointless trailer
+ //try w.writeByteNTimes(0, 512 * 2);
try response.end();
}
@@ -369,3 +383,77 @@ fn openBrowserTabThread(gpa: Allocator, url: []const u8) !void {
try child.spawn();
_ = try child.wait();
}
+
+/// Forked from https://github.com/mattnite/tar/blob/main/src/main.zig which is
+/// MIT licensed.
+pub const TarHeader = extern struct {
+ name: [100]u8,
+ mode: [7:0]u8,
+ uid: [7:0]u8,
+ gid: [7:0]u8,
+ size: [11:0]u8,
+ mtime: [11:0]u8,
+ checksum: [7:0]u8,
+ typeflag: FileType,
+ linkname: [100]u8,
+ magic: [5:0]u8,
+ version: [2]u8,
+ uname: [31:0]u8,
+ gname: [31:0]u8,
+ devmajor: [7:0]u8,
+ devminor: [7:0]u8,
+ prefix: [155]u8,
+ pad: [12]u8,
+
+ const FileType = enum(u8) {
+ regular = '0',
+ hard_link = '1',
+ symbolic_link = '2',
+ character = '3',
+ block = '4',
+ directory = '5',
+ fifo = '6',
+ reserved = '7',
+ pax_global = 'g',
+ extended = 'x',
+ _,
+ };
+
+ fn init() TarHeader {
+ var ret = std.mem.zeroes(TarHeader);
+ ret.magic = [_:0]u8{ 'u', 's', 't', 'a', 'r' };
+ ret.version = [_:0]u8{ '0', '0' };
+ return ret;
+ }
+
+ fn setPath(self: *TarHeader, prefix: []const u8, path: []const u8) !void {
+ if (prefix.len + 1 + path.len > 100) {
+ var i: usize = 0;
+ while (i < path.len and path.len - i > 100) {
+ while (path[i] != '/') : (i += 1) {}
+ }
+
+ _ = try std.fmt.bufPrint(&self.prefix, "{s}/{s}", .{ prefix, path[0..i] });
+ _ = try std.fmt.bufPrint(&self.name, "{s}", .{path[i + 1 ..]});
+ } else {
+ _ = try std.fmt.bufPrint(&self.name, "{s}/{s}", .{ prefix, path });
+ }
+ }
+
+ fn setSize(self: *TarHeader, size: u64) !void {
+ _ = try std.fmt.bufPrint(&self.size, "{o:0>11}", .{size});
+ }
+
+ fn updateChecksum(self: *TarHeader) !void {
+ const offset = @offsetOf(TarHeader, "checksum");
+ var checksum: usize = 0;
+ for (std.mem.asBytes(self), 0..) |val, i| {
+ checksum += if (i >= offset and i < offset + @sizeOf(@TypeOf(self.checksum)))
+ ' '
+ else
+ val;
+ }
+
+ _ = try std.fmt.bufPrint(&self.checksum, "{o:0>7}", .{checksum});
+ }
+};