Print this page
Incorporate rmustacc's review feedback.
*** 8,25 ****
* source. A copy of the CDDL is also available via the Internet at
* http://www.illumos.org/license/CDDL.
*/
/*
! * Copyright 2014 Garrett D'Amore <garrett@damore.org>
*/
/*
* This program tests symbol visibility using the /usr/bin/c89 and
* /usr/bin/c99 programs.
- *
- * See symbols_defs.c for the actual list of symbols tested.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
--- 8,23 ----
* source. A copy of the CDDL is also available via the Internet at
* http://www.illumos.org/license/CDDL.
*/
/*
! * Copyright 2015 Garrett D'Amore <garrett@damore.org>
*/
/*
* This program tests symbol visibility using the /usr/bin/c89 and
* /usr/bin/c99 programs.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
*** 34,43 ****
--- 32,42 ----
char *dname;
char *cfile;
char *ofile;
char *lfile;
+ char *efile;
const char *sym = NULL;
static int good_count = 0;
static int fail_count = 0;
*** 60,88 ****
"/opt/sfw/bin/gcc",
"/usr/local/bin/gcc",
NULL
};
- const char *puname[] = {
- "",
- "/usr/bin/puname -S "
- };
-
char *compiler = NULL;
const char *c89flags = NULL;
const char *c99flags = NULL;
! /* ====== BEGIN ======== */
!
! #include <errno.h>
! #include <string.h>
! #include <stdio.h>
! #include <stdlib.h>
! #include <ctype.h>
! #include <stdint.h>
!
! #define MAXENV 64 /* bits */
#define MAXHDR 10 /* maximum # headers to require to access symbol */
#define MAXARG 20 /* maximum # of arguments */
#define WS " \t"
--- 59,73 ----
"/opt/sfw/bin/gcc",
"/usr/local/bin/gcc",
NULL
};
char *compiler = NULL;
const char *c89flags = NULL;
const char *c99flags = NULL;
! #define MAXENV 64 /* maximum number of environments (bitmask width) */
#define MAXHDR 10 /* maximum # headers to require to access symbol */
#define MAXARG 20 /* maximum # of arguments */
#define WS " \t"
*** 120,130 ****
--- 105,151 ----
struct env_group *env_groups = NULL;
struct sym_test *sym_tests = NULL;
struct sym_test **sym_insert = &sym_tests;
+ static char *
+ mystrdup(const char *s)
+ {
+ char *r;
+ if ((r = strdup(s)) == NULL) {
+ perror("strdup");
+ exit(1);
+ }
+ return (r);
+ }
+
+ static void *
+ myzalloc(size_t sz)
+ {
+ void *buf;
+ if ((buf = calloc(1, sz)) == NULL) {
+ perror("calloc");
+ exit(1);
+ }
+ return (buf);
+ }
+
static void
+ myasprintf(char **buf, const char *fmt, ...)
+ {
+ int rv;
+ va_list va;
+ va_start(va, fmt);
+ rv = vasprintf(buf, fmt, va);
+ va_end(va);
+ if (rv < 0) {
+ perror("vasprintf");
+ exit(1);
+ }
+ }
+
+ static void
append_sym_test(struct sym_test *st)
{
*sym_insert = st;
sym_insert = &st->next;
}
*** 209,234 ****
char *name;
char *lang;
char *defs;
if (nfields != 3) {
! (void) asprintf(err, "number of fields (%d) != 3", nfields);
return (-1);
}
if (next_env >= MAXENV) {
! (void) asprintf(err, "too many environments");
return (-1);
}
name = fields[0];
lang = fields[1];
defs = fields[2];
! compile_env[next_env].name = strdup(name);
! compile_env[next_env].lang = strdup(lang);
! compile_env[next_env].defs = strdup(defs);
compile_env[next_env].index = next_env;
next_env++;
return (0);
}
--- 230,255 ----
char *name;
char *lang;
char *defs;
if (nfields != 3) {
! myasprintf(err, "number of fields (%d) != 3", nfields);
return (-1);
}
if (next_env >= MAXENV) {
! myasprintf(err, "too many environments");
return (-1);
}
name = fields[0];
lang = fields[1];
defs = fields[2];
! compile_env[next_env].name = mystrdup(name);
! compile_env[next_env].lang = mystrdup(lang);
! compile_env[next_env].defs = mystrdup(defs);
compile_env[next_env].index = next_env;
next_env++;
return (0);
}
*** 240,383 ****
struct env_group *eg;
uint64_t mask;
char *item;
if (nfields != 2) {
! (void) asprintf(err, "number of fields (%d) != 2", nfields);
return (-1);
}
name = fields[0];
list = fields[1];
mask = 0;
if (expand_env(list, &mask, &item) < 0) {
! (void) asprintf(err, "reference to undefined env %s", item);
return (-1);
}
! eg = calloc(1, sizeof (*eg));
! eg->name = strdup(name);
eg->mask = mask;
eg->next = env_groups;
env_groups = eg;
return (0);
}
static void
mkprog(struct sym_test *st)
{
- static char buf[2048];
char *s;
- char *prog = buf;
! *prog = 0;
- #define ADDSTR(p, str) (void) strcpy(p, str); p += strlen(p)
- #define ADDFMT(p, ...) \
- (void) snprintf(p, sizeof (buf) - (p-buf), __VA_ARGS__); \
- p += strlen(p)
- #define ADDCHR(p, c) *p++ = c; *p = 0
-
for (int i = 0; i < MAXHDR && st->hdrs[i] != NULL; i++) {
! ADDFMT(prog, "#include <%s>\n", st->hdrs[i]);
}
for (s = st->rtype; *s; s++) {
! ADDCHR(prog, *s);
if (*s == '(') {
s++;
! ADDCHR(prog, *s);
s++;
break;
}
}
! ADDCHR(prog, ' ');
/* for function pointers, s is closing suffix, otherwise empty */
switch (st->type) {
case SYM_TYPE:
! ADDFMT(prog, "test_type;", st->rtype);
break;
case SYM_VALUE:
! ADDFMT(prog, "test_value%s;\n", s); /* s usually empty */
! ADDSTR(prog, "void\ntest_func(void)\n{\n");
! ADDFMT(prog, "\ttest_value = %s;\n}",
! st->name);
break;
case SYM_FUNC:
! ADDSTR(prog, "\ntest_func(");
for (int i = 0; st->atypes[i] != NULL && i < MAXARG; i++) {
int didname = 0;
if (i > 0) {
! ADDSTR(prog, ", ");
}
if (strcmp(st->atypes[i], "void") == 0) {
didname = 1;
}
if (strcmp(st->atypes[i], "") == 0) {
didname = 1;
! ADDSTR(prog, "void");
}
/* print the argument list */
for (char *a = st->atypes[i]; *a; a++) {
if (*a == '(' && a[1] == '*' && !didname) {
! ADDFMT(prog, "(*a%d", i);
didname = 1;
a++;
} else if (*a == '[' && !didname) {
! ADDFMT(prog, "a%d[", i);
didname = 1;
} else {
! ADDCHR(prog, *a);
}
}
if (!didname) {
! ADDFMT(prog, " a%d", i);
}
}
if (st->atypes[0] == NULL) {
! ADDSTR(prog, "void");
}
/* close argument list, and closing ")" for func ptrs */
! ADDFMT(prog, ")%s\n{\n\t", s); /* NB: s is normally empty */
if (strcmp(st->rtype, "") != 0 &&
strcmp(st->rtype, "void") != 0) {
! ADDSTR(prog, "return ");
}
/* add the function call */
! ADDFMT(prog, "%s(", st->name);
for (int i = 0; st->atypes[i] != NULL && i < MAXARG; i++) {
if (strcmp(st->atypes[i], "") != 0 &&
strcmp(st->atypes[i], "void") != 0) {
! ADDFMT(prog, "%sa%d", i > 0 ? ", " : "", i);
}
}
! ADDSTR(prog, ");\n}");
break;
}
! ADDCHR(prog, '\n');
! st->prog = strdup(buf);
}
static int
add_envs(struct sym_test *st, char *envs, char **err)
{
char *item;
if (expand_env_list(envs, &st->test_mask, &st->need_mask, &item) < 0) {
! (void) asprintf(err, "bad env action %s", item);
return (-1);
}
return (0);
}
--- 261,438 ----
struct env_group *eg;
uint64_t mask;
char *item;
if (nfields != 2) {
! myasprintf(err, "number of fields (%d) != 2", nfields);
return (-1);
}
name = fields[0];
list = fields[1];
mask = 0;
if (expand_env(list, &mask, &item) < 0) {
! myasprintf(err, "reference to undefined env %s", item);
return (-1);
}
! eg = myzalloc(sizeof (*eg));
! eg->name = mystrdup(name);
eg->mask = mask;
eg->next = env_groups;
env_groups = eg;
return (0);
}
+ static char *progbuf = NULL;
+ size_t proglen = 0;
+ size_t progsiz = 0;
+
static void
+ addprogch(char c)
+ {
+ while (progsiz <= (proglen + 1)) {
+ progbuf = realloc(progbuf, progsiz + 4096);
+ if (progbuf == NULL) {
+ perror("realloc");
+ exit(1);
+ }
+ progsiz += 1024;
+ }
+ progbuf[proglen++] = c;
+ progbuf[proglen] = 0;
+ }
+
+ static void
+ addprogstr(char *s)
+ {
+ while (*s != NULL) {
+ addprogch(*s);
+ s++;
+ }
+ }
+
+ static void
+ addprogfmt(const char *fmt, ...)
+ {
+ va_list va;
+ char *buf = NULL;
+ va_start(va, fmt);
+ if (vasprintf(&buf, fmt, va) < 0) {
+ perror("vasprintf");
+ exit(1);
+ }
+ va_end(va);
+ addprogstr(buf);
+ free(buf);
+ }
+
+ static void
mkprog(struct sym_test *st)
{
char *s;
! proglen = 0;
for (int i = 0; i < MAXHDR && st->hdrs[i] != NULL; i++) {
! addprogfmt("#include <%s>\n", st->hdrs[i]);
}
for (s = st->rtype; *s; s++) {
! addprogch(*s);
if (*s == '(') {
s++;
! addprogch(*s);
s++;
break;
}
}
! addprogch(' ');
/* for function pointers, s is closing suffix, otherwise empty */
switch (st->type) {
case SYM_TYPE:
! addprogstr("test_type;");
break;
case SYM_VALUE:
! addprogfmt("test_value%s;\n", s); /* s usually empty */
! addprogstr("void\ntest_func(void)\n{\n");
! addprogfmt("\ttest_value = %s;\n}", st->name);
break;
case SYM_FUNC:
! addprogstr("\ntest_func(");
for (int i = 0; st->atypes[i] != NULL && i < MAXARG; i++) {
int didname = 0;
if (i > 0) {
! addprogstr(", ");
}
if (strcmp(st->atypes[i], "void") == 0) {
didname = 1;
}
if (strcmp(st->atypes[i], "") == 0) {
didname = 1;
! addprogstr("void");
}
/* print the argument list */
for (char *a = st->atypes[i]; *a; a++) {
if (*a == '(' && a[1] == '*' && !didname) {
! addprogfmt("(*a%d", i);
didname = 1;
a++;
} else if (*a == '[' && !didname) {
! addprogfmt("a%d[", i);
didname = 1;
} else {
! addprogch(*a);
}
}
if (!didname) {
! addprogfmt(" a%d", i);
}
}
if (st->atypes[0] == NULL) {
! addprogstr("void");
}
/* close argument list, and closing ")" for func ptrs */
! addprogfmt(")%s\n{\n\t", s); /* NB: s is normally empty */
if (strcmp(st->rtype, "") != 0 &&
strcmp(st->rtype, "void") != 0) {
! addprogstr("return ");
}
/* add the function call */
! addprogfmt("%s(", st->name);
for (int i = 0; st->atypes[i] != NULL && i < MAXARG; i++) {
if (strcmp(st->atypes[i], "") != 0 &&
strcmp(st->atypes[i], "void") != 0) {
! addprogfmt("%sa%d", i > 0 ? ", " : "", i);
}
}
! addprogstr(");\n}");
break;
}
! addprogch('\n');
! st->prog = progbuf;
}
static int
add_envs(struct sym_test *st, char *envs, char **err)
{
char *item;
if (expand_env_list(envs, &st->test_mask, &st->need_mask, &item) < 0) {
! myasprintf(err, "bad env action %s", item);
return (-1);
}
return (0);
}
*** 386,400 ****
{
int i = 0;
for (char *h = strsep(&hdrs, ";"); h != NULL; h = strsep(&hdrs, ";")) {
if (i >= MAXHDR) {
! (void) asprintf(err, "too many headers");
return (-1);
}
test_trim(&h);
! st->hdrs[i++] = strdup(h);
}
return (0);
}
--- 441,455 ----
{
int i = 0;
for (char *h = strsep(&hdrs, ";"); h != NULL; h = strsep(&hdrs, ";")) {
if (i >= MAXHDR) {
! myasprintf(err, "too many headers");
return (-1);
}
test_trim(&h);
! st->hdrs[i++] = mystrdup(h);
}
return (0);
}
*** 403,417 ****
{
int i = 0;
char *a;
for (a = strsep(&atype, ";"); a != NULL; a = strsep(&atype, ";")) {
if (i >= MAXARG) {
! (void) asprintf(err, "too many arguments");
return (-1);
}
test_trim(&a);
! st->atypes[i++] = strdup(a);
}
return (0);
}
--- 458,472 ----
{
int i = 0;
char *a;
for (a = strsep(&atype, ";"); a != NULL; a = strsep(&atype, ";")) {
if (i >= MAXARG) {
! myasprintf(err, "too many arguments");
return (-1);
}
test_trim(&a);
! st->atypes[i++] = mystrdup(a);
}
return (0);
}
*** 422,442 ****
char *hdrs;
char *envs;
struct sym_test *st;
if (nfields != 3) {
! (void) asprintf(err, "number of fields (%d) != 3", nfields);
return (-1);
}
decl = fields[0];
hdrs = fields[1];
envs = fields[2];
! st = calloc(1, sizeof (*st));
st->type = SYM_TYPE;
! st->name = strdup(decl);
! st->rtype = strdup(decl);
if ((add_envs(st, envs, err) < 0) ||
(add_headers(st, hdrs, err) < 0)) {
return (-1);
}
--- 477,497 ----
char *hdrs;
char *envs;
struct sym_test *st;
if (nfields != 3) {
! myasprintf(err, "number of fields (%d) != 3", nfields);
return (-1);
}
decl = fields[0];
hdrs = fields[1];
envs = fields[2];
! st = myzalloc(sizeof (*st));
st->type = SYM_TYPE;
! st->name = mystrdup(decl);
! st->rtype = mystrdup(decl);
if ((add_envs(st, envs, err) < 0) ||
(add_headers(st, hdrs, err) < 0)) {
return (-1);
}
*** 453,474 ****
char *hdrs;
char *envs;
struct sym_test *st;
if (nfields != 4) {
! (void) asprintf(err, "number of fields (%d) != 4", nfields);
return (-1);
}
name = fields[0];
type = fields[1];
hdrs = fields[2];
envs = fields[3];
! st = calloc(1, sizeof (*st));
st->type = SYM_VALUE;
! st->name = strdup(name);
! st->rtype = strdup(type);
if ((add_envs(st, envs, err) < 0) ||
(add_headers(st, hdrs, err) < 0)) {
return (-1);
}
--- 508,529 ----
char *hdrs;
char *envs;
struct sym_test *st;
if (nfields != 4) {
! myasprintf(err, "number of fields (%d) != 4", nfields);
return (-1);
}
name = fields[0];
type = fields[1];
hdrs = fields[2];
envs = fields[3];
! st = myzalloc(sizeof (*st));
st->type = SYM_VALUE;
! st->name = mystrdup(name);
! st->rtype = mystrdup(type);
if ((add_envs(st, envs, err) < 0) ||
(add_headers(st, hdrs, err) < 0)) {
return (-1);
}
*** 486,508 ****
char *hdrs;
char *envs;
struct sym_test *st;
if (nfields != 5) {
! (void) asprintf(err, "number of fields (%d) != 5", nfields);
return (-1);
}
name = fields[0];
rtype = fields[1];
atype = fields[2];
hdrs = fields[3];
envs = fields[4];
! st = calloc(1, sizeof (*st));
st->type = SYM_FUNC;
! st->name = strdup(name);
! st->rtype = strdup(rtype);
if ((add_envs(st, envs, err) < 0) ||
(add_headers(st, hdrs, err) < 0) ||
(add_arg_types(st, atype, err) < 0)) {
return (-1);
--- 541,563 ----
char *hdrs;
char *envs;
struct sym_test *st;
if (nfields != 5) {
! myasprintf(err, "number of fields (%d) != 5", nfields);
return (-1);
}
name = fields[0];
rtype = fields[1];
atype = fields[2];
hdrs = fields[3];
envs = fields[4];
! st = myzalloc(sizeof (*st));
st->type = SYM_FUNC;
! st->name = mystrdup(name);
! st->rtype = mystrdup(rtype);
if ((add_envs(st, envs, err) < 0) ||
(add_headers(st, hdrs, err) < 0) ||
(add_arg_types(st, atype, err) < 0)) {
return (-1);
*** 532,543 ****
{
return (st->name);
}
/*
! * Iterate through tests. Pass NULL for cenv first time, and previous result
! * the next. Returns NULL when no more environments.
*/
struct compile_env *
sym_test_env(struct sym_test *st, struct compile_env *cenv, int *need)
{
int i = cenv ? cenv->index + 1: 0;
--- 587,599 ----
{
return (st->name);
}
/*
! * Iterate through tests. Pass in NULL for cenv to begin the iteration. For
! * subsequent iterations, use the return value from the previous iteration.
! * Returns NULL when there are no more environments.
*/
struct compile_env *
sym_test_env(struct sym_test *st, struct compile_env *cenv, int *need)
{
int i = cenv ? cenv->index + 1: 0;
*** 580,589 ****
--- 636,649 ----
char *buf = NULL;
size_t cap = 0;
int line = 1;
f = fopen(path, "r");
+ if (f == NULL) {
+ test_debugf(t, "fopen(%s): %s", path, strerror(errno));
+ return;
+ }
test_debugf(t, "----->> begin (%s) <<------", path);
while (getline(&buf, &cap, f) >= 0) {
(void) strtok(buf, "\r\n");
test_debugf(t, "%d: %s", line, buf);
*** 609,618 ****
--- 669,683 ----
if (cfile != NULL) {
(void) unlink(cfile);
free(cfile);
cfile = NULL;
}
+ if (efile != NULL) {
+ (void) unlink(efile);
+ free(efile);
+ efile = NULL;
+ }
if (dname) {
(void) rmdir(dname);
free(dname);
dname = NULL;
}
*** 629,642 ****
(void) strlcpy(b, "/tmp/symbols_testXXXXXX", sizeof (b));
if ((d = mkdtemp(b)) == NULL) {
perror("mkdtemp");
return (-1);
}
! dname = strdup(d);
! (void) asprintf(&cfile, "%s/compile_test.c", d);
! (void) asprintf(&ofile, "%s/compile_test.o", d);
! (void) asprintf(&lfile, "%s/compile_test.log", d);
return (0);
}
void
find_compiler(void)
--- 694,708 ----
(void) strlcpy(b, "/tmp/symbols_testXXXXXX", sizeof (b));
if ((d = mkdtemp(b)) == NULL) {
perror("mkdtemp");
return (-1);
}
! dname = mystrdup(d);
! myasprintf(&cfile, "%s/compile_test.c", d);
! myasprintf(&ofile, "%s/compile_test.o", d);
! myasprintf(&lfile, "%s/compile_test.log", d);
! myasprintf(&efile, "%s/compile_test.exe", d);
return (0);
}
void
find_compiler(void)
*** 646,655 ****
--- 712,723 ----
FILE *cf;
t = test_start("finding compiler");
if ((cf = fopen(cfile, "w+")) == NULL) {
+ test_failed(t, "Unable to open %s for write: %s", cfile,
+ strerror(errno));
return;
}
(void) fprintf(cf, "#include <stdio.h>\n");
(void) fprintf(cf, "int main(int argc, char **argv) {\n");
(void) fprintf(cf, "#if defined(__SUNPRO_C)\n");
*** 659,684 ****
(void) fprintf(cf, "#else\n");
(void) fprintf(cf, "exit(99)\n");
(void) fprintf(cf, "#endif\n}\n");
(void) fclose(cf);
! for (i = 0; compilers[i/2] != NULL; i++) {
char cmd[256];
int rv;
(void) snprintf(cmd, sizeof (cmd),
! "%s%s %s %s -o %s >/dev/null 2>&1",
! puname[i%2], compilers[i/2], MFLAG, cfile, ofile);
test_debugf(t, "trying %s", cmd);
rv = system(cmd);
test_debugf(t, "result: %d", rv);
if ((rv < 0) || !WIFEXITED(rv) || WEXITSTATUS(rv) != 0)
continue;
! rv = system(ofile);
if (rv >= 0 && WIFEXITED(rv)) {
rv = WEXITSTATUS(rv);
} else {
rv = -1;
}
--- 727,752 ----
(void) fprintf(cf, "#else\n");
(void) fprintf(cf, "exit(99)\n");
(void) fprintf(cf, "#endif\n}\n");
(void) fclose(cf);
! for (i = 0; compilers[i] != NULL; i++) {
char cmd[256];
int rv;
(void) snprintf(cmd, sizeof (cmd),
! "%s %s %s -o %s >/dev/null 2>&1",
! compilers[i], MFLAG, cfile, efile);
test_debugf(t, "trying %s", cmd);
rv = system(cmd);
test_debugf(t, "result: %d", rv);
if ((rv < 0) || !WIFEXITED(rv) || WEXITSTATUS(rv) != 0)
continue;
! rv = system(efile);
if (rv >= 0 && WIFEXITED(rv)) {
rv = WEXITSTATUS(rv);
} else {
rv = -1;
}
*** 705,716 ****
test_passed(t);
break;
default:
continue;
}
! (void) asprintf(&compiler,
! "%s%s", puname[i%2], compilers[i/2]);
test_debugf(t, "compiler: %s", compiler);
return;
}
test_failed(t, "No compiler found.");
}
--- 773,783 ----
test_passed(t);
break;
default:
continue;
}
! myasprintf(&compiler, "%s", compilers[i]);
test_debugf(t, "compiler: %s", compiler);
return;
}
test_failed(t, "No compiler found.");
}
*** 740,761 ****
return (-1);
}
(void) unlink(ofile);
! if (asprintf(&cmd, "%s %s %s -c %s -o %s >>%s 2>&1",
compiler, strcmp(env_lang(cenv), "c99") == 0 ? c99flags : c89flags,
! env_defs(cenv), cfile, ofile, lfile) < 0) {
! test_failed(t, "asprintf: %s", strerror(errno));
! return (-1);
! }
if (extra_debug) {
test_debugf(t, "command: %s", cmd);
}
-
if ((logf = fopen(lfile, "w+")) == NULL) {
test_failed(t, "fopen: %s", strerror(errno));
return (-1);
}
(void) fprintf(logf, "===================\n");
--- 807,824 ----
return (-1);
}
(void) unlink(ofile);
! myasprintf(&cmd, "%s %s %s -c %s -o %s >>%s 2>&1",
compiler, strcmp(env_lang(cenv), "c99") == 0 ? c99flags : c89flags,
! env_defs(cenv), cfile, ofile, lfile);
if (extra_debug) {
test_debugf(t, "command: %s", cmd);
}
if ((logf = fopen(lfile, "w+")) == NULL) {
test_failed(t, "fopen: %s", strerror(errno));
return (-1);
}
(void) fprintf(logf, "===================\n");
*** 762,785 ****
(void) fprintf(logf, "PROGRAM:\n%s\n", sym_test_prog(st));
(void) fprintf(logf, "COMMAND: %s\n", cmd);
(void) fprintf(logf, "EXPECT: %s\n", need ? "OK" : "FAIL");
(void) fclose(logf);
! if (system(cmd) != 0) {
! if (need) {
fail_count++;
show_file(t, lfile);
! test_failed(t, "error compiling in %s", env_name(cenv));
return (-1);
}
! } else {
! if (!need) {
fail_count++;
show_file(t, lfile);
! test_failed(t, "symbol visible in %s", env_name(cenv));
return (-1);
}
}
good_count++;
return (0);
}
--- 825,855 ----
(void) fprintf(logf, "PROGRAM:\n%s\n", sym_test_prog(st));
(void) fprintf(logf, "COMMAND: %s\n", cmd);
(void) fprintf(logf, "EXPECT: %s\n", need ? "OK" : "FAIL");
(void) fclose(logf);
! switch (system(cmd)) {
! case -1:
! test_failed(t, "error compiling in %s: %s", env_name(cenv),
! strerror(errno));
! return (-1);
! case 0:
! if (!need) {
fail_count++;
show_file(t, lfile);
! test_failed(t, "symbol visible in %s", env_name(cenv));
return (-1);
}
! break;
! default:
! if (need) {
fail_count++;
show_file(t, lfile);
! test_failed(t, "error compiling in %s", env_name(cenv));
return (-1);
}
+ break;
}
good_count++;
return (0);
}
*** 858,868 ****
NULL) < 0) {
exit(1);
}
}
! (void) atexit(cleanup);
if (mkworkdir() < 0) {
perror("mkdir");
exit(1);
}
--- 928,941 ----
NULL) < 0) {
exit(1);
}
}
! if (atexit(cleanup) != 0) {
! perror("atexit");
! exit(1);
! }
if (mkworkdir() < 0) {
perror("mkdir");
exit(1);
}