ww: make allocation failures stage-equivalent
This commit is contained in:
@@ -1728,8 +1728,14 @@ sep_scan_file(struct sepgraph *g, int pi, const char *file,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
errno = 0;
|
||||||
char *canon = realpath(ipath, NULL);
|
char *canon = realpath(ipath, NULL);
|
||||||
if (canon == NULL) {
|
if (canon == NULL) {
|
||||||
|
if (errno == ENOMEM) {
|
||||||
|
sep_fail_nomem();
|
||||||
|
rc = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
errorf(u->pos, "cannot canonicalize package '%s'", name);
|
errorf(u->pos, "cannot canonicalize package '%s'", name);
|
||||||
rc = -1;
|
rc = -1;
|
||||||
break;
|
break;
|
||||||
@@ -2130,8 +2136,12 @@ sep_reverse_import_base(const struct sepgraph *g, const struct seppkg *pkg,
|
|||||||
if (root == NULL) return sep_fail_nomem();
|
if (root == NULL) return sep_fail_nomem();
|
||||||
memcpy(root, p, n);
|
memcpy(root, p, n);
|
||||||
root[n] = '\0';
|
root[n] = '\0';
|
||||||
|
errno = 0;
|
||||||
char *canon = n == 0 ? NULL : realpath(root, NULL);
|
char *canon = n == 0 ? NULL : realpath(root, NULL);
|
||||||
|
int canon_errno = n == 0 ? 0 : errno;
|
||||||
free(root);
|
free(root);
|
||||||
|
if (canon == NULL && canon_errno == ENOMEM)
|
||||||
|
return sep_fail_nomem();
|
||||||
if (canon != NULL) {
|
if (canon != NULL) {
|
||||||
size_t rn = strlen(canon);
|
size_t rn = strlen(canon);
|
||||||
const char *rel = NULL;
|
const char *rel = NULL;
|
||||||
@@ -2149,9 +2159,16 @@ sep_reverse_import_base(const struct sepgraph *g, const struct seppkg *pkg,
|
|||||||
char located[PATH_MAX];
|
char located[PATH_MAX];
|
||||||
if (locate_import(searchpath, rel, located,
|
if (locate_import(searchpath, rel, located,
|
||||||
sizeof located)) {
|
sizeof located)) {
|
||||||
|
errno = 0;
|
||||||
char *selected = realpath(located, NULL);
|
char *selected = realpath(located, NULL);
|
||||||
|
int selected_errno = errno;
|
||||||
int same = selected != NULL
|
int same = selected != NULL
|
||||||
&& strcmp(selected, pkg->canon) == 0;
|
&& strcmp(selected, pkg->canon) == 0;
|
||||||
|
if (selected == NULL
|
||||||
|
&& selected_errno == ENOMEM) {
|
||||||
|
free(canon);
|
||||||
|
return sep_fail_nomem();
|
||||||
|
}
|
||||||
free(selected);
|
free(selected);
|
||||||
if (same) { free(canon); return 1; }
|
if (same) { free(canon); return 1; }
|
||||||
}
|
}
|
||||||
@@ -2896,7 +2913,12 @@ build_one_sep_impl(const char *src, int entry_is_dir,
|
|||||||
g->support_context = sep_context_for(g, toolsrcdir, NULL,
|
g->support_context = sep_context_for(g, toolsrcdir, NULL,
|
||||||
toolsrcdir);
|
toolsrcdir);
|
||||||
if (g->support_context < 0) return 1;
|
if (g->support_context < 0) return 1;
|
||||||
|
errno = 0;
|
||||||
char *tc = realpath(tpath, NULL);
|
char *tc = realpath(tpath, NULL);
|
||||||
|
if (tc == NULL && errno == ENOMEM) {
|
||||||
|
sep_fail_nomem();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
int collision = 0;
|
int collision = 0;
|
||||||
for (int i = 0; i < nproducts; i++) {
|
for (int i = 0; i < nproducts; i++) {
|
||||||
int root_is_support = tc != NULL
|
int root_is_support = tc != NULL
|
||||||
@@ -2914,7 +2936,13 @@ build_one_sep_impl(const char *src, int entry_is_dir,
|
|||||||
"test", userpath, sizeof userpath)) {
|
"test", userpath, sizeof userpath)) {
|
||||||
userdir = 1;
|
userdir = 1;
|
||||||
(void)userdir;
|
(void)userdir;
|
||||||
|
errno = 0;
|
||||||
char *uc = realpath(userpath, NULL);
|
char *uc = realpath(userpath, NULL);
|
||||||
|
if (uc == NULL && errno == ENOMEM) {
|
||||||
|
free(tc);
|
||||||
|
sep_fail_nomem();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
if (tc != NULL && uc != NULL
|
if (tc != NULL && uc != NULL
|
||||||
&& strcmp(tc, uc) != 0)
|
&& strcmp(tc, uc) != 0)
|
||||||
collision = 1;
|
collision = 1;
|
||||||
@@ -3704,22 +3732,24 @@ do_build(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
const char *src = NULL;
|
const char *src = NULL;
|
||||||
struct seplinkflags linkflags = {0};
|
struct seplinkflags linkflags = {0};
|
||||||
size_t incsz = 1;
|
size_t incsz = 0;
|
||||||
for (int i = 0; i < argc; i++) incsz += strlen(argv[i]) + 1;
|
char *incs = NULL;
|
||||||
char incs[incsz];
|
if (include_buffer_for_args(argc, argv, &incs, &incsz) < 0) return 1;
|
||||||
memset(incs, 0, sizeof incs);
|
|
||||||
char outflag[PATH_MAX] = {0};
|
char outflag[PATH_MAX] = {0};
|
||||||
char workdir[PATH_MAX] = {0};
|
char workdir[PATH_MAX] = {0};
|
||||||
int emit_asm = 0;
|
int emit_asm = 0;
|
||||||
int package_only = 0;
|
int package_only = 0;
|
||||||
if (parse_build_flags("build", argc, argv, incs, sizeof incs,
|
if (parse_build_flags("build", argc, argv, incs, incsz,
|
||||||
&linkflags,
|
&linkflags,
|
||||||
outflag, sizeof outflag, workdir, sizeof workdir,
|
outflag, sizeof outflag, workdir, sizeof workdir,
|
||||||
&src, &emit_asm, &package_only) < 0)
|
&src, &emit_asm, &package_only) < 0) {
|
||||||
|
free(incs);
|
||||||
return 2;
|
return 2;
|
||||||
|
}
|
||||||
if (src == NULL) src = ".";
|
if (src == NULL) src = ".";
|
||||||
if (package_only && emit_asm) {
|
if (package_only && emit_asm) {
|
||||||
fprintf(stderr, "ww build: -p and -S cannot be combined\n");
|
fprintf(stderr, "ww build: -p and -S cannot be combined\n");
|
||||||
|
free(incs);
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
struct stat requested;
|
struct stat requested;
|
||||||
@@ -3728,10 +3758,12 @@ do_build(int argc, char **argv)
|
|||||||
int is_dir = 0;
|
int is_dir = 0;
|
||||||
if (!resolve_module(src, incs, resolved, sizeof resolved, &is_dir)) {
|
if (!resolve_module(src, incs, resolved, sizeof resolved, &is_dir)) {
|
||||||
fprintf(stderr, "ww build: cannot find module %s\n", src);
|
fprintf(stderr, "ww build: cannot find module %s\n", src);
|
||||||
|
free(incs);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (package_only && !is_dir) {
|
if (package_only && !is_dir) {
|
||||||
fprintf(stderr, "ww build: -p needs a package directory\n");
|
fprintf(stderr, "ww build: -p needs a package directory\n");
|
||||||
|
free(incs);
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
char out[PATH_MAX];
|
char out[PATH_MAX];
|
||||||
@@ -3752,9 +3784,11 @@ do_build(int argc, char **argv)
|
|||||||
basename_no_ext(resolved, out, sizeof out);
|
basename_no_ext(resolved, out, sizeof out);
|
||||||
}
|
}
|
||||||
const char *root_identity = !literal && is_dir ? src : NULL;
|
const char *root_identity = !literal && is_dir ? src : NULL;
|
||||||
return build_one_sep(resolved, is_dir, root_identity, out, objstem, incs,
|
int rc = build_one_sep(resolved, is_dir, root_identity, out, objstem, incs,
|
||||||
&linkflags, package_only, 0, SEP_VARIANT_PRODUCTION, NULL, emit_asm,
|
&linkflags, package_only, 0, SEP_VARIANT_PRODUCTION, NULL, emit_asm,
|
||||||
1, workdir);
|
1, workdir);
|
||||||
|
free(incs);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -3762,15 +3796,14 @@ do_run(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
const char *src = NULL;
|
const char *src = NULL;
|
||||||
struct seplinkflags linkflags = {0};
|
struct seplinkflags linkflags = {0};
|
||||||
size_t incsz = 1;
|
size_t incsz = 0;
|
||||||
for (int i = 0; i < argc; i++) incsz += strlen(argv[i]) + 1;
|
char *incs = NULL;
|
||||||
char incs[incsz];
|
if (include_buffer_for_args(argc, argv, &incs, &incsz) < 0) return 1;
|
||||||
memset(incs, 0, sizeof incs);
|
|
||||||
char outflag[PATH_MAX] = {0}; /* -o accepted+ignored: run always uses the temp */
|
char outflag[PATH_MAX] = {0}; /* -o accepted+ignored: run always uses the temp */
|
||||||
int next = parse_build_flags("run", argc, argv, incs, sizeof incs,
|
int next = parse_build_flags("run", argc, argv, incs, incsz,
|
||||||
&linkflags,
|
&linkflags,
|
||||||
outflag, sizeof outflag, NULL, 0, &src, NULL, NULL);
|
outflag, sizeof outflag, NULL, 0, &src, NULL, NULL);
|
||||||
if (next < 0) return 2;
|
if (next < 0) { free(incs); return 2; }
|
||||||
if (src == NULL) src = ".";
|
if (src == NULL) src = ".";
|
||||||
struct stat requested;
|
struct stat requested;
|
||||||
int literal = stat(src, &requested) == 0;
|
int literal = stat(src, &requested) == 0;
|
||||||
@@ -3778,22 +3811,29 @@ do_run(int argc, char **argv)
|
|||||||
int is_dir = 0;
|
int is_dir = 0;
|
||||||
if (!resolve_module(src, incs, resolved, sizeof resolved, &is_dir)) {
|
if (!resolve_module(src, incs, resolved, sizeof resolved, &is_dir)) {
|
||||||
fprintf(stderr, "ww run: cannot find module %s\n", src);
|
fprintf(stderr, "ww run: cannot find module %s\n", src);
|
||||||
|
free(incs);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
char tmpdir[PATH_MAX], tmp[PATH_MAX];
|
char tmpdir[PATH_MAX], tmp[PATH_MAX];
|
||||||
snprintf(tmpdir, sizeof tmpdir, "/tmp/ww_run_%d", getpid());
|
snprintf(tmpdir, sizeof tmpdir, "/tmp/ww_run_%d", getpid());
|
||||||
if (mkdir(tmpdir, 0700) != 0) {
|
if (mkdir(tmpdir, 0700) != 0) {
|
||||||
fprintf(stderr, "ww: cannot create temporary directory %s\n", tmpdir);
|
fprintf(stderr, "ww: cannot create temporary directory %s\n", tmpdir);
|
||||||
|
free(incs);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
int tn = snprintf(tmp, sizeof tmp, "%s/main", tmpdir);
|
int tn = snprintf(tmp, sizeof tmp, "%s/main", tmpdir);
|
||||||
if (tn < 0 || (size_t)tn >= sizeof tmp) return 1;
|
if (tn < 0 || (size_t)tn >= sizeof tmp) {
|
||||||
|
free(incs);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
/* The freshly acquired directory owns both the executable and the
|
/* The freshly acquired directory owns both the executable and the
|
||||||
* adjacent main.sepwork tree. Nothing outside it is adopted or removed. */
|
* adjacent main.sepwork tree. Nothing outside it is adopted or removed. */
|
||||||
const char *root_identity = !literal && is_dir ? src : NULL;
|
const char *root_identity = !literal && is_dir ? src : NULL;
|
||||||
if (build_one_sep(resolved, is_dir, root_identity, tmp, tmp, incs,
|
int buildrc = build_one_sep(resolved, is_dir, root_identity, tmp, tmp, incs,
|
||||||
&linkflags,
|
&linkflags,
|
||||||
0, 0, SEP_VARIANT_PRODUCTION, NULL, 0, 0, NULL) != 0) {
|
0, 0, SEP_VARIANT_PRODUCTION, NULL, 0, 0, NULL);
|
||||||
|
free(incs);
|
||||||
|
if (buildrc != 0) {
|
||||||
if (unlink(tmp) != 0 && errno != ENOENT)
|
if (unlink(tmp) != 0 && errno != ENOENT)
|
||||||
fputs("ww: cannot remove temporary output\n", stderr);
|
fputs("ww: cannot remove temporary output\n", stderr);
|
||||||
if (rmdir(tmpdir) != 0)
|
if (rmdir(tmpdir) != 0)
|
||||||
|
|||||||
@@ -1010,6 +1010,23 @@ fn sepmakeints(count: i32, out: *[]i32) bool = {
|
|||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
fn sepmakeptrs(count: i32, out: *[]*u8) bool = {
|
||||||
|
if (count < 0) {
|
||||||
|
sepfailsize();
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
let allocation: ([]*u8 | nomem) = sepallocptrs(count);
|
||||||
|
match (allocation) {
|
||||||
|
case let value: []*u8 => {
|
||||||
|
value.len = count;
|
||||||
|
*out = value;
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
case nomem => { sepfailnomem(); return false; };
|
||||||
|
};
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
fn sepreservepackages(g: *sepgraph, need: i32) bool = {
|
fn sepreservepackages(g: *sepgraph, need: i32) bool = {
|
||||||
if (need <= g.pkg.len) { return true; };
|
if (need <= g.pkg.len) { return true; };
|
||||||
let cap: i32 = sepgrowcap(g.pkg.len, need);
|
let cap: i32 = sepgrowcap(g.pkg.len, need);
|
||||||
@@ -2599,6 +2616,7 @@ fn sepreverseimportbase(g: *sepgraph, p: *seppkg, context: i32,
|
|||||||
root.ptr = searchpath + pos;
|
root.ptr = searchpath + pos;
|
||||||
root.len = (end - pos): i32;
|
root.len = (end - pos): i32;
|
||||||
let canonroot: *u8 = canonicaldir(root);
|
let canonroot: *u8 = canonicaldir(root);
|
||||||
|
if (canonroot == nil && sepfatalallocation) { return -1; };
|
||||||
if (canonroot != nil) {
|
if (canonroot != nil) {
|
||||||
let rn: u64 = cstrlen(canonroot);
|
let rn: u64 = cstrlen(canonroot);
|
||||||
let dn: u64 = cstrlen(p.canon);
|
let dn: u64 = cstrlen(p.canon);
|
||||||
@@ -2623,6 +2641,9 @@ fn sepreverseimportbase(g: *sepgraph, p: *seppkg, context: i32,
|
|||||||
cstrlen(rel));
|
cstrlen(rel));
|
||||||
if (selected != nil) {
|
if (selected != nil) {
|
||||||
let selectedcanon: *u8 = canonicaldir(pathstr(selected));
|
let selectedcanon: *u8 = canonicaldir(pathstr(selected));
|
||||||
|
if (selectedcanon == nil && sepfatalallocation) {
|
||||||
|
return -1;
|
||||||
|
};
|
||||||
if (selectedcanon != nil
|
if (selectedcanon != nil
|
||||||
&& cstreq(selectedcanon, p.canon)) {
|
&& cstreq(selectedcanon, p.canon)) {
|
||||||
return 1;
|
return 1;
|
||||||
@@ -4485,20 +4506,21 @@ fn dobuild(selfdir: *u8, argv: **u8, argc: i32, start: i32) i32 = {
|
|||||||
let inccap: u64 = 1u64;
|
let inccap: u64 = 1u64;
|
||||||
let capi: i32 = start;
|
let capi: i32 = start;
|
||||||
for (capi < argc) {
|
for (capi < argc) {
|
||||||
inccap += cstrlen(argv[capi]) + 1u64;
|
if (!sepaddbytes(&inccap, cstrlen(argv[capi]))
|
||||||
|
|| !sepaddbytes(&inccap, 1u64)) { return 1; };
|
||||||
capi += 1;
|
capi += 1;
|
||||||
};
|
};
|
||||||
let incs: []u8 = alloc([], inccap)!;
|
let incs: []u8;
|
||||||
incs.len = inccap: i32;
|
if (!sepmakebytes(inccap, &incs)) { return 1; };
|
||||||
let incoff: u64 = 0u64;
|
let incoff: u64 = 0u64;
|
||||||
cstrseal(incs.ptr, 0u64);
|
cstrseal(incs.ptr, 0u64);
|
||||||
|
|
||||||
let maxlflags: i32 = 32;
|
let maxlflags: i32 = 32;
|
||||||
let libdirs: []*u8 = alloc([], maxlflags: u64)!;
|
let libdirs: []*u8;
|
||||||
libdirs.len = maxlflags;
|
if (!sepmakeptrs(maxlflags, &libdirs)) { return 1; };
|
||||||
let nlibdirs: i32 = 0;
|
let nlibdirs: i32 = 0;
|
||||||
let libs: []*u8 = alloc([], maxlflags: u64)!;
|
let libs: []*u8;
|
||||||
libs.len = maxlflags;
|
if (!sepmakeptrs(maxlflags, &libs)) { return 1; };
|
||||||
let nlibs: i32 = 0;
|
let nlibs: i32 = 0;
|
||||||
|
|
||||||
let i: i32 = start;
|
let i: i32 = start;
|
||||||
@@ -4696,20 +4718,21 @@ fn dorun(selfdir: *u8, argv: **u8, argc: i32, start: i32) i32 = {
|
|||||||
let inccap: u64 = 1u64;
|
let inccap: u64 = 1u64;
|
||||||
let capi: i32 = start;
|
let capi: i32 = start;
|
||||||
for (capi < argc) {
|
for (capi < argc) {
|
||||||
inccap += cstrlen(argv[capi]) + 1u64;
|
if (!sepaddbytes(&inccap, cstrlen(argv[capi]))
|
||||||
|
|| !sepaddbytes(&inccap, 1u64)) { return 1; };
|
||||||
capi += 1;
|
capi += 1;
|
||||||
};
|
};
|
||||||
let incs: []u8 = alloc([], inccap)!;
|
let incs: []u8;
|
||||||
incs.len = inccap: i32;
|
if (!sepmakebytes(inccap, &incs)) { return 1; };
|
||||||
let incoff: u64 = 0u64;
|
let incoff: u64 = 0u64;
|
||||||
cstrseal(incs.ptr, 0u64);
|
cstrseal(incs.ptr, 0u64);
|
||||||
|
|
||||||
let maxlflags: i32 = 32;
|
let maxlflags: i32 = 32;
|
||||||
let libdirs: []*u8 = alloc([], maxlflags: u64)!;
|
let libdirs: []*u8;
|
||||||
libdirs.len = maxlflags;
|
if (!sepmakeptrs(maxlflags, &libdirs)) { return 1; };
|
||||||
let nlibdirs: i32 = 0;
|
let nlibdirs: i32 = 0;
|
||||||
let libs: []*u8 = alloc([], maxlflags: u64)!;
|
let libs: []*u8;
|
||||||
libs.len = maxlflags;
|
if (!sepmakeptrs(maxlflags, &libs)) { return 1; };
|
||||||
let nlibs: i32 = 0;
|
let nlibs: i32 = 0;
|
||||||
|
|
||||||
let i: i32 = start;
|
let i: i32 = start;
|
||||||
@@ -5001,11 +5024,12 @@ fn dotest(selfdir: *u8, argv: **u8, argc: i32, start: i32) i32 = {
|
|||||||
let inccap: u64 = 1u64;
|
let inccap: u64 = 1u64;
|
||||||
let capi: i32 = start;
|
let capi: i32 = start;
|
||||||
for (capi < argc) {
|
for (capi < argc) {
|
||||||
inccap += cstrlen(argv[capi]) + 1u64;
|
if (!sepaddbytes(&inccap, cstrlen(argv[capi]))
|
||||||
|
|| !sepaddbytes(&inccap, 1u64)) { return 1; };
|
||||||
capi += 1;
|
capi += 1;
|
||||||
};
|
};
|
||||||
let incs: []u8 = alloc([], inccap)!;
|
let incs: []u8;
|
||||||
incs.len = inccap: i32;
|
if (!sepmakebytes(inccap, &incs)) { return 1; };
|
||||||
let incoff: u64 = 0u64;
|
let incoff: u64 = 0u64;
|
||||||
cstrseal(incs.ptr, 0u64);
|
cstrseal(incs.ptr, 0u64);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user