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 */