tristanisham / zvm

zvm (Zig Version Manager) lets you easily install/upgrade between different versions of Zig.

Home Page:https://www.zvm.app

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Downloading large file, cURL

tristanisham opened this issue · comments

I'm currently working on a version manager for Zig https://github.com/tristanisham/zvm. I use cURL for my http requests.

While downloading smaller files (a resume) the program works 100% as expected. I use an ArrayList and an ArenaAllocator. But when the files get larger, like Zig's latest version at around 46mb the program spits out the following error.

error: FailedToPerformRequest
/home/tristan/Development/zvm/src/fetch-version.zig:85:9: 0x24ea32 in downloadFile (zvm)
        return CurlError.FailedToPerformRequest;
        ^
/home/tristan/Development/zvm/src/main.zig:68:17: 0x250303 in main (zvm)
                try version.downloadFile(tarball, "./out.tar.xz", &fba);
                ^
The following command exited with error code 1 (expected 0):
cd /home/tristan/Development/zvm && /home/tristan/Development/zvm/zig-out/bin/zvm install master 
error: UnexpectedExitCode
/home/tristan/.zig/lib/std/build/RunStep.zig:277:17: 0x30c77a in runCommand (build)
                return error.UnexpectedExitCode;
                ^
/home/tristan/.zig/lib/std/build/RunStep.zig:183:5: 0x2fa240 in make (build)
    try runCommand(
    ^
/home/tristan/.zig/lib/std/build.zig:3649:9: 0x2a5037 in make (build)
        try self.makeFn(self);
        ^
/home/tristan/.zig/lib/std/build.zig:509:9: 0x292c54 in makeOneStep (build)
        try s.make();
        ^
/home/tristan/.zig/lib/std/build.zig:503:17: 0x292bc2 in makeOneStep (build)
                return err;
                ^
/home/tristan/.zig/lib/std/build.zig:464:13: 0x292922 in make (build)
            try self.makeOneStep(s);
            ^
/home/tristan/.zig/lib/build_runner.zig:223:21: 0x29588a in main (build)
            else => return err

Here's the function code. My current theory is that it has something to do with not enough allocated memory? But I already tried allocating a large enough amount on the stack and the heap using FixedBufferAllocator and ArenaAllocator.

pub fn downloadFile(url: []const u8, path: []const u8, arena: *std.heap.ArenaAllocator) !void {
    var buf = std.ArrayList(u8).init(arena.*.allocator());
    defer buf.deinit();

    if (cURL.curl_global_init(cURL.CURL_GLOBAL_ALL) != cURL.CURLE_OK) {
        return CurlError.CURLGlobalInitFailed;
    }
    defer cURL.curl_global_cleanup();

    // curl easy handle init, or fail
    const handle = cURL.curl_easy_init() orelse return CurlError.CURLHandleInitFailed;
    defer cURL.curl_easy_cleanup(handle);

    // setup curl options
    if (cURL.curl_easy_setopt(handle, cURL.CURLOPT_URL, url.ptr) != cURL.CURLE_OK)
        return CurlError.CouldNotSetURL;

    if (cURL.curl_easy_setopt(handle, cURL.CURLOPT_USERAGENT, "zvm (Zig Version Manager)/v0.0.1") != cURL.CURLE_OK) {
        return CurlError.CouldNotSetUserAgent;
    }
    // set write function callbacks
    if (cURL.curl_easy_setopt(handle, cURL.CURLOPT_WRITEFUNCTION, writeToArrayListCallback) != cURL.CURLE_OK) {
        return CurlError.CouldNotSetWriteCallback;
    }
    if (cURL.curl_easy_setopt(handle, cURL.CURLOPT_WRITEDATA, &buf) != cURL.CURLE_OK) {
        return CurlError.CouldNotSetWriteCallback;
    }

    if (cURL.curl_easy_perform(handle) != cURL.CURLE_OK) {
        return CurlError.FailedToPerformRequest;
    }

    const file = try std.fs.cwd().createFile(path, .{ .read = true });
    defer file.close();
    try file.writeAll(buf.items);
}

How can I create a structure to store such a large amount in memory?