88 *
99 *
1010 * IDENTIFICATION
11- * $Header: /cvsroot/pgsql/src/backend/utils/fmgr/dfmgr.c,v 1.51 2001/09/16 16:11:11 petere Exp $
11+ * $Header: /cvsroot/pgsql/src/backend/utils/fmgr/dfmgr.c,v 1.52 2001/10/04 19:13:55 tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
2424
2525
2626/*
27- * List of dynamically loaded files.
27+ * List of dynamically loaded files (kept in malloc'd memory) .
2828 */
2929
3030typedef struct df_files
@@ -71,25 +71,25 @@ load_external_function(char *filename, char *funcname,
7171char * fullname ;
7272
7373fullname = expand_dynamic_library_name (filename );
74- if (fullname )
75- filename = fullname ;
74+ if (!fullname )
75+ fullname = pstrdup (filename );
76+ /* at this point fullname is always freshly palloc'd */
7677
7778/*
7879 * Scan the list of loaded FILES to see if the file has been loaded.
7980 */
8081for (file_scanner = file_list ;
8182file_scanner != (DynamicFileList * )NULL &&
82- strcmp (filename ,file_scanner -> filename )!= 0 ;
83+ strcmp (fullname ,file_scanner -> filename )!= 0 ;
8384file_scanner = file_scanner -> next )
8485;
8586if (file_scanner == (DynamicFileList * )NULL )
8687{
87-
8888/*
8989 * Check for same files - different paths (ie, symlink or link)
9090 */
91- if (stat (filename ,& stat_buf )== -1 )
92- elog (ERROR ,"stat failed on file '%s': %m" ,filename );
91+ if (stat (fullname ,& stat_buf )== -1 )
92+ elog (ERROR ,"stat failed on file '%s': %m" ,fullname );
9393
9494for (file_scanner = file_list ;
9595file_scanner != (DynamicFileList * )NULL &&
@@ -100,27 +100,26 @@ load_external_function(char *filename, char *funcname,
100100
101101if (file_scanner == (DynamicFileList * )NULL )
102102{
103-
104103/*
105104 * File not loaded yet.
106105 */
107106file_scanner = (DynamicFileList * )
108- malloc (sizeof (DynamicFileList )+ strlen (filename ));
107+ malloc (sizeof (DynamicFileList )+ strlen (fullname ));
109108if (file_scanner == NULL )
110109elog (ERROR ,"Out of memory in load_external_function" );
111110
112111MemSet ((char * )file_scanner ,0 ,sizeof (DynamicFileList ));
113- strcpy (file_scanner -> filename ,filename );
112+ strcpy (file_scanner -> filename ,fullname );
114113file_scanner -> device = stat_buf .st_dev ;
115114file_scanner -> inode = stat_buf .st_ino ;
116115file_scanner -> next = (DynamicFileList * )NULL ;
117116
118- file_scanner -> handle = pg_dlopen (filename );
117+ file_scanner -> handle = pg_dlopen (fullname );
119118if (file_scanner -> handle == (void * )NULL )
120119{
121120load_error = (char * )pg_dlerror ();
122121free ((char * )file_scanner );
123- elog (ERROR ,"Load of file %s failed: %s" ,filename ,load_error );
122+ elog (ERROR ,"Load of file %s failed: %s" ,fullname ,load_error );
124123}
125124
126125/* OK to link it into list */
@@ -135,13 +134,17 @@ load_external_function(char *filename, char *funcname,
135134 * If funcname is NULL, we only wanted to load the file.
136135 */
137136if (funcname == (char * )NULL )
137+ {
138+ pfree (fullname );
138139return (PGFunction )NULL ;
140+ }
139141
140142retval = pg_dlsym (file_scanner -> handle ,funcname );
141143
142144if (retval == (PGFunction )NULL && signalNotFound )
143- elog (ERROR ,"Can't find function %s in file %s" ,funcname ,filename );
145+ elog (ERROR ,"Can't find function %s in file %s" ,funcname ,fullname );
144146
147+ pfree (fullname );
145148return retval ;
146149}
147150
@@ -159,16 +162,17 @@ load_file(char *filename)
159162char * fullname ;
160163
161164fullname = expand_dynamic_library_name (filename );
162- if (fullname )
163- filename = fullname ;
165+ if (!fullname )
166+ fullname = pstrdup (filename );
167+ /* at this point fullname is always freshly palloc'd */
164168
165169/*
166170 * We need to do stat() in order to determine whether this is the same
167171 * file as a previously loaded file; it's also handy so as to give a
168172 * good error message if bogus file name given.
169173 */
170- if (stat (filename ,& stat_buf )== -1 )
171- elog (ERROR ,"LOAD: could not open file '%s': %m" ,filename );
174+ if (stat (fullname ,& stat_buf )== -1 )
175+ elog (ERROR ,"LOAD: could not open file '%s': %m" ,fullname );
172176
173177if (file_list != (DynamicFileList * )NULL )
174178{
@@ -197,7 +201,9 @@ load_file(char *filename)
197201}
198202}
199203
200- load_external_function (filename , (char * )NULL , false);
204+ load_external_function (fullname , (char * )NULL , false);
205+
206+ pfree (fullname );
201207}
202208
203209
@@ -235,6 +241,8 @@ file_exists(const char *name)
235241 * find_in_dynamic_libpath below); if that works, return the fully
236242 * expanded file name. If the previous failed, append DLSUFFIX and
237243 * try again. If all fails, return NULL.
244+ *
245+ * A non-NULL result will always be freshly palloc'd.
238246 */
239247static char *
240248expand_dynamic_library_name (const char * name )
@@ -258,6 +266,7 @@ expand_dynamic_library_name(const char *name)
258266full = substitute_libpath_macro (name );
259267if (file_exists (full ))
260268return full ;
269+ pfree (full );
261270}
262271
263272new = palloc (strlen (name )+ strlen (DLSUFFIX )+ 1 );
@@ -274,15 +283,20 @@ expand_dynamic_library_name(const char *name)
274283else
275284{
276285full = substitute_libpath_macro (new );
286+ pfree (new );
277287if (file_exists (full ))
278288return full ;
289+ pfree (full );
279290}
280291
281292return NULL ;
282293}
283294
284295
285-
296+ /*
297+ * Substitute for any macros appearing in the given string.
298+ * Result is always freshly palloc'd.
299+ */
286300static char *
287301substitute_libpath_macro (const char * name )
288302{
@@ -302,7 +316,7 @@ substitute_libpath_macro(const char * name)
302316elog (ERROR ,"invalid macro name in dynamic library path" );
303317
304318if (name [macroname_len ]== '\0' )
305- return replacement ;
319+ return pstrdup ( replacement ) ;
306320else
307321{
308322char * new ;
@@ -319,15 +333,14 @@ substitute_libpath_macro(const char * name)
319333
320334/*
321335 * Search for a file called 'basename' in the colon-separated search
322- * path 'path'. If the file is found, the full file name is returned
323- * in palloced memory. The the file is not found, return NULL.
336+ * path Dynamic_library_path. If the file is found, the full file name
337+ * is returned in freshly palloc'd memory. If the file is not found,
338+ * return NULL.
324339 */
325340static char *
326341find_in_dynamic_libpath (const char * basename )
327342{
328343const char * p ;
329- char * full ;
330- size_t len ;
331344size_t baselen ;
332345
333346AssertArg (basename != NULL );
@@ -340,9 +353,12 @@ find_in_dynamic_libpath(const char * basename)
340353
341354baselen = strlen (basename );
342355
343- do {
356+ for (;;)
357+ {
358+ size_t len ;
344359char * piece ;
345- const char * mangled ;
360+ char * mangled ;
361+ char * full ;
346362
347363len = strcspn (p ,":" );
348364
@@ -354,27 +370,29 @@ find_in_dynamic_libpath(const char * basename)
354370piece [len ]= '\0' ;
355371
356372mangled = substitute_libpath_macro (piece );
373+ pfree (piece );
357374
358375/* only absolute paths */
359376if (mangled [0 ]!= '/' )
360377elog (ERROR ,"dynamic_library_path component is not absolute" );
361378
362379full = palloc (strlen (mangled )+ 1 + baselen + 1 );
363380sprintf (full ,"%s/%s" ,mangled ,basename );
381+ pfree (mangled );
364382
365383if (DebugLvl > 1 )
366384elog (DEBUG ,"find_in_dynamic_libpath: trying %s" ,full );
367385
368386if (file_exists (full ))
369387return full ;
370388
371- pfree (piece );
372389pfree (full );
390+
373391if (p [len ]== '\0' )
374392break ;
375393else
376394p += len + 1 ;
377- }while ( 1 );
395+ }
378396
379397return NULL ;
380398}