Return {error, enonmem} in OOM situations
This commit is contained in:
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
29
c_src/geef.c
29
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},
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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';
|
||||
|
||||
Reference in New Issue
Block a user