etc/services - sync with NetBSD-8
[minix.git] / minix / tests / common.c
blobb950f88dd1e4b9e3b42db8b7d541fd260c41c908
1 /* Utility routines for Minix tests.
2 * This is designed to be #includ'ed near the top of test programs. It is
3 * self-contained except for max_error.
4 */
6 #include <errno.h>
7 #include <paths.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <unistd.h>
11 #include <stdarg.h>
12 #include <stdio.h>
13 #include <sys/statvfs.h>
14 #include <sys/syslimits.h>
15 #include <sys/wait.h>
17 #include "common.h"
19 int common_test_nr = -1, errct = 0, subtest;
20 int quietflag = 1, bigflag = 0;
22 /* provide a default max_error symbol as Max_error with a value
23 * of 5. The test program can override it wit its own max_error
24 * symbol if it wants that this code will then use instead.
26 __weak_alias(max_error,Max_error);
27 int Max_error = 5;
28 extern int max_error;
30 void start(test_nr)
31 int test_nr;
33 char buf[64];
34 int i;
36 /* if this variable is set, specify to tests we are running
37 * in 'overnight' mode
39 bigflag = !!getenv(BIGVARNAME);
41 common_test_nr = test_nr;
42 printf("Test %2d ", test_nr);
43 fflush(stdout); /* since stdout is probably line buffered */
44 sync();
45 rm_rf_dir(test_nr);
46 sprintf(buf, "mkdir DIR_%02d", test_nr);
47 if (system(buf) != 0) {
48 e(666);
49 quit();
51 sprintf(buf, "DIR_%02d", test_nr);
52 if (chdir(buf) != 0) {
53 e(6666);
54 quit();
57 for (i = 3; i < OPEN_MAX; ++i) {
58 /* Close all files except stdin, stdout, and stderr */
59 (void) close(i);
63 int does_fs_truncate(void)
65 struct statvfs stvfs;
66 int does_truncate = 0;
67 char cwd[PATH_MAX]; /* Storage for path to current working dir */
69 if (realpath(".", cwd) == NULL) e(7777); /* Get current working dir */
70 if (statvfs(cwd, &stvfs) != 0) e(7778); /* Get FS information */
71 /* Depending on how an FS handles too long file names, we have to adjust our
72 * error checking. If an FS does not truncate file names, it should generate
73 * an ENAMETOOLONG error when we provide too long a file name.
75 if (!(stvfs.f_flag & ST_NOTRUNC)) does_truncate = 1;
77 return(does_truncate);
80 int name_max(char *path)
82 struct statvfs stvfs;
84 if (statvfs(path, &stvfs) != 0) e(7779);
85 return(stvfs.f_namemax);
89 void rm_rf_dir(test_nr)
90 int test_nr;
92 char buf[128];
94 sprintf(buf, "rm -rf DIR_%02d >/dev/null 2>&1", test_nr);
95 if (system_p(buf) != 0) printf("Warning: system(\"%s\") failed\n", buf);
98 void rm_rf_ppdir(test_nr)
99 int test_nr;
101 /* Attempt to remove everything in the test directory (== the current dir). */
103 char buf[128];
105 sprintf(buf, "chmod 777 ../DIR_%02d/* ../DIR_%02d/*/* >/dev/null 2>&1",
106 test_nr, test_nr);
107 (void) system(buf);
108 sprintf(buf, "rm -rf ../DIR_%02d >/dev/null 2>&1", test_nr);
109 if (system(buf) != 0) printf("Warning: system(\"%s\") failed\n", buf);
112 void e_f(char *file, int line, int n)
114 int err_number;
115 err_number = errno; /* Store before printf can clobber it */
116 if (errct == 0) printf("\n"); /* finish header */
117 printf("%s:%d: Subtest %d, error %d, errno %d: %s\n",
118 file, line, subtest, n, err_number, strerror(err_number));
119 if (++errct > max_error) {
120 printf("Too many errors; test aborted\n");
121 cleanup();
122 exit(1);
124 errno = err_number;
127 void cleanup()
129 if (chdir("..") == 0 && common_test_nr != -1) rm_rf_dir(common_test_nr);
132 void fail_printf(const char *file, const char *func, int line,
133 const char *fmt, ...) {
134 va_list ap;
135 char buf[1024];
136 size_t len;
138 len = snprintf(buf, sizeof(buf), "[%s:%s:%d] ", file, func, line);
140 va_start(ap, fmt);
141 len += vsnprintf(buf + len, sizeof(buf) - len, fmt, ap);
142 va_end(ap);
144 snprintf(buf + len, sizeof(buf) - len, " errno=%d error=%s",
145 errno, strerror(errno));
147 em(line, buf);
150 void quit()
152 cleanup();
153 if (errct == 0) {
154 printf("ok\n");
155 exit(0);
156 } else {
157 printf("%d errors\n", errct);
158 exit(1);
162 void
163 printprogress(char *msg, int i, int max)
165 int use_i = i + 1;
166 static time_t start_time, prev_time;
167 static int prev_i;
168 time_t now;
170 if(quietflag) return;
172 time(&now);
173 if(prev_i >= i) start_time = now;
175 if(now > start_time && prev_time < now) {
176 double i_per_sec = i / (now - start_time);
177 int remain_secs;
179 remain_secs = (int)((max-i) / i_per_sec);
181 fprintf(stderr, "%-35s %7d/%7d %3d%% ETA %3ds\r", msg,
182 use_i, (max), use_i*100/(max), remain_secs);
183 fflush(stderr);
186 if(use_i >= max) {
187 fprintf(stderr, "%-35s done \n", msg);
190 prev_i = i;
191 prev_time = now;
194 void getmem(uint32_t *total, uint32_t *free, uint32_t *cached)
196 uint32_t pagesize, largest;
197 FILE *f = fopen("/proc/meminfo", "r");
198 if(!f) return;
199 if(fscanf(f, "%u %u %u %u %u", &pagesize, total, free,
200 &largest, cached) != 5) {
201 fprintf(stderr, "fscanf of meminfo failed\n");
202 exit(1);
204 fclose(f);
207 static int get_setting(const char *name, int def)
209 const char *value;
211 value = getenv(name);
212 if (!value || !*value) return def;
213 if (strcmp(value, "yes") == 0) return 1;
214 if (strcmp(value, "no") == 0) return 0;
216 fprintf(stderr, "warning: invalid $%s value: %s\n", name, value);
217 return 0;
220 int get_setting_use_network(void)
222 /* set $USENETWORK to "yes" or "no" to indicate whether
223 * an internet connection is to be expected; defaults to "no"
225 return get_setting("USENETWORK", 0);
229 system_p(const char *command)
231 extern char **environ;
232 pid_t pid;
233 int pstat;
234 const char *argp[] = {"sh", "-c", "-p", NULL, NULL};
235 argp[3] = command;
237 switch(pid = vfork()) {
238 case -1: /* error */
239 return -1;
240 case 0: /* child */
241 execve(_PATH_BSHELL, __UNCONST(argp), environ);
242 _exit(127);
245 while (waitpid(pid, &pstat, 0) == -1) {
246 if (errno != EINTR) {
247 pstat = -1;
248 break;
252 return (pstat);