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 */ 5 6 #include <errno.h> 7 #include <stdlib.h> 8 #include <string.h> 9 #include <unistd.h> 10 #include <stdio.h> 11 #include <sys/statvfs.h> 12 #include <sys/syslimits.h> 13 14 #include "common.h" 15 16 int common_test_nr = -1, errct = 0, subtest; 17 int quietflag = 1, bigflag = 0; 18 19 /* provide a default max_error symbol as Max_error with a value 20 * of 5. The test program can override it wit its own max_error 21 * symbol if it wants that this code will then use instead. 22 */ 23 __weak_alias(max_error,Max_error); 24 int Max_error = 5; 25 extern int max_error; 26 27 void start(test_nr) 28 int test_nr; 29 { 30 char buf[64]; 31 int i; 32 33 /* if this variable is set, specify to tests we are running 34 * in 'overnight' mode 35 */ 36 bigflag = !!getenv(BIGVARNAME); 37 38 common_test_nr = test_nr; 39 printf("Test %2d ", test_nr); 40 fflush(stdout); /* since stdout is probably line buffered */ 41 sync(); 42 rm_rf_dir(test_nr); 43 sprintf(buf, "mkdir DIR_%02d", test_nr); 44 if (system(buf) != 0) { 45 e(666); 46 quit(); 47 } 48 sprintf(buf, "DIR_%02d", test_nr); 49 if (chdir(buf) != 0) { 50 e(6666); 51 quit(); 52 } 53 54 for (i = 3; i < OPEN_MAX; ++i) { 55 /* Close all files except stdin, stdout, and stderr */ 56 (void) close(i); 57 } 58 } 59 60 int does_fs_truncate(void) 61 { 62 struct statvfs stvfs; 63 int does_truncate = 0; 64 char cwd[PATH_MAX]; /* Storage for path to current working dir */ 65 66 if (realpath(".", cwd) == NULL) e(7777); /* Get current working dir */ 67 if (statvfs(cwd, &stvfs) != 0) e(7778); /* Get FS information */ 68 /* Depending on how an FS handles too long file names, we have to adjust our 69 * error checking. If an FS does not truncate file names, it should generate 70 * an ENAMETOOLONG error when we provide too long a file name. 71 */ 72 if (!(stvfs.f_flag & ST_NOTRUNC)) does_truncate = 1; 73 74 return(does_truncate); 75 } 76 77 int name_max(char *path) 78 { 79 struct statvfs stvfs; 80 81 if (statvfs(path, &stvfs) != 0) e(7779); 82 return(stvfs.f_namemax); 83 } 84 85 86 void rm_rf_dir(test_nr) 87 int test_nr; 88 { 89 char buf[128]; 90 91 sprintf(buf, "rm -rf DIR_%02d >/dev/null 2>&1", test_nr); 92 if (system(buf) != 0) printf("Warning: system(\"%s\") failed\n", buf); 93 } 94 95 void rm_rf_ppdir(test_nr) 96 int test_nr; 97 { 98 /* Attempt to remove everything in the test directory (== the current dir). */ 99 100 char buf[128]; 101 102 sprintf(buf, "chmod 777 ../DIR_%02d/* ../DIR_%02d/*/* >/dev/null 2>&1", 103 test_nr, test_nr); 104 (void) system(buf); 105 sprintf(buf, "rm -rf ../DIR_%02d >/dev/null 2>&1", test_nr); 106 if (system(buf) != 0) printf("Warning: system(\"%s\") failed\n", buf); 107 } 108 109 void e_f(char *file, int line, int n) 110 { 111 int err_number; 112 err_number = errno; /* Store before printf can clobber it */ 113 if (errct == 0) printf("\n"); /* finish header */ 114 printf("%s:%d: Subtest %d, error %d, errno %d: %s\n", 115 file, line, subtest, n, err_number, strerror(err_number)); 116 if (++errct > max_error) { 117 printf("Too many errors; test aborted\n"); 118 cleanup(); 119 exit(1); 120 } 121 errno = err_number; 122 } 123 124 void cleanup() 125 { 126 if (chdir("..") == 0 && common_test_nr != -1) rm_rf_dir(common_test_nr); 127 } 128 129 void quit() 130 { 131 cleanup(); 132 if (errct == 0) { 133 printf("ok\n"); 134 exit(0); 135 } else { 136 printf("%d errors\n", errct); 137 exit(1); 138 } 139 } 140 141 void 142 printprogress(char *msg, int i, int max) 143 { 144 int use_i = i + 1; 145 static time_t start_time, prev_time; 146 static int prev_i; 147 time_t now; 148 149 if(quietflag) return; 150 151 time(&now); 152 if(prev_i >= i) start_time = now; 153 154 if(now > start_time && prev_time < now) { 155 double i_per_sec = i / (now - start_time); 156 int remain_secs; 157 158 remain_secs = (int)((max-i) / i_per_sec); 159 160 fprintf(stderr, "%-35s %7d/%7d %3d%% ETA %3ds\r", msg, 161 use_i, (max), use_i*100/(max), remain_secs); 162 fflush(stderr); 163 } 164 165 if(use_i >= max) { 166 fprintf(stderr, "%-35s done \n", msg); 167 } 168 169 prev_i = i; 170 prev_time = now; 171 } 172 173 void getmem(u32_t *total, u32_t *free, u32_t *cached) 174 { 175 u32_t pagesize, largest; 176 FILE *f = fopen("/proc/meminfo", "r"); 177 if(!f) return; 178 if(fscanf(f, "%u %u %u %u %u", &pagesize, total, free, 179 &largest, cached) != 5) { 180 fprintf(stderr, "fscanf of meminfo failed\n"); 181 exit(1); 182 } 183 fclose(f); 184 } 185 186