PAX

 view release on metacpan or  search on metacpan

lib/PAX/StandaloneImage.pm  view on Meta::CPAN

    if (snprintf(code_root, code_size, "%s/code", root) >= (int)code_size) return 111;
    if (snprintf(runtime_root, runtime_size, "%s/runtime", root) >= (int)runtime_size) return 111;
    if (snprintf(assets_root, assets_size, "%s/assets", root) >= (int)assets_size) return 111;
    return 0;
}

static int extract_roots(const char *root, char *code_root, size_t code_size, char *runtime_root, size_t runtime_size, char *assets_root, size_t assets_size) {
    if (resolve_roots(root, code_root, code_size, runtime_root, runtime_size, assets_root, assets_size) != 0) return 111;
    if (write_package_root(code_root, _binary_code_pkg_start, (unsigned long)(_binary_code_pkg_end - _binary_code_pkg_start)) != 0) return 111;
    if (write_package_root(runtime_root, _binary_runtime_pkg_start, (unsigned long)(_binary_runtime_pkg_end - _binary_runtime_pkg_start)) != 0) return 111;
    if (write_package_root(assets_root, _binary_assets_pkg_start, (unsigned long)(_binary_assets_pkg_end - _binary_assets_pkg_start)) != 0) return 111;
    if ($native_package_present && write_package_root(root, _binary_native_pkg_start, (unsigned long)(_binary_native_pkg_end - _binary_native_pkg_start)) != 0) return 111;
    return 0;
}

static int extract_runtime(char *tmpdir, size_t size, char *entrypoint, size_t entry_size, char *perl_exec, size_t perl_size, char *libpath, size_t lib_size, char *asset_root, size_t asset_size) {
    const char *base = getenv("TMPDIR");
    if (!base || !*base) base = "/tmp";
    char code_root[4096];
    char runtime_root[4096];
    char assets_root[4096];
    char runtime_lib_root[4096];
    char manifest_path[4096];
    FILE *manifest_out;
    if (snprintf(tmpdir, size, "%s/pax-standalone-cache-%s", base, $source_hash) >= (int)size) return 111;
    if (mkdir(tmpdir, 0700) != 0 && errno != EEXIST) return 111;
    if (resolve_roots(tmpdir, code_root, sizeof(code_root), runtime_root, sizeof(runtime_root), assets_root, sizeof(assets_root)) != 0) return 111;
    if (snprintf(manifest_path, sizeof(manifest_path), "%s/manifest.json", tmpdir) >= (int)sizeof(manifest_path)) return 111;
    if (access(manifest_path, F_OK) != 0 || access(code_root, F_OK) != 0 || access(runtime_root, F_OK) != 0 || access(assets_root, F_OK) != 0) {
        if (extract_roots(tmpdir, code_root, sizeof(code_root), runtime_root, sizeof(runtime_root), assets_root, sizeof(assets_root)) != 0) return 111;
        manifest_out = fopen(manifest_path, "wb");
        if (!manifest_out) return 111;
        if (fwrite($manifest_literal, 1, strlen($manifest_literal), manifest_out) != strlen($manifest_literal)) {
            fclose(manifest_out);
            return 111;
        }
        fclose(manifest_out);
    }

    if (snprintf(entrypoint, entry_size, "%s/%s", code_root, $entrypoint_logical) >= (int)entry_size) return 111;
    if (snprintf(asset_root, asset_size, "%s", assets_root) >= (int)asset_size) return 111;
    if (snprintf(runtime_lib_root, sizeof(runtime_lib_root), "%s/lib", runtime_root) >= (int)sizeof(runtime_lib_root)) return 111;
    if (strcmp($runtime_mode, "bundled_perl") == 0 && strlen($runtime_perl) > 0) {
        if (snprintf(perl_exec, perl_size, "%s/%s", runtime_root, $runtime_perl) >= (int)perl_size) return 111;
        chmod(perl_exec, 0700);
    } else {
        if (snprintf(perl_exec, perl_size, "%s", "perl") >= (int)perl_size) return 111;
    }
    libpath[0] = 0;
    for (unsigned long i = 0; i < pax_code_lib_roots_count; i++) {
        char top[4096];
        if (snprintf(top, sizeof(top), "%s/%s", code_root, pax_code_lib_roots[i]) >= (int)sizeof(top)) return 111;
        if (append_path(libpath, lib_size, top) != 0) return 111;
    }
    for (unsigned long i = 0; i < pax_runtime_inc_roots_count; i++) {
        char top[4096];
        if (snprintf(top, sizeof(top), "%s/%s", runtime_root, pax_runtime_inc_roots[i]) >= (int)sizeof(top)) return 111;
        if (append_path(libpath, lib_size, top) != 0) return 111;
    }

    setenv("PAX_EMBEDDED_ASSET_ROOT", asset_root, 1);
    setenv("PAX_STANDALONE_TMPDIR", tmpdir, 1);
    setenv("PAX_STANDALONE_MANIFEST_PATH", manifest_path, 1);
    if (access(runtime_lib_root, F_OK) == 0) {
        const char *old_ld = getenv("LD_LIBRARY_PATH");
        char merged_ld[16384];
        if (old_ld && *old_ld) snprintf(merged_ld, sizeof(merged_ld), "%s:%s", runtime_lib_root, old_ld);
        else snprintf(merged_ld, sizeof(merged_ld), "%s", runtime_lib_root);
        setenv("LD_LIBRARY_PATH", merged_ld, 1);
    }
    return 0;
}

int main(int argc, char **argv) {
    if (argc > 1 && strcmp(argv[1], "--pax-standalone-inspect") == 0) {
        puts($manifest_literal);
        return 0;
    }
    if (argc == 2 && strcmp(argv[1], "version") == 0 && strlen($fast_version) > 0) {
        puts($fast_version);
        return 0;
    }
    if (argc > 2 && strcmp(argv[1], "--pax-standalone-extract") == 0) {
        char code_root[4096];
        char runtime_root[4096];
        char assets_root[4096];
        if (mkdir(argv[2], 0700) != 0 && errno != EEXIST) return 111;
        if (extract_roots(argv[2], code_root, sizeof(code_root), runtime_root, sizeof(runtime_root), assets_root, sizeof(assets_root)) != 0) return 111;
        puts(argv[2]);
        return 0;
    }

    char tmpdir[4096];
    char entrypoint[4096];
    char perl_exec[4096];
    char libpath[8192];
    char asset_root[4096];
    if (extract_runtime(tmpdir, sizeof(tmpdir), entrypoint, sizeof(entrypoint), perl_exec, sizeof(perl_exec), libpath, sizeof(libpath), asset_root, sizeof(asset_root)) != 0) {
        fprintf(stderr, "failed to extract standalone payload\\n");
        return 111;
    }
    if (argc > 0 && argv[0] && *argv[0]) {
        setenv("PAX_STANDALONE_EXECUTABLE", argv[0], 1);
    }

    if (strlen(libpath) > 0) {
        const char *old = getenv("PERL5LIB");
        char merged[16384];
        if (old && *old) snprintf(merged, sizeof(merged), "%s:%s", libpath, old);
        else snprintf(merged, sizeof(merged), "%s", libpath);
        setenv("PERL5LIB", merged, 1);
    }

    char **next = calloc((size_t)argc + 5, sizeof(char *));
    if (!next) return 111;
    next[0] = perl_exec;
    next[1] = "-MPAX::StandaloneRuntime";
    next[2] = "-e";
    next[3] = $bootstrap_code;
    next[4] = entrypoint;
    for (int i = 1; i < argc; i++) next[i + 4] = argv[i];



( run in 1.133 second using v1.01-cache-2.11-cpan-71847e10f99 )