Convert tabs to spaces
[obnox/tinyproxy.git] / src / heap.c
1 /* tinyproxy - A fast light-weight HTTP proxy
2  * Copyright (C) 2002 Robert James Kaes <rjkaes@users.sourceforge.net>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18
19 /* Debugging versions of various heap related functions are combined
20  * here.  The debugging versions include assertions and also print
21  * (to standard error) the function called along with the amount
22  * of memory allocated, and where the memory is pointing.  The
23  * format of the log message is standardized.
24  */
25
26 #include "tinyproxy.h"
27 #include "heap.h"
28 #include "text.h"
29
30 void *
31 debugging_calloc (size_t nmemb, size_t size, const char *file,
32                   unsigned long line)
33 {
34   void *ptr;
35
36   assert (nmemb > 0);
37   assert (size > 0);
38
39   ptr = calloc (nmemb, size);
40   fprintf (stderr, "{calloc: %p:%zu x %zu} %s:%lu\n", ptr, nmemb, size, file,
41            line);
42   return ptr;
43 }
44
45 void *
46 debugging_malloc (size_t size, const char *file, unsigned long line)
47 {
48   void *ptr;
49
50   assert (size > 0);
51
52   ptr = malloc (size);
53   fprintf (stderr, "{malloc: %p:%zu} %s:%lu\n", ptr, size, file, line);
54   return ptr;
55 }
56
57 void *
58 debugging_realloc (void *ptr, size_t size, const char *file,
59                    unsigned long line)
60 {
61   void *newptr;
62
63   assert (size > 0);
64
65   newptr = realloc (ptr, size);
66   fprintf (stderr, "{realloc: %p -> %p:%zu} %s:%lu\n", ptr, newptr, size,
67            file, line);
68   return newptr;
69 }
70
71 void
72 debugging_free (void *ptr, const char *file, unsigned long line)
73 {
74   fprintf (stderr, "{free: %p} %s:%lu\n", ptr, file, line);
75
76   if (ptr != NULL)
77     free (ptr);
78   return;
79 }
80
81 char *
82 debugging_strdup (const char *s, const char *file, unsigned long line)
83 {
84   char *ptr;
85   size_t len;
86
87   assert (s != NULL);
88
89   len = strlen (s) + 1;
90   ptr = malloc (len);
91   if (!ptr)
92     return NULL;
93   memcpy (ptr, s, len);
94
95   fprintf (stderr, "{strdup: %p:%zu} %s:%lu\n", ptr, len, file, line);
96   return ptr;
97 }
98
99 /*
100  * Allocate a block of memory in the "shared" memory region.
101  *
102  * FIXME: This uses the most basic (and slowest) means of creating a
103  * shared memory location.  It requires the use of a temporary file.  We might
104  * want to look into something like MM (Shared Memory Library) for a better
105  * solution.
106  */
107 void *
108 malloc_shared_memory (size_t size)
109 {
110   int fd;
111   void *ptr;
112   char buffer[32];
113
114   static char *shared_file = "/tmp/tinyproxy.shared.XXXXXX";
115
116   assert (size > 0);
117
118   strlcpy (buffer, shared_file, sizeof (buffer));
119
120   /* Only allow u+rw bits. This may be required for some versions
121    * of glibc so that mkstemp() doesn't make us vulnerable.
122    */
123   umask (0177);
124
125   if ((fd = mkstemp (buffer)) == -1)
126     return MAP_FAILED;
127   unlink (buffer);
128
129   if (ftruncate (fd, size) == -1)
130     return MAP_FAILED;
131   ptr = mmap (NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
132
133   return ptr;
134 }
135
136 /*
137  * Allocate a block of memory from the "shared" region an initialize it to
138  * zero.
139  */
140 void *
141 calloc_shared_memory (size_t nmemb, size_t size)
142 {
143   void *ptr;
144   long length;
145
146   assert (nmemb > 0);
147   assert (size > 0);
148
149   length = nmemb * size;
150
151   ptr = malloc_shared_memory (length);
152   if (ptr == MAP_FAILED)
153     return ptr;
154
155   memset (ptr, 0, length);
156
157   return ptr;
158 }