1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* 28 * Much like calloc, but with functions to report the size of the 29 * allocation given only the pointer. 30 */ 31 32 #include <assert.h> 33 #include <string.h> 34 #include <malloc.h> 35 #include "sized_array.h" 36 37 /* 38 * Assumes that int is at least 32 bits and that nothing needs more than 39 * 8-byte alignment. 40 */ 41 42 /* COOKIE provides some bad-pointer protection. */ 43 #define COOKIE "SACOOKIE" 44 45 struct sized_array { 46 int n; 47 int sz; 48 #if defined(COOKIE) 49 char cookie[8]; 50 #endif 51 }; 52 53 54 void * 55 sized_array(size_t n, size_t sz) 56 { 57 struct sized_array *sa; 58 size_t total; 59 60 total = sizeof (struct sized_array) + n*sz; 61 62 sa = malloc(total); 63 64 if (sa == NULL) 65 return (NULL); 66 67 (void) memset(sa, 0, total); 68 69 sa->n = n; 70 sa->sz = sz; 71 72 #if defined(COOKIE) 73 (void) memcpy(sa->cookie, COOKIE, sizeof (sa->cookie)); 74 #endif 75 76 return ((void *)(sa + 1)); 77 } 78 79 void 80 sized_array_free(void *p) 81 { 82 struct sized_array *sa; 83 84 if (p == NULL) 85 return; 86 87 sa = ((struct sized_array *)p)-1; 88 89 #if defined(COOKIE) 90 assert(memcmp(sa->cookie, COOKIE, sizeof (sa->cookie)) == 0); 91 #endif 92 93 free(sa); 94 } 95 96 size_t 97 sized_array_n(void *p) 98 { 99 struct sized_array *sa; 100 101 sa = ((struct sized_array *)p)-1; 102 103 #if defined(COOKIE) 104 assert(memcmp(sa->cookie, COOKIE, sizeof (sa->cookie)) == 0); 105 #endif 106 107 return (sa->n); 108 } 109 110 size_t 111 sized_array_sz(void *p) 112 { 113 struct sized_array *sa; 114 115 sa = ((struct sized_array *)p)-1; 116 117 #if defined(COOKIE) 118 assert(memcmp(sa->cookie, COOKIE, sizeof (sa->cookie)) == 0); 119 #endif 120 121 return (sa->sz); 122 } 123