1 /* Immutable data. 2 3 Copyright (C) 2021 Free Software Foundation, Inc. 4 5 This file is free software: you can redistribute it and/or modify 6 it under the terms of the GNU Lesser General Public License as 7 published by the Free Software Foundation; either version 2.1 of the 8 License, or (at your option) any later version. 9 10 This file 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 the 13 GNU Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public License 16 along with this program. If not, see <https://www.gnu.org/licenses/>. */ 17 18 /* Written by Bruno Haible <bruno@clisp.org>, 2021. */ 19 20 #ifndef _IMMUTABLE_H 21 #define _IMMUTABLE_H 22 23 /* This file provide a facility to allocate and free immutable data objects. 24 25 An immutable data object is allocated in three steps: 26 1. You allocate an immutable memory region. 27 DATA *wp = immmalloc (sizeof (*wp)); 28 The pointer wp is actually a writable view to the memory region. 29 2. You fill the memory region, through the pointer wp: 30 wp->x = ...; 31 wp->y = ...; 32 ... 33 3. You declare the memory region as frozen. This means that you relinquish 34 write access. 35 DATA const *p = immfreeze (wp); 36 You can now let wp get out-of-scope. 37 38 Then the pointer p can be used only in read-only ways. That is, if you cast 39 away the 'const' and attempt to write to the memory region, it will crash at 40 runtime (through a SIGSEGV signal). 41 p->x = ...; // rejected by the compiler 42 ((DATA *) p)->x = ...; // crashes at runtime 43 44 Finally, you can free the immutable data object: 45 immfree (p); 46 */ 47 48 /* If you compile this module with the C macro NO_IMMUTABLE set to 1, or on a 49 platform that lacks support for read-only and writeable memory areas, the 50 functions work alike, except that the "read-only" pointers are actually 51 writable. */ 52 53 #include <stddef.h> 54 55 #ifdef __cplusplus 56 extern "C" { 57 #endif 58 59 /* This macro tells whether the implementation effectively rejects writes to 60 immutable data. */ 61 #if !NO_IMMUTABLE && ((defined _WIN32 && !defined __CYGWIN__) || HAVE_WORKING_MPROTECT) 62 # define IMMUTABLE_EFFECTIVE 1 63 #else 64 # define IMMUTABLE_EFFECTIVE 0 65 #endif 66 67 /* Allocates an immutable memory region. 68 SIZE if the number of bytes; should be > 0. 69 Returns a writeable pointer to the memory region. 70 Upon memory allocation failure, returns NULL with errno set to ENOMEM. */ 71 extern void * immmalloc (size_t size); 72 73 /* Freezes an immutable memory region. 74 WRITABLE_POINTER is a non-NULL return value from immmalloc(). 75 Returns a read-only pointer to the same memory region. */ 76 extern const void * immfreeze (void *writable_pointer); 77 78 /* Frees an immutable memory region. 79 READONLY_POINTER is a return value from immfreeze(). */ 80 extern void immfree (const void *readonly_pointer); 81 82 /* The following is just an application to some data types. */ 83 84 /* Allocates an immutable memory region that contains a copy of the given string. 85 Returns a read-only pointer to this duplicated string. 86 Upon memory allocation failure, returns NULL with errno set to ENOMEM. */ 87 extern const char * immstrdup (const char *string); 88 89 #ifdef __cplusplus 90 } 91 #endif 92 93 #endif /* _IMMUTABLE_H */