diff --git a/c_src/blob.c b/c_src/blob.c index 2d6551b..01231a6 100644 --- a/c_src/blob.c +++ b/c_src/blob.c @@ -39,7 +39,7 @@ geef_blob_content(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) return atoms.error; if (!enif_alloc_binary(len, &bin)) - return atoms.error; + return geef_oom(env); memcpy(bin.data, content, len); diff --git a/c_src/commit.c b/c_src/commit.c index 901dcee..9114288 100644 --- a/c_src/commit.c +++ b/c_src/commit.c @@ -18,7 +18,7 @@ geef_commit_tree_id(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) id = git_commit_tree_id((git_commit *) obj->obj); if (geef_oid_bin(&bin, id) < 0) - return atoms.error; + return geef_oom(env); return enif_make_binary(env, &bin); } diff --git a/c_src/geef.c b/c_src/geef.c index 1b08a58..210077b 100644 --- a/c_src/geef.c +++ b/c_src/geef.c @@ -73,6 +73,9 @@ static int load(ErlNifEnv *env, void **priv, ERL_NIF_TERM load_info) atoms.timesort = enif_make_atom(env, "sort_time"); atoms.reversesort = enif_make_atom(env, "sort_reverse"); atoms.iterover = enif_make_atom(env, "iterover"); + /* Errors */ + atoms.enomem = enif_make_atom(env, "enomem"); + atoms.eunknown = enif_make_atom(env, "eunknown"); return 0; } @@ -92,24 +95,34 @@ geef_error(ErlNifEnv *env) { const git_error *error; ErlNifBinary bin; - const char *message; size_t len; error = giterr_last(); - if (error && error->message) - message = error->message; - else - message = "No message specified"; - len = strlen(message); + if (!error) + return enif_make_tuple2(env, atoms.error, atoms.eunknown); + + if (error->klass == GITERR_NOMEMORY) + return geef_oom(env); + + if (!error->message) + return enif_make_tuple2(env, atoms.error, atoms.eunknown); + + len = strlen(error->message); if (!enif_alloc_binary(len, &bin)) - return atoms.error; + return geef_oom(env); - memcpy(bin.data, message, len); + memcpy(bin.data, error->message, len); return enif_make_tuple2(env, atoms.error, enif_make_binary(env, &bin)); } +ERL_NIF_TERM +geef_oom(ErlNifEnv *env) +{ + return enif_make_tuple2(env, atoms.error, atoms.enomem); +} + static ErlNifFunc geef_funcs[] = { {"repository_init", 2, geef_repository_init}, diff --git a/c_src/geef.h b/c_src/geef.h index bd83944..acd7808 100644 --- a/c_src/geef.h +++ b/c_src/geef.h @@ -4,6 +4,7 @@ #include "erl_nif.h" ERL_NIF_TERM geef_error(ErlNifEnv *env); +ERL_NIF_TERM geef_oom(ErlNifEnv *env); typedef struct { ERL_NIF_TERM ok; @@ -21,6 +22,9 @@ typedef struct { ERL_NIF_TERM timesort; ERL_NIF_TERM reversesort; ERL_NIF_TERM iterover; + + ERL_NIF_TERM enomem; + ERL_NIF_TERM eunknown; } geef_atoms; extern geef_atoms atoms; diff --git a/c_src/index.c b/c_src/index.c index f84ca4a..4c1d10f 100644 --- a/c_src/index.c +++ b/c_src/index.c @@ -19,7 +19,7 @@ geef_index_new(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) index = enif_alloc_resource(geef_index_type, sizeof(geef_index)); if (!index) - return atoms.error; + return geef_oom(env); if (git_index_new(&index->index) < 0) return geef_error(env); @@ -69,7 +69,7 @@ geef_index_write_tree(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) return geef_error(env); if (geef_oid_bin(&bin, &id) < 0) - return atoms.error; + return geef_oom(env); return enif_make_tuple2(env, atoms.ok, enif_make_binary(env, &bin)); } diff --git a/c_src/object.c b/c_src/object.c index 1e40633..b90f064 100644 --- a/c_src/object.c +++ b/c_src/object.c @@ -64,7 +64,7 @@ geef_object_lookup(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) obj = enif_alloc_resource(geef_object_type, sizeof(geef_object)); if (!obj) - return atoms.error; + return geef_oom(env); if (git_object_lookup(&obj->obj, repo->repo, &id, GIT_OBJ_ANY) < 0) { enif_release_resource(obj); @@ -94,7 +94,7 @@ geef_object_id(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) id = git_object_id(obj->obj); if (geef_oid_bin(&bin, id) < 0) - return atoms.error; + return geef_oom(env); return enif_make_tuple2(env, atoms.ok, enif_make_binary(env, &bin)); } diff --git a/c_src/oid.c b/c_src/oid.c index 2e54ac3..a0cf889 100644 --- a/c_src/oid.c +++ b/c_src/oid.c @@ -26,7 +26,7 @@ geef_oid_fmt(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) return enif_make_badarg(env); if (!enif_alloc_binary(GIT_OID_HEXSZ, &bin_out)) - return atoms.error; + return geef_oom(env); git_oid_fromraw(&id, bin.data); git_oid_fmt((char *)bin_out.data, &id); @@ -46,7 +46,7 @@ geef_oid_parse(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) git_oid_fromstrn(&id, (const char *)bin.data, bin.size); if (geef_oid_bin(&bin_out, &id) < 0) - return atoms.error; + return geef_oom(env); return enif_make_binary(env, &bin_out); } diff --git a/c_src/reference.c b/c_src/reference.c index bae2ce8..c408a20 100644 --- a/c_src/reference.c +++ b/c_src/reference.c @@ -38,7 +38,7 @@ geef_reference_list(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) on_error: git_strarray_free(&array); - return atoms.error; + return geef_oom(env); } ERL_NIF_TERM @@ -60,7 +60,7 @@ geef_reference_lookup(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) name = malloc(bin.size + 1); if (!name) - return atoms.error; + return geef_oom(env); memcpy(name, bin.data, bin.size); name[bin.size] = '\0'; @@ -142,7 +142,7 @@ geef_reference_glob(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) glob = malloc(bin.size + 1); if (!glob) - return atoms.error; + return geef_oom(env); memcpy(glob, bin.data, bin.size); glob[bin.size] = '\0'; @@ -173,7 +173,7 @@ geef_reference_target(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) id = git_reference_target(ref->ref); if (geef_oid_bin(&bin, id) < 0) - return atoms.error; + return geef_oom(env); } else { const char *name; size_t len; @@ -182,7 +182,7 @@ geef_reference_target(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) len = strlen(name); if (enif_alloc_binary(len, &bin) < 0) - return atoms.error; + return geef_oom(env); memcpy(bin.data, name, len + 1); } @@ -206,7 +206,7 @@ geef_reference_to_id(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) name = malloc(bin.size + 1); if (!name) - return atoms.error; + return geef_oom(env); memcpy(name, bin.data, bin.size); name[bin.size] = '\0'; @@ -215,7 +215,7 @@ geef_reference_to_id(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) return geef_error(env); if (geef_oid_bin(&bin, &id) < 0) - return atoms.error; + return geef_oom(env); return enif_make_tuple2(env, atoms.ok, enif_make_binary(env, &bin)); } @@ -268,7 +268,7 @@ geef_reference_create(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) /* Allocate the extra byte for the NUL terminator */ if (!enif_realloc_binary(&name, name.size + 1)) - return atoms.error; + return geef_oom(env); name.data[name.size-1] = '\0'; @@ -283,7 +283,7 @@ geef_reference_create(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) } else if (enif_is_identical(argv[2], atoms.symbolic)) { /* Allocate the extra byte for the NUL terminator */ if (!enif_realloc_binary(&target, target.size + 1)) - return atoms.error; + return geef_oom(env); target.data[target.size - 1] = '\0'; ptarget = (const char *) target.data; diff --git a/c_src/repository.c b/c_src/repository.c index cadd174..952cee1 100644 --- a/c_src/repository.c +++ b/c_src/repository.c @@ -32,7 +32,7 @@ geef_repository_init(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) path = malloc(bin.size + 1); if (!path) - return atoms.error; + return geef_oom(env); memcpy(path, bin.data, bin.size); path[bin.size] = '\0'; @@ -68,7 +68,7 @@ geef_repository_open(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) path = malloc(bin.size + 1); if (!path) - return atoms.error; + return geef_oom(env); memcpy(path, bin.data, bin.size); path[bin.size] = '\0'; @@ -100,7 +100,7 @@ geef_repository_discover(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) path = malloc(bin.size + 1); if (!path) - return atoms.error; + return geef_oom(env); memcpy(path, bin.data, bin.size); path[bin.size] = '\0'; @@ -108,7 +108,7 @@ geef_repository_discover(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) buffer_len = 256; buffer = malloc(buffer_len); if (!buffer) - return atoms.error; + return geef_oom(env); while ((error = git_repository_discover(buffer, buffer_len, path, 0, NULL)) < 0 && giterr_last()->klass == GITERR_REPOSITORY) { @@ -118,7 +118,7 @@ geef_repository_discover(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) if (!tmp) { free(path); free(buffer); - return atoms.error; + return geef_oom(env); } buffer = tmp; @@ -134,7 +134,7 @@ geef_repository_discover(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) buffer_len = strlen(buffer); if (!enif_alloc_binary(buffer_len, &res_bin)) { free(buffer); - return atoms.error; + return geef_oom(env); } memcpy(res_bin.data, buffer, buffer_len); @@ -158,7 +158,7 @@ geef_repository_path(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) len = strlen(path); if (!enif_alloc_binary(len, &bin)) - return atoms.error; + return geef_oom(env); memcpy(bin.data, path, len); return enif_make_binary(env, &bin); @@ -182,7 +182,7 @@ geef_repository_workdir(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) len = strlen(path); if (!enif_alloc_binary(len, &bin)) - return atoms.error; + return geef_oom(env); memcpy(bin.data, path, len); return enif_make_binary(env, &bin); @@ -266,7 +266,7 @@ geef_odb_write(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) return geef_error(env); if (geef_oid_bin(&oid_bin, &oid) < 0) - return atoms.error; + return geef_oom(env); return enif_make_tuple2(env, atoms.ok, enif_make_binary(env, &oid_bin)); } diff --git a/c_src/revwalk.c b/c_src/revwalk.c index 9b13433..0a85f60 100644 --- a/c_src/revwalk.c +++ b/c_src/revwalk.c @@ -23,7 +23,7 @@ geef_revwalk_new(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) walk = enif_alloc_resource(geef_revwalk_type, sizeof(geef_revwalk)); if (!walk) - return atoms.error; + return geef_oom(env); if (git_revwalk_new(&walk->walk, repo->repo) < 0) { enif_release_resource(walk); @@ -70,7 +70,7 @@ geef_revwalk_next(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) return enif_make_badarg(env); if (!enif_alloc_binary(GIT_OID_RAWSZ, &bin)) - return atoms.error; + return geef_oom(env); if ((error = git_revwalk_next((git_oid *)bin.data, walk->walk)) < 0) { if (error == GIT_ITEROVER) diff --git a/c_src/tree.c b/c_src/tree.c index 1f7cfca..7062425 100644 --- a/c_src/tree.c +++ b/c_src/tree.c @@ -24,11 +24,11 @@ static ERL_NIF_TERM tree_entry_to_term(ErlNifEnv *env, const git_tree_entry *ent ErlNifBinary name, oid; if (geef_oid_bin(&oid, git_tree_entry_id(entry)) < 0) - return atoms.error; + return geef_oom(env); if (geef_string_bin(&name, git_tree_entry_name(entry)) < 0) { enif_release_binary(&name); - return atoms.error; + return geef_oom(env); } return enif_make_tuple5(env, atoms.ok, enif_make_int(env, git_tree_entry_filemode(entry)), @@ -54,7 +54,7 @@ geef_tree_bypath(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) path = malloc(bin.size + 1); if (!path) - return atoms.error; + return geef_oom(env); memcpy(path, bin.data, bin.size); path[bin.size] = '\0';