From: Ralf Wildenhues Date: Thu, 31 Aug 2006 05:34:01 +0000 (+0000) Subject: Avoid mixing functions and data pointers in callback functions. X-Git-Tag: release-2-1b~258 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=833a91c5bf049c240a65559c88ecd512d3c41f23;p=thirdparty%2Flibtool.git Avoid mixing functions and data pointers in callback functions. * libltdl/ltdl.c (file_worker_func): New type. (lt_dlforeachfile): Instead of passing a function pointer as a data pointer, pass a pointer to a file_worker_func pointer. (foreach_callback_func): Adjust. * tests/mdemo/main.c: Assume C89. Exercise lt_dlforeachfile. (callback, try_iterate, my_dirname): New functions. * tests/mdemo-exec.test: Check for its output. --- diff --git a/ChangeLog b/ChangeLog index dd9138b59..815d43e79 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2006-08-31 Ralf Wildenhues + + Avoid mixing functions and data pointers in callback functions. + + * libltdl/ltdl.c (file_worker_func): New type. + (lt_dlforeachfile): Instead of passing a function pointer as a + data pointer, pass a pointer to a file_worker_func pointer. + (foreach_callback_func): Adjust. + * tests/mdemo/main.c: Assume C89. Exercise lt_dlforeachfile. + (callback, try_iterate, my_dirname): New functions. + * tests/mdemo-exec.test: Check for its output. + 2006-08-30 Ralf Wildenhues * libltdl/libltdl/lt__private.h (__attribute__, LT__UNUSED): diff --git a/libltdl/ltdl.c b/libltdl/ltdl.c index 92b6a0099..0e57473b1 100644 --- a/libltdl/ltdl.c +++ b/libltdl/ltdl.c @@ -86,6 +86,8 @@ static const char sys_dlsearch_path[] = LT_DLSEARCH_PATH; /* The type of a function used at each iteration of foreach_dirinpath(). */ typedef int foreach_callback_func (char *filename, void *data1, void *data2); +/* foreachfile_callback itself calls a function of this type: */ +typedef int file_worker_func (const char *filename, void *data); static int foreach_dirinpath (const char *search_path, const char *base_name, @@ -1604,8 +1606,7 @@ list_files_by_dir (const char *dirnam, char **pargz, size_t *pargz_len) static int foreachfile_callback (char *dirname, void *data1, void *data2) { - int (*func) (const char *filename, void *data) - = (int (*) (const char *filename, void *data)) data1; + file_worker_func *func = *(file_worker_func **) data1; int is_done = 0; char *argz = 0; @@ -1642,37 +1643,38 @@ lt_dlforeachfile (const char *search_path, void *data) { int is_done = 0; + file_worker_func **fpptr = &func; if (search_path) { /* If a specific path was passed, search only the directories listed in it. */ is_done = foreach_dirinpath (search_path, 0, - foreachfile_callback, func, data); + foreachfile_callback, fpptr, data); } else { /* Otherwise search the default paths. */ is_done = foreach_dirinpath (user_search_path, 0, - foreachfile_callback, func, data); + foreachfile_callback, fpptr, data); if (!is_done) { is_done = foreach_dirinpath (getenv(LTDL_SEARCHPATH_VAR), 0, - foreachfile_callback, func, data); + foreachfile_callback, fpptr, data); } #if defined(LT_MODULE_PATH_VAR) if (!is_done) { is_done = foreach_dirinpath (getenv(LT_MODULE_PATH_VAR), 0, - foreachfile_callback, func, data); + foreachfile_callback, fpptr, data); } #endif #if defined(LT_DLSEARCH_PATH) if (!is_done && sys_dlsearch_path) { is_done = foreach_dirinpath (sys_dlsearch_path, 0, - foreachfile_callback, func, data); + foreachfile_callback, fpptr, data); } #endif } diff --git a/tests/mdemo-exec.test b/tests/mdemo-exec.test index b9f00bf19..3101d6833 100755 --- a/tests/mdemo-exec.test +++ b/tests/mdemo-exec.test @@ -27,7 +27,9 @@ func_require "mdemo-make" "tests/mdemo/mdemo$EXEEXT" func_rmprefixdir func_exec_init "uninstalled" -func_exec "tests/mdemo/mdemo_static tests/mdemo/foo1.la tests/mdemo/libfoo2.la" -func_exec "tests/mdemo/mdemo tests/mdemo/foo1.la tests/mdemo/libfoo2.la" +func_exec "tests/mdemo/mdemo_static tests/mdemo/foo1.la tests/mdemo/libfoo2.la" \ + "try_iterate: .*libfoo2" +func_exec "tests/mdemo/mdemo tests/mdemo/foo1.la tests/mdemo/libfoo2.la" \ + "try_iterate: .*libfoo2" exit $exec_status diff --git a/tests/mdemo/main.c b/tests/mdemo/main.c index 0e6cd25b0..4b38f7ff0 100644 --- a/tests/mdemo/main.c +++ b/tests/mdemo/main.c @@ -1,5 +1,5 @@ /* main.c -- mdemo test program - Copyright (C) 1998-2000 Free Software Foundation, Inc. + Copyright (C) 1998-2000, 2006 Free Software Foundation, Inc. Originally by Thomas Tanner This file is part of GNU Libtool. @@ -21,10 +21,11 @@ USA. */ #include "foo.h" #include "ltdl.h" #include +#include int test_dl (filename) - char *filename; +test_dl (char *filename) { lt_dlhandle handle; const lt_dlinfo *info; @@ -132,7 +133,7 @@ test_dlself () return 1; } - pmyfunc = (int(*)())lt_dlsym(handle, "myfunc"); + pmyfunc = (int(*)())lt_dlsym(handle, "myfunc"); if (pmyfunc) { int value = (*pmyfunc) (); @@ -163,10 +164,38 @@ test_dlself () return ret; } +static int +callback (const char *filename, void *data) +{ + printf ("%s: %s\n", (char *)data, filename); + return 0; +} + +static int +try_iterate (const char *search_path) +{ + char *s = "try_iterate"; + return lt_dlforeachfile (search_path, callback, s); +} + +/* cheap dirname clone. We require a '/' separator, nonempty and large + enough input, not ending with '/', and we will overwrite the input. */ +static char * +my_dirname (char *path) +{ + char *p = strrchr (path, '/'); + if (p) + *p = '\0'; + else + { + path[0] = '.'; + path[1] = '\0'; + } + return path; +} + int -main (argc, argv) - int argc; - char **argv; +main (int argc, char **argv) { int i; int ret = 0; @@ -190,6 +219,14 @@ main (argc, argv) if (test_dlself()) ret = 1; + for (i = 1; i < argc; i++) + if (argv[i][0] != '\0') + { + my_dirname (argv[i]); + if (try_iterate (argv[i])) + ret = 1; + } + lt_dlexit(); return ret; }