@@ -37,6 +37,18 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
3737#include "compile.h"
3838#include "ceval.h"
3939
40+ #ifdef DEBUG
41+ #define D (x ) x
42+ #else
43+ #define D (x )
44+ #endif
45+
46+ #ifdef USE_DL
47+ #include "dl.h"
48+
49+ static char * getbinaryname ();
50+ #endif
51+
4052/* Magic word to reject pre-0.9.4 .pyc files */
4153
4254#define MAGIC 0x949494L
@@ -93,19 +105,38 @@ add_module(name)
93105 return m ;
94106}
95107
108+ /* Suffixes used by open_module: */
109+
110+ #define PY_SUFFIX ".py"
111+ #ifdef USE_DL
112+ #define O_SUFFIX "module.o"
113+ #endif
114+
115+ /* Find and open a module file, using sys.path.
116+ Return a NULL pointer if no module file is found.
117+ When dynamic loading is enabled, the contents of namebuf
118+ is important when NULL is returned: if namebuf[0] != '\0'
119+ a dl-able object file was found and namebuf is its pathname. */
120+
96121static FILE *
97- open_module (name , suffix , namebuf )
122+ open_module (name , namebuf )
98123 char * name ;
99- char * suffix ;
100124 char * namebuf ; /* XXX No buffer overflow checks! */
101125{
102126 object * path ;
103127 FILE * fp ;
104128
105129 path = sysget ("path" );
106130 if (path == NULL || !is_listobject (path )) {
131+ /* No path -- at least try current directory */
132+ #ifdef USE_DL
133+ strcpy (namebuf , name );
134+ strcat (namebuf , O_SUFFIX );
135+ if (getmtime (namebuf ) > 0 )
136+ return NULL ;
137+ #endif
107138 strcpy (namebuf , name );
108- strcat (namebuf , suffix );
139+ strcat (namebuf , PY_SUFFIX );
109140 fp = fopen (namebuf , "r" );
110141 }
111142 else {
@@ -121,13 +152,21 @@ open_module(name, suffix, namebuf)
121152 len = getstringsize (v );
122153 if (len > 0 && namebuf [len - 1 ] != SEP )
123154 namebuf [len ++ ] = SEP ;
155+ #ifdef USE_DL
124156 strcpy (namebuf + len , name );
125- strcat (namebuf , suffix );
157+ strcat (namebuf , O_SUFFIX );
158+ if (getmtime (namebuf ) > 0 )
159+ return NULL ;
160+ #endif
161+ strcpy (namebuf + len , name );
162+ strcat (namebuf , PY_SUFFIX );
126163 fp = fopen (namebuf , "r" );
127164 if (fp != NULL )
128165 break ;
129166 }
130167 }
168+ if (fp == NULL )
169+ namebuf [0 ] = '\0' ;
131170 return fp ;
132171}
133172
@@ -147,8 +186,35 @@ get_module(m, name, m_ret)
147186 long mtime ;
148187 extern long getmtime ();
149188
150- fp = open_module (name , ".py" , namebuf );
189+ fp = open_module (name , namebuf );
151190 if (fp == NULL ) {
191+ #ifdef USE_DL
192+ if (namebuf [0 ] != '\0' ) {
193+ char funcname [258 ];
194+ dl_funcptr p ;
195+ D (fprintf (stderr , "Found %s\n" , namebuf ));
196+ sprintf (funcname , "init%s" , name );
197+ p = dl_loadmod (getbinaryname (), namebuf , funcname );
198+ if (p == NULL ) {
199+ D (fprintf (stderr , "dl_loadmod failed\n" ));
200+ }
201+ else {
202+ (* p )();
203+ * m_ret = m = dictlookup (modules , name );
204+ if (m == NULL ) {
205+ err_setstr (SystemError ,
206+ "dynamic module missing" );
207+ return NULL ;
208+ }
209+ else {
210+ D (fprintf (stderr ,
211+ "module %s loaded!\n" , name ));
212+ INCREF (None );
213+ return None ;
214+ }
215+ }
216+ }
217+ #endif
152218 if (m == NULL ) {
153219 sprintf (namebuf , "no module named %.200s" , name );
154220 err_setstr (ImportError , namebuf );
@@ -338,3 +404,64 @@ init_builtin(name)
338404 }
339405 return 0 ;
340406}
407+
408+ #ifdef USE_DL
409+
410+ /* A function to find a filename for the currently executing binary.
411+ Because this is not directly available, we have to search for argv[0]
412+ along $PATH. But note that if argv[0] contains a slash anywhere,
413+ sh(1) doesn't search $PATH -- so neither do we! */
414+
415+ /* XXX This should be moved to a more system-specific file */
416+
417+ #include <sys/types.h>
418+ #include <sys/stat.h> /* For stat */
419+
420+ extern char * getenv ();
421+
422+ extern char * argv0 ; /* In config.c */
423+
424+ /* Default path from sh(1) in Irix 4.0.1 */
425+ #define DEF_PATH ":/usr/sbin:/usr/bsd:/bin:/usr/bin:/usr/bin/X11"
426+
427+ static char *
428+ getbinaryname ()
429+ {
430+ char * p , * q ;
431+ char * path ;
432+ static char buf [258 ];
433+ int i ;
434+ struct stat st ;
435+
436+ if (strchr (argv0 , '/' ) != NULL ) {
437+ D (fprintf (stderr , "binary includes slash: %s\n" , argv0 ));
438+ return argv0 ;
439+ }
440+ path = getenv ("PATH" );
441+ if (path == NULL )
442+ path = DEF_PATH ;
443+ p = q = path ;
444+ for (;;) {
445+ while (* q && * q != ':' )
446+ q ++ ;
447+ i = q - p ;
448+ strncpy (buf , p , i );
449+ if (q > p && q [-1 ] != '/' )
450+ buf [i ++ ] = '/' ;
451+ strcpy (buf + i , argv0 );
452+ if (stat (buf , & st ) >= 0 ) {
453+ if (S_ISREG (st .st_mode ) &&
454+ (st .st_mode & 0111 )) {
455+ D (fprintf (stderr , "found binary: %s\n" , buf ));
456+ return buf ;
457+ }
458+ }
459+ if (!* q )
460+ break ;
461+ p = ++ q ;
462+ }
463+ D (fprintf (stderr , "can't find binary: %s\n" , argv0 ));
464+ return argv0 ;
465+ }
466+
467+ #endif
0 commit comments