mridge | 949c5b1 | 2006-01-03 23:01:28 +0000 | [diff] [blame] | 1 | /* |
| 2 | * |
| 3 | * Copyright (c) International Business Machines Corp., 2001 |
| 4 | * |
| 5 | * This program is free software; you can redistribute it and/or modify |
| 6 | * it under the terms of the GNU General Public License as published by |
| 7 | * the Free Software Foundation; either version 2 of the License, or |
| 8 | * (at your option) any later version. |
| 9 | * |
| 10 | * This program is distributed in the hope that it will be useful, |
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See |
| 13 | * the GNU General Public License for more details. |
| 14 | * |
| 15 | * You should have received a copy of the GNU General Public License |
| 16 | * along with this program; if not, write to the Free Software |
Wanlong Gao | 4548c6c | 2012-10-19 18:03:36 +0800 | [diff] [blame] | 17 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
mridge | 949c5b1 | 2006-01-03 23:01:28 +0000 | [diff] [blame] | 18 | */ |
| 19 | |
| 20 | /* |
| 21 | * runcc.a - common functions for lib6 testing |
| 22 | * |
| 23 | * HISTORY |
| 24 | * 05/2005 written by David L Stevens |
| 25 | * |
| 26 | * RESTRICTIONS: |
| 27 | * None. |
| 28 | * |
| 29 | */ |
| 30 | |
| 31 | #include <stdio.h> |
| 32 | #include <unistd.h> |
| 33 | #include <errno.h> |
subrata_modak | aa588ae | 2008-09-18 13:18:36 +0000 | [diff] [blame] | 34 | #include <ctype.h> |
mridge | 949c5b1 | 2006-01-03 23:01:28 +0000 | [diff] [blame] | 35 | |
| 36 | #include <sys/wait.h> |
| 37 | |
| 38 | #include "test.h" |
mridge | 949c5b1 | 2006-01-03 23:01:28 +0000 | [diff] [blame] | 39 | |
| 40 | char fieldref[1024]; |
| 41 | char program[8192]; |
| 42 | |
| 43 | char *filetmpl = "/tmp/%.*s_XXXXXX"; |
| 44 | |
| 45 | char cmd[1024]; |
| 46 | |
| 47 | /* |
| 48 | * like strspn, with ASCII, numbers and underscore only |
| 49 | */ |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 50 | int strfpn(char *name) |
mridge | 949c5b1 | 2006-01-03 23:01:28 +0000 | [diff] [blame] | 51 | { |
| 52 | int i; |
| 53 | |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 54 | for (i = 0; *name; ++name, ++i) |
mridge | 949c5b1 | 2006-01-03 23:01:28 +0000 | [diff] [blame] | 55 | if (!(isalnum(*name) || *name == '_')) |
| 56 | break; |
| 57 | return i; |
| 58 | } |
| 59 | |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 60 | int runcc(char *tname, char *filename0, char *program) |
mridge | 949c5b1 | 2006-01-03 23:01:28 +0000 | [diff] [blame] | 61 | { |
| 62 | static char filename[1024]; |
| 63 | int fd, es, saved_errno; |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 64 | char *cflags = ""; |
mridge | 949c5b1 | 2006-01-03 23:01:28 +0000 | [diff] [blame] | 65 | |
| 66 | fd = mkstemp(filename0); |
| 67 | if (fd < 0) { |
| 68 | perror("mkstemp"); |
| 69 | return -1; |
| 70 | } |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 71 | strncpy(filename, filename0, sizeof(filename) - 1); |
| 72 | filename[sizeof(filename) - 1] = '\0'; |
| 73 | strncat(filename, ".c", sizeof(filename) - strlen(filename) - 1); |
mridge | 949c5b1 | 2006-01-03 23:01:28 +0000 | [diff] [blame] | 74 | if (rename(filename0, filename) < 0) { |
| 75 | perror("rename"); |
| 76 | unlink(filename0); |
| 77 | return -1; |
| 78 | } |
| 79 | if (write(fd, program, strlen(program)) < 0) { |
| 80 | perror("write"); |
subrata_modak | 814e03c | 2008-11-11 06:44:51 +0000 | [diff] [blame] | 81 | unlink(filename); |
mridge | 949c5b1 | 2006-01-03 23:01:28 +0000 | [diff] [blame] | 82 | return -1; |
| 83 | } |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 84 | (void)close(fd); |
subrata_modak | 8ea40f8 | 2009-02-23 11:09:42 +0000 | [diff] [blame] | 85 | |
| 86 | cflags = getenv("CFLAGS"); |
Garrett Cooper | df3eb16 | 2010-11-28 22:44:32 -0800 | [diff] [blame] | 87 | if (cflags == NULL) { |
subrata_modak | f0d432c | 2009-04-16 06:54:20 +0000 | [diff] [blame] | 88 | tst_resm(TINFO, "CFLAGS not found, using default cc arch."); |
| 89 | cflags = ""; |
subrata_modak | 8ea40f8 | 2009-02-23 11:09:42 +0000 | [diff] [blame] | 90 | } |
| 91 | |
| 92 | snprintf(cmd, sizeof(cmd), "%s %s -o %s %s > /tmp/test 2>&1", "cc", |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 93 | cflags, filename0, filename); |
mridge | 949c5b1 | 2006-01-03 23:01:28 +0000 | [diff] [blame] | 94 | es = system(cmd); |
| 95 | if (WEXITSTATUS(es) == 127) { |
yaberauneya | ef77253 | 2009-10-09 17:55:43 +0000 | [diff] [blame] | 96 | tst_resm(TBROK, "can't run C compiler: \"%s\"", cmd); |
mridge | 949c5b1 | 2006-01-03 23:01:28 +0000 | [diff] [blame] | 97 | if (unlink(filename) < 0) |
| 98 | tst_resm(TWARN, "%s; unlink \"%s\" failed: %s", tname, |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 99 | filename, strerror(errno)); |
mridge | 949c5b1 | 2006-01-03 23:01:28 +0000 | [diff] [blame] | 100 | return -1; |
| 101 | } |
| 102 | if (unlink(filename) < 0) |
| 103 | tst_resm(TWARN, "%s: unlink \"%s\" failed: %s", tname, |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 104 | filename, strerror(errno)); |
mridge | 949c5b1 | 2006-01-03 23:01:28 +0000 | [diff] [blame] | 105 | |
| 106 | if (WIFSIGNALED(es) && |
| 107 | (WTERMSIG(es) == SIGINT || WTERMSIG(es) == SIGQUIT)) |
| 108 | exit(1); |
| 109 | |
| 110 | if (WEXITSTATUS(es)) { |
| 111 | tst_resm(TFAIL, "%s: not present", tname); |
subrata_modak | aa588ae | 2008-09-18 13:18:36 +0000 | [diff] [blame] | 112 | return -1; |
mridge | 949c5b1 | 2006-01-03 23:01:28 +0000 | [diff] [blame] | 113 | } |
| 114 | /* run the test */ |
| 115 | |
| 116 | es = system(filename0); |
| 117 | saved_errno = errno; |
| 118 | if (unlink(filename0) < 0) |
| 119 | tst_resm(TWARN, "%s: unlink \"%s\" failed: %s", tname, |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 120 | filename0, strerror(errno)); |
mridge | 949c5b1 | 2006-01-03 23:01:28 +0000 | [diff] [blame] | 121 | |
| 122 | if (WIFSIGNALED(es) && |
| 123 | (WTERMSIG(es) == SIGINT || WTERMSIG(es) == SIGQUIT)) |
| 124 | exit(1); |
| 125 | |
| 126 | if (WEXITSTATUS(es) == 127) |
| 127 | tst_resm(TBROK, "%s: can't run \"%s\": %s", tname, filename0, |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 128 | strerror(saved_errno)); |
mridge | 949c5b1 | 2006-01-03 23:01:28 +0000 | [diff] [blame] | 129 | if (WEXITSTATUS(es)) |
| 130 | tst_resm(TFAIL, "%s: present, but incorrect", tname); |
| 131 | else |
| 132 | tst_resm(TPASS, "%s present and correct", tname); |
| 133 | return 0; |
| 134 | } |
| 135 | |
| 136 | char *field_fmt = "\n\texit((offsetof(struct %s, %s) != %s) || " |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 137 | "sizeof(tst.%s) != (%s));\n"; |
mridge | 949c5b1 | 2006-01-03 23:01:28 +0000 | [diff] [blame] | 138 | /* no offset check */ |
| 139 | char *field_fmt2 = "\n\texit(sizeof(tst.%s) != (%s));\n"; |
| 140 | |
| 141 | const char *stmpl = |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 142 | "%s\n#ifndef offsetof\n" |
| 143 | "#define offsetof(dtype, dfield) ((int)&((dtype *)0)->dfield)\n" |
| 144 | "#endif\n\nstruct %s tst;\n\nmain(int argc, char *argv[])\n{\n\t%s\n}\n"; |
mridge | 949c5b1 | 2006-01-03 23:01:28 +0000 | [diff] [blame] | 145 | |
| 146 | int |
| 147 | structcheck(char *tname, char *incl, char *structure, char *field, |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 148 | char *offset, char *size) |
mridge | 949c5b1 | 2006-01-03 23:01:28 +0000 | [diff] [blame] | 149 | { |
| 150 | int rv; |
| 151 | static char filename[1024]; |
| 152 | |
| 153 | if (offset) |
| 154 | sprintf(fieldref, field_fmt, structure, field, offset, field, |
| 155 | size); |
| 156 | else |
| 157 | sprintf(fieldref, field_fmt2, field, size); |
| 158 | sprintf(program, stmpl, incl, structure, fieldref); |
| 159 | snprintf(filename, sizeof(filename), filetmpl, strfpn(structure), |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 160 | structure); |
subrata_modak | aa588ae | 2008-09-18 13:18:36 +0000 | [diff] [blame] | 161 | rv = runcc(tname, filename, program); |
| 162 | return rv; |
mridge | 949c5b1 | 2006-01-03 23:01:28 +0000 | [diff] [blame] | 163 | } |
| 164 | |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 165 | char *aliasfmt = |
| 166 | "exit(&tst.%s != &tst.%s || sizeof(tst.%s) != sizeof(tst.%s));"; |
mridge | 949c5b1 | 2006-01-03 23:01:28 +0000 | [diff] [blame] | 167 | |
| 168 | int |
| 169 | aliascheck(char *tname, char *incl, char *structure, char *field, char *dname) |
| 170 | { |
| 171 | int rv; |
| 172 | static char filename[1024]; |
| 173 | |
| 174 | sprintf(fieldref, aliasfmt, field, dname, field, dname); |
| 175 | sprintf(program, stmpl, incl, structure, fieldref); |
| 176 | snprintf(filename, sizeof(filename), filetmpl, strfpn(structure), |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 177 | structure); |
subrata_modak | aa588ae | 2008-09-18 13:18:36 +0000 | [diff] [blame] | 178 | rv = runcc(tname, filename, program); |
| 179 | return rv; |
mridge | 949c5b1 | 2006-01-03 23:01:28 +0000 | [diff] [blame] | 180 | } |
| 181 | |
| 182 | const char *dtmpl = |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 183 | "%s\n\nmain(int argc, char *argv[])\n{\n\texit((%s) != (%s));\n}\n"; |
mridge | 949c5b1 | 2006-01-03 23:01:28 +0000 | [diff] [blame] | 184 | |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 185 | int valuecheck(char *tname, char *incl, char *dname, char *dval) |
mridge | 949c5b1 | 2006-01-03 23:01:28 +0000 | [diff] [blame] | 186 | { |
| 187 | int rv; |
| 188 | static char filename[1024]; |
| 189 | |
| 190 | sprintf(program, dtmpl, incl, dname, dval); |
| 191 | snprintf(filename, sizeof(filename), filetmpl, strfpn(dname), dname); |
subrata_modak | aa588ae | 2008-09-18 13:18:36 +0000 | [diff] [blame] | 192 | rv = runcc(tname, filename, program); |
| 193 | return rv; |
mridge | 949c5b1 | 2006-01-03 23:01:28 +0000 | [diff] [blame] | 194 | } |
| 195 | |
| 196 | const char *ftmpl = |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 197 | "%s\n\nmain(int argc, char *argv[])\n{\n#ifdef %s\n\texit(0);\n#else\n" |
| 198 | "\tsyntax error;\n#endif\n}\n"; |
mridge | 949c5b1 | 2006-01-03 23:01:28 +0000 | [diff] [blame] | 199 | |
Wanlong Gao | 354ebb4 | 2012-12-07 10:10:04 +0800 | [diff] [blame] | 200 | int funccheck(char *tname, char *incl, char *fname) |
mridge | 949c5b1 | 2006-01-03 23:01:28 +0000 | [diff] [blame] | 201 | { |
| 202 | int rv; |
| 203 | static char filename[1024]; |
| 204 | |
| 205 | sprintf(program, ftmpl, incl, fname); |
| 206 | snprintf(filename, sizeof(filename), filetmpl, strfpn(fname), fname); |
subrata_modak | aa588ae | 2008-09-18 13:18:36 +0000 | [diff] [blame] | 207 | rv = runcc(tname, filename, program); |
| 208 | return rv; |
Chris Dearman | ec6edca | 2012-10-17 19:54:01 -0700 | [diff] [blame] | 209 | } |