1570af302Sopenharmony_ci// commit: 3e936ce81bbbcc968f576aedbd5203621839f152 2014-09-19 2570af302Sopenharmony_ci// flockfile linked list handling was broken 3570af302Sopenharmony_ci#include <errno.h> 4570af302Sopenharmony_ci#include <stdio.h> 5570af302Sopenharmony_ci#include <stdlib.h> 6570af302Sopenharmony_ci#include <string.h> 7570af302Sopenharmony_ci#include "test.h" 8570af302Sopenharmony_ci 9570af302Sopenharmony_ci#define t_fatal(...) (t_error(__VA_ARGS__), _Exit(t_status)) 10570af302Sopenharmony_ci#define length(a) (sizeof(a)/sizeof*(a)) 11570af302Sopenharmony_ci 12570af302Sopenharmony_ci// interpose malloc functions 13570af302Sopenharmony_ci// freed memory is not reused, it is checked for clobber. 14570af302Sopenharmony_ci 15570af302Sopenharmony_cistatic unsigned char buf[1<<20]; 16570af302Sopenharmony_cistatic size_t pos; 17570af302Sopenharmony_cistatic struct { 18570af302Sopenharmony_ci size_t pos; 19570af302Sopenharmony_ci size_t n; 20570af302Sopenharmony_ci int freed; 21570af302Sopenharmony_ci} alloc[100]; 22570af302Sopenharmony_cistatic int idx; 23570af302Sopenharmony_ci 24570af302Sopenharmony_civoid *malloc(size_t n) 25570af302Sopenharmony_ci{ 26570af302Sopenharmony_ci if (n == 0) n++; 27570af302Sopenharmony_ci if (n > sizeof buf - pos) 28570af302Sopenharmony_ci t_fatal("test buffer is small, pos: %zu, need: %zu\n", pos, n); 29570af302Sopenharmony_ci if (idx >= length(alloc)) 30570af302Sopenharmony_ci t_fatal("test buffer is small, idx: %d\n", idx); 31570af302Sopenharmony_ci void *p = buf + pos; 32570af302Sopenharmony_ci alloc[idx].pos = pos; 33570af302Sopenharmony_ci alloc[idx].n = n; 34570af302Sopenharmony_ci pos += n; 35570af302Sopenharmony_ci idx++; 36570af302Sopenharmony_ci return p; 37570af302Sopenharmony_ci} 38570af302Sopenharmony_ci 39570af302Sopenharmony_civoid *calloc(size_t n, size_t m) 40570af302Sopenharmony_ci{ 41570af302Sopenharmony_ci return memset(malloc(n*m), 0, n*m); 42570af302Sopenharmony_ci} 43570af302Sopenharmony_ci 44570af302Sopenharmony_civoid *aligned_alloc(size_t a, size_t n) 45570af302Sopenharmony_ci{ 46570af302Sopenharmony_ci t_fatal("aligned_alloc is unsupported\n"); 47570af302Sopenharmony_ci} 48570af302Sopenharmony_ci 49570af302Sopenharmony_cistatic int findidx(void *p) 50570af302Sopenharmony_ci{ 51570af302Sopenharmony_ci size_t pos = (unsigned char *)p - buf; 52570af302Sopenharmony_ci for (int i=0; i<idx; i++) 53570af302Sopenharmony_ci if (alloc[i].pos == pos) 54570af302Sopenharmony_ci return i; 55570af302Sopenharmony_ci t_fatal("%p is not an allocated pointer\n", p); 56570af302Sopenharmony_ci return -1; 57570af302Sopenharmony_ci} 58570af302Sopenharmony_ci 59570af302Sopenharmony_civoid *realloc(void *p, size_t n) 60570af302Sopenharmony_ci{ 61570af302Sopenharmony_ci void *q = malloc(n); 62570af302Sopenharmony_ci size_t m = alloc[findidx(p)].n; 63570af302Sopenharmony_ci memcpy(q, p, m < n ? m : n); 64570af302Sopenharmony_ci free(p); 65570af302Sopenharmony_ci return q; 66570af302Sopenharmony_ci} 67570af302Sopenharmony_ci 68570af302Sopenharmony_civoid free(void *p) 69570af302Sopenharmony_ci{ 70570af302Sopenharmony_ci if (p == 0) return; 71570af302Sopenharmony_ci int i = findidx(p); 72570af302Sopenharmony_ci memset(p, 42, alloc[i].n); 73570af302Sopenharmony_ci alloc[i].freed = 1; 74570af302Sopenharmony_ci} 75570af302Sopenharmony_ci 76570af302Sopenharmony_cistatic void checkfreed(void) 77570af302Sopenharmony_ci{ 78570af302Sopenharmony_ci for (int i=0; i<idx; i++) 79570af302Sopenharmony_ci if (alloc[i].freed) 80570af302Sopenharmony_ci for (size_t j=0; j<alloc[i].n; j++) 81570af302Sopenharmony_ci if (buf[alloc[i].pos + j] != 42) { 82570af302Sopenharmony_ci t_error("freed allocation %d (pos: %zu, len: %zu) is clobbered\n", i, alloc[i].pos, alloc[i].n); 83570af302Sopenharmony_ci break; 84570af302Sopenharmony_ci } 85570af302Sopenharmony_ci} 86570af302Sopenharmony_ci 87570af302Sopenharmony_ciint main() 88570af302Sopenharmony_ci{ 89570af302Sopenharmony_ci FILE *f = tmpfile(); 90570af302Sopenharmony_ci FILE *g = tmpfile(); 91570af302Sopenharmony_ci flockfile(g); 92570af302Sopenharmony_ci flockfile(f); 93570af302Sopenharmony_ci funlockfile(g); 94570af302Sopenharmony_ci fclose(g); 95570af302Sopenharmony_ci /* may corrupt memory */ 96570af302Sopenharmony_ci funlockfile(f); 97570af302Sopenharmony_ci checkfreed(); 98570af302Sopenharmony_ci return t_status; 99570af302Sopenharmony_ci} 100