14710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 24710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Support for dynamic loading of extension modules */ 34710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 44710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include <kernel/image.h> 54710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include <kernel/OS.h> 64710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include <stdlib.h> 74710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 84710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include "Python.h" 94710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include "importdl.h" 104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmconst struct filedescr _PyImport_DynLoadFiletab[] = { 124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {".so", "rb", C_EXTENSION}, 134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {"module.so", "rb", C_EXTENSION}, 144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm {0, 0} 154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}; 164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#if defined(MAXPATHLEN) && !defined(_SYS_PARAM_H) 184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#undef MAXPATHLEN 194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif 204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef WITH_THREAD 224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include "pythread.h" 234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyThread_type_lock beos_dyn_lock; 244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif 254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject *beos_dyn_images = NULL; 274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* ---------------------------------------------------------------------- 294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * BeOS dynamic loading support 304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * 314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * This uses shared libraries, but BeOS has its own way of doing things 324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * (much easier than dlfnc.h, from the look of things). We'll use a 334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * Python Dictionary object to store the images_ids so we can be very 344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * nice and unload them when we exit. 354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * 364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * Note that this is thread-safe. Probably irrelevent, because of losing 374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * systems... Python probably disables threads while loading modules. 384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * Note the use of "probably"! Better to be safe than sorry. [chrish] 394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * 404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * As of 1.5.1 this should also work properly when you've configured 414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * Python without thread support; the 1.5 version required it, which wasn't 424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * very friendly. Note that I haven't tested it without threading... why 434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * would you want to avoid threads on BeOS? [chrish] 444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * 454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * As of 1.5.2, the PyImport_BeImageID() function has been removed; Donn 464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * tells me it's not necessary anymore because of PyCObject_Import(). 474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * [chrish] 484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */ 494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Whack an item; the item is an image_id in disguise, so we'll call 514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * unload_add_on() for it. 524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */ 534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic void beos_nuke_dyn( PyObject *item ) 544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm status_t retval; 564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if( item ) { 584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm image_id id = (image_id)PyInt_AsLong( item ); 594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm retval = unload_add_on( id ); 614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* atexit() handler that'll call unload_add_on() for every item in the 654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * dictionary. 664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */ 674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic void beos_cleanup_dyn( void ) 684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if( beos_dyn_images ) { 704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm int idx; 714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm int list_size; 724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *id_list; 734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef WITH_THREAD 754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyThread_acquire_lock( beos_dyn_lock, 1 ); 764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif 774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm id_list = PyDict_Values( beos_dyn_images ); 794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm list_size = PyList_Size( id_list ); 814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm for( idx = 0; idx < list_size; idx++ ) { 824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *the_item; 834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm the_item = PyList_GetItem( id_list, idx ); 854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm beos_nuke_dyn( the_item ); 864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyDict_Clear( beos_dyn_images ); 894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef WITH_THREAD 914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyThread_free_lock( beos_dyn_lock ); 924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif 934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* 974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * Initialize our dictionary, and the dictionary mutex. 984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */ 994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic void beos_init_dyn( void ) 1004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 1014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* We're protected from a race condition here by the atomic init_count 1024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * variable. 1034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */ 1044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm static int32 init_count = 0; 1054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm int32 val; 1064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm val = atomic_add( &init_count, 1 ); 1084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if( beos_dyn_images == NULL && val == 0 ) { 1094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm beos_dyn_images = PyDict_New(); 1104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef WITH_THREAD 1114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm beos_dyn_lock = PyThread_allocate_lock(); 1124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif 1134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm atexit( beos_cleanup_dyn ); 1144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 1154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 1164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* 1184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * Add an image_id to the dictionary; the module name of the loaded image 1194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * is the key. Note that if the key is already in the dict, we unload 1204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * that image; this should allow reload() to work on dynamically loaded 1214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * modules (super-keen!). 1224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */ 1234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic void beos_add_dyn( char *name, image_id id ) 1244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 1254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm int retval; 1264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyObject *py_id; 1274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if( beos_dyn_images == NULL ) { 1294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm beos_init_dyn(); 1304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 1314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef WITH_THREAD 1334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm retval = PyThread_acquire_lock( beos_dyn_lock, 1 ); 1344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif 1354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* If there's already an object with this key in the dictionary, 1374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * we're doing a reload(), so let's nuke it. 1384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */ 1394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm py_id = PyDict_GetItemString( beos_dyn_images, name ); 1404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if( py_id ) { 1414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm beos_nuke_dyn( py_id ); 1424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm retval = PyDict_DelItemString( beos_dyn_images, name ); 1434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 1444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm py_id = PyInt_FromLong( (long)id ); 1464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if( py_id ) { 1474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm retval = PyDict_SetItemString( beos_dyn_images, name, py_id ); 1484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 1494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef WITH_THREAD 1514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyThread_release_lock( beos_dyn_lock ); 1524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif 1534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 1544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmdl_funcptr _PyImport_GetDynLoadFunc(const char *fqname, const char *shortname, 1584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm const char *pathname, FILE *fp) 1594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{ 1604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm dl_funcptr p; 1614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm image_id the_id; 1624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm status_t retval; 1634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm char fullpath[PATH_MAX]; 1644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm char funcname[258]; 1654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if( Py_VerboseFlag ) { 1674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm printf( "load_add_on( %s )\n", pathname ); 1684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 1694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* Hmm, this old bug appears to have regenerated itself; if the 1714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * path isn't absolute, load_add_on() will fail. Reported to Be 1724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * April 21, 1998. 1734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */ 1744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if( pathname[0] != '/' ) { 1754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (void)getcwd( fullpath, PATH_MAX ); 1764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (void)strncat( fullpath, "/", PATH_MAX ); 1774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (void)strncat( fullpath, pathname, PATH_MAX ); 1784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if( Py_VerboseFlag ) { 1804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm printf( "load_add_on( %s )\n", fullpath ); 1814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 1824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } else { 1834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm (void)strcpy( fullpath, pathname ); 1844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 1854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm the_id = load_add_on( fullpath ); 1874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if( the_id < B_NO_ERROR ) { 1884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* It's too bad load_add_on() doesn't set errno or something... 1894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */ 1904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm char buff[256]; /* hate hard-coded string sizes... */ 1914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if( Py_VerboseFlag ) { 1934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm printf( "load_add_on( %s ) failed", fullpath ); 1944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 1954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 1964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if( the_id == B_ERROR ) 1974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyOS_snprintf( buff, sizeof(buff), 1984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "BeOS: Failed to load %.200s", 1994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm fullpath ); 2004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm else 2014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyOS_snprintf( buff, sizeof(buff), 2024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "Unknown error loading %.200s", 2034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm fullpath ); 2044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_SetString( PyExc_ImportError, buff ); 2064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 2074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 2084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyOS_snprintf(funcname, sizeof(funcname), "init%.200s", shortname); 2104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if( Py_VerboseFlag ) { 2114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm printf( "get_image_symbol( %s )\n", funcname ); 2124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 2134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm retval = get_image_symbol( the_id, funcname, B_SYMBOL_TYPE_TEXT, &p ); 2154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if( retval != B_NO_ERROR || p == NULL ) { 2164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* That's bad, we can't find that symbol in the module... 2174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */ 2184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm char buff[256]; /* hate hard-coded string sizes... */ 2194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm if( Py_VerboseFlag ) { 2214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm printf( "get_image_symbol( %s ) failed", funcname ); 2224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 2234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm switch( retval ) { 2254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm case B_BAD_IMAGE_ID: 2264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyOS_snprintf( buff, sizeof(buff), 2274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "can't load init function for dynamic module: " 2284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "Invalid image ID for %.180s", fullpath ); 2294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm break; 2304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm case B_BAD_INDEX: 2314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyOS_snprintf( buff, sizeof(buff), 2324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "can't load init function for dynamic module: " 2334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "Bad index for %.180s", funcname ); 2344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm break; 2354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm default: 2364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyOS_snprintf( buff, sizeof(buff), 2374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "can't load init function for dynamic module: " 2384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm "Unknown error looking up %.180s", funcname ); 2394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm break; 2404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 2414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm retval = unload_add_on( the_id ); 2434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm PyErr_SetString( PyExc_ImportError, buff ); 2454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return NULL; 2464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm } 2474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm /* Save the module name and image ID for later so we can clean up 2494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * gracefully. 2504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */ 2514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm beos_add_dyn( fqname, the_id ); 2524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm 2534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm return p; 2544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} 255