1 /* 2 libparted - a library for manipulating disk partitions 3 Copyright (C) 1999, 2000, 2001, 2007 Free Software Foundation, Inc. 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 3 of the License, or 8 (at your option) any later version. 9 10 This program 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 General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program. If not, see <http://www.gnu.org/licenses/>. 17 */ 18 19 #include <config.h> 20 #include "configmake.h" 21 22 #include <parted/parted.h> 23 #include <parted/debug.h> 24 25 #ifdef linux 26 # include <parted/linux.h> 27 #elif defined(__BEOS__) 28 # include <parted/beos.h> 29 #elif defined(__sun) 30 # include <parted/solaris.h> 31 #else 32 # include <parted/gnu.h> 33 #endif 34 35 #if ENABLE_NLS 36 # include <locale.h> 37 # include <libintl.h> 38 # define _(String) dgettext (PACKAGE, String) 39 #else 40 # define _(String) (String) 41 #endif /* ENABLE_NLS */ 42 43 const PedArchitecture* ped_architecture; 44 45 /* ped_malloc() debugging. Stick the address and size of memory blocks that 46 * weren't ped_free()d in here, and an exception will be thrown when it is 47 * allocated. That way, you can find out what, exactly, the allocated thing 48 * is, and where it is created. 49 */ 50 typedef struct 51 { 52 void* pointer; 53 size_t size; 54 } pointer_size_type; 55 56 /* IMHO, none of the DEBUG-related code below is useful, and the 57 ped_malloc memset code is actually quite harmful: it masked at 58 least two nasty bugs that were fixed in June of 2007. */ 59 #undef DEBUG 60 #ifdef DEBUG 61 static pointer_size_type dodgy_malloc_list[] = { 62 {0, 0}, 63 {0, 0}, 64 {0, 0}, 65 {0, 0}, 66 {0, 0}, 67 {0, 0}, 68 {0, 0}, 69 {0, 0}, 70 {0, 0}, 71 {0, 0} 72 }; 73 74 static int dodgy_memory_active[100]; 75 #endif /* DEBUG */ 76 77 int 78 ped_set_architecture (const PedArchitecture* arch) 79 { 80 PED_ASSERT (ped_device_get_next (NULL) == NULL, return 0); 81 82 ped_architecture = arch; 83 return 1; 84 } 85 86 extern void ped_disk_aix_init (); 87 extern void ped_disk_bsd_init (); 88 extern void ped_disk_dvh_init (); 89 extern void ped_disk_gpt_init (); 90 extern void ped_disk_loop_init (); 91 extern void ped_disk_mac_init (); 92 extern void ped_disk_msdos_init (); 93 extern void ped_disk_pc98_init (); 94 extern void ped_disk_sun_init (); 95 extern void ped_disk_amiga_init (); 96 extern void ped_disk_dasd_init (); 97 98 static void 99 init_disk_types () 100 { 101 ped_disk_loop_init (); /* must be last in the probe list */ 102 103 #if defined(__s390__) || defined(__s390x__) 104 ped_disk_dasd_init(); 105 #endif 106 107 ped_disk_sun_init (); 108 #ifdef ENABLE_PC98 109 ped_disk_pc98_init (); 110 #endif 111 ped_disk_msdos_init (); 112 ped_disk_mac_init (); 113 ped_disk_gpt_init (); 114 ped_disk_dvh_init (); 115 ped_disk_bsd_init (); 116 ped_disk_amiga_init (); 117 ped_disk_aix_init (); 118 } 119 120 #ifdef ENABLE_FS 121 extern void ped_file_system_amiga_init (void); 122 extern void ped_file_system_xfs_init (void); 123 extern void ped_file_system_ufs_init (void); 124 extern void ped_file_system_reiserfs_init (void); 125 extern void ped_file_system_ntfs_init (void); 126 extern void ped_file_system_linux_swap_init (void); 127 extern void ped_file_system_jfs_init (void); 128 extern void ped_file_system_hfs_init (void); 129 extern void ped_file_system_fat_init (void); 130 extern void ped_file_system_ext2_init (void); 131 extern void ped_file_system_solaris_x86_init (void); 132 133 static void 134 init_file_system_types () 135 { 136 ped_file_system_amiga_init (); 137 ped_file_system_xfs_init (); 138 ped_file_system_ufs_init (); 139 ped_file_system_reiserfs_init (); 140 ped_file_system_ntfs_init (); 141 ped_file_system_linux_swap_init (); 142 ped_file_system_jfs_init (); 143 ped_file_system_hfs_init (); 144 ped_file_system_fat_init (); 145 ped_file_system_ext2_init (); 146 ped_file_system_solaris_x86_init (); 147 } 148 #endif /* ENABLE_FS */ 149 150 extern void ped_disk_aix_done (); 151 extern void ped_disk_bsd_done (); 152 extern void ped_disk_dvh_done (); 153 extern void ped_disk_gpt_done (); 154 extern void ped_disk_loop_done (); 155 extern void ped_disk_mac_done (); 156 extern void ped_disk_msdos_done (); 157 extern void ped_disk_pc98_done (); 158 extern void ped_disk_sun_done (); 159 extern void ped_disk_amiga_done (); 160 extern void ped_disk_dasd_done (); 161 162 static void 163 done_disk_types () 164 { 165 #if defined(__s390__) || (__s390x__) 166 ped_disk_dasd_done (); 167 #endif 168 ped_disk_sun_done (); 169 #ifdef ENABLE_PC98 170 ped_disk_pc98_done (); 171 #endif 172 ped_disk_msdos_done (); 173 ped_disk_mac_done (); 174 ped_disk_loop_done (); 175 ped_disk_gpt_done (); 176 ped_disk_dvh_done (); 177 ped_disk_bsd_done (); 178 ped_disk_amiga_done (); 179 ped_disk_aix_done (); 180 } 181 182 static void _init() __attribute__ ((constructor)); 183 184 static void 185 _init() 186 { 187 #ifdef ENABLE_NLS 188 bindtextdomain (PACKAGE, LOCALEDIR); 189 #endif 190 191 init_disk_types (); 192 193 #ifdef ENABLE_FS 194 init_file_system_types (); 195 #endif 196 197 /* FIXME: a better way of doing this? */ 198 #ifdef linux 199 ped_set_architecture (&ped_linux_arch); 200 #elif defined(__BEOS__) 201 ped_set_architecture (&ped_beos_arch); 202 #elif defined (__sun) 203 ped_set_architecture (&ped_solaris_arch); 204 #else 205 ped_set_architecture (&ped_gnu_arch); 206 #endif 207 208 #ifdef DEBUG 209 memset (dodgy_memory_active, 0, sizeof (dodgy_memory_active)); 210 #endif 211 } 212 213 #ifdef ENABLE_FS 214 extern void ped_file_system_ext2_done (void); 215 extern void ped_file_system_fat_done (void); 216 extern void ped_file_system_hfs_done (void); 217 extern void ped_file_system_jfs_done (void); 218 extern void ped_file_system_linux_swap_done (void); 219 extern void ped_file_system_ntfs_done (void); 220 extern void ped_file_system_reiserfs_done (void); 221 extern void ped_file_system_ufs_done (void); 222 extern void ped_file_system_xfs_done (void); 223 extern void ped_file_system_amiga_done (void); 224 225 static void 226 done_file_system_types () 227 { 228 ped_file_system_ext2_done (); 229 ped_file_system_fat_done (); 230 ped_file_system_hfs_done (); 231 ped_file_system_jfs_done (); 232 ped_file_system_linux_swap_done (); 233 ped_file_system_ntfs_done (); 234 ped_file_system_reiserfs_done (); 235 ped_file_system_ufs_done (); 236 ped_file_system_xfs_done (); 237 ped_file_system_amiga_done (); 238 } 239 #endif /* ENABLE_FS */ 240 241 static void _done() __attribute__ ((destructor)); 242 243 static void 244 _done() 245 { 246 ped_device_free_all (); 247 248 done_disk_types (); 249 250 #ifdef ENABLE_FS 251 done_file_system_types (); 252 #endif 253 } 254 255 const char* 256 ped_get_version () 257 { 258 return VERSION; 259 } 260 261 #ifdef DEBUG 262 static void 263 _check_dodgy_pointer (const void* ptr, size_t size, int is_malloc) 264 { 265 int i; 266 267 for (i=0; dodgy_malloc_list[i].pointer; i++) { 268 if (dodgy_malloc_list[i].pointer != ptr) 269 continue; 270 if (is_malloc && dodgy_malloc_list[i].size != size) 271 continue; 272 if (!is_malloc && !dodgy_memory_active[i]) 273 continue; 274 275 276 if (is_malloc) { 277 ped_exception_throw ( 278 PED_EXCEPTION_INFORMATION, 279 PED_EXCEPTION_OK, 280 "Dodgy malloc(%x) == %p occurred (active==%d)", 281 size, ptr, dodgy_memory_active[i]); 282 dodgy_memory_active[i]++; 283 } else { 284 ped_exception_throw ( 285 PED_EXCEPTION_INFORMATION, 286 PED_EXCEPTION_OK, 287 "Dodgy free(%p) occurred (active==%d)", 288 ptr, dodgy_memory_active[i]); 289 dodgy_memory_active[i]--; 290 } 291 292 return; 293 } 294 } 295 #endif /* DEBUG */ 296 297 void* 298 ped_malloc (size_t size) 299 { 300 void* mem; 301 302 mem = (void*) malloc (size); 303 if (!mem) { 304 ped_exception_throw (PED_EXCEPTION_FATAL, PED_EXCEPTION_CANCEL, 305 _("Out of memory.")); 306 return NULL; 307 } 308 309 #ifdef DEBUG 310 memset (mem, 0xff, size); 311 _check_dodgy_pointer (mem, size, 1); 312 #endif 313 314 return mem; 315 } 316 317 int 318 ped_realloc (void** old, size_t size) 319 { 320 void* mem; 321 322 mem = (void*) realloc (*old, size); 323 if (!mem) { 324 ped_exception_throw (PED_EXCEPTION_FATAL, PED_EXCEPTION_CANCEL, 325 _("Out of memory.")); 326 return 0; 327 } 328 *old = mem; 329 return 1; 330 } 331 332 333 void* ped_calloc (size_t size) 334 { 335 void* buf = ped_malloc (size); 336 337 memset (buf, 0, size); 338 339 return buf; 340 } 341 342 343 void 344 ped_free (void* ptr) 345 { 346 #ifdef DEBUG 347 _check_dodgy_pointer (ptr, 0, 0); 348 #endif 349 350 free (ptr); 351 }