diff options
author | Marcus Meissner <marcus@jet.franken.de> | 2022-11-05 09:43:06 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-11-05 09:43:06 +0100 |
commit | 3067c978af62f34cce4b366f4723c137227b9059 (patch) | |
tree | 3a34666844a216cb029dcb0d661e52aa8949d2fb /libgphoto2 | |
parent | 48136a68094301fe465684abc00dc2bdffa94b4a (diff) | |
download | libgphoto2-3067c978af62f34cce4b366f4723c137227b9059.tar.gz |
Wrap unsafe libltdl calls with locking (#848)
* Wrap unsafe libltdl calls with locking
https://github.com/gphoto/libgphoto2/issues/166
* 848: do not install internal header gphoto2-port-mutex.h
* 848: wrap symbol declarations in #ifdef _GPHOTO2_INTERNAL_CODE
* 848: Use proper include guard macro
* 848: Encapsulate the lock/unlock code inside functions
This hides the pthread usage as an implementation detail inside the
gpi_libltdl_lock() and gpi_libltdl_unlock() functions.
* 848: Rename from *-mutex.[ch] to *-locking.[ch]
The *-lock.[ch] name is implementation neutral.
* 848: update libgphoto2_port version number
* 848: internal headers do not require __cplusplus checks
* 848: add copyright comment at the beginning of *.[ch]
* 848: add an unlocked variant of gp_abilities_list_load_dir to avoid lots of unlock/lock codes
* 848: remove unnecessary whitespace addition
Co-authored-by: kadler15 <spurfan15@gmail.com>
Co-authored-by: Hans Ulrich Niedermann <hun@n-dimensional.de>
Diffstat (limited to 'libgphoto2')
-rw-r--r-- | libgphoto2/gphoto2-abilities-list.c | 24 | ||||
-rw-r--r-- | libgphoto2/gphoto2-camera.c | 15 |
2 files changed, 33 insertions, 6 deletions
diff --git a/libgphoto2/gphoto2-abilities-list.c b/libgphoto2/gphoto2-abilities-list.c index b4a9725d1..7db617aed 100644 --- a/libgphoto2/gphoto2-abilities-list.c +++ b/libgphoto2/gphoto2-abilities-list.c @@ -36,6 +36,7 @@ #include <gphoto2/gphoto2-result.h> #include <gphoto2/gphoto2-port-log.h> #include <gphoto2/gphoto2-library.h> +#include <gphoto2/gphoto2-port-locking.h> #include "libgphoto2/i18n.h" @@ -185,9 +186,8 @@ foreach_func (const char *filename, lt_ptr data) return ((fd->result == GP_OK)?0:1); } - -int -gp_abilities_list_load_dir (CameraAbilitiesList *list, const char *dir, +static int +unlocked_gp_abilities_list_load_dir (CameraAbilitiesList *list, const char *dir, GPContext *context) { CameraLibraryIdFunc id; @@ -295,7 +295,6 @@ gp_abilities_list_load_dir (CameraAbilitiesList *list, const char *dir, #if !defined(VALGRIND) lt_dlclose (lh); #endif - new_count = gp_abilities_list_count (list); if (new_count < 0) continue; @@ -310,16 +309,29 @@ gp_abilities_list_load_dir (CameraAbilitiesList *list, const char *dir, if (gp_context_cancel (context) == GP_CONTEXT_FEEDBACK_CANCEL) { lt_dlexit (); gp_list_free (flist); - return (GP_ERROR_CANCEL); + return GP_ERROR_CANCEL; } } gp_context_progress_stop (context, p); lt_dlexit (); gp_list_free (flist); - return (GP_OK); + return GP_OK; } +int +gp_abilities_list_load_dir (CameraAbilitiesList *list, const char *dir, + GPContext *context) +{ + int ret; + + gpi_libltdl_lock(); + ret = unlocked_gp_abilities_list_load_dir (list, dir, context); + gpi_libltdl_unlock(); + return ret; +} + + /** * \brief Scans the system for camera drivers. diff --git a/libgphoto2/gphoto2-camera.c b/libgphoto2/gphoto2-camera.c index 91828df46..745d7f988 100644 --- a/libgphoto2/gphoto2-camera.c +++ b/libgphoto2/gphoto2-camera.c @@ -37,6 +37,7 @@ #include <gphoto2/gphoto2-result.h> #include <gphoto2/gphoto2-library.h> #include <gphoto2/gphoto2-port-log.h> +#include <gphoto2/gphoto2-port-locking.h> #include "libgphoto2/i18n.h" @@ -279,8 +280,10 @@ gp_camera_exit (Camera *camera, GPContext *context) if (camera->pc->lh) { #if !defined(VALGRIND) + gpi_libltdl_lock(); lt_dlclose (camera->pc->lh); lt_dlexit (); + gpi_libltdl_unlock(); #endif camera->pc->lh = NULL; } @@ -777,21 +780,29 @@ gp_camera_init (Camera *camera, GPContext *context) /* Load the library. */ GP_LOG_D ("Loading '%s'...", camera->pc->a.library); + gpi_libltdl_lock(); lt_dlinit (); camera->pc->lh = lt_dlopenext (camera->pc->a.library); + gpi_libltdl_unlock(); if (!camera->pc->lh) { + gpi_libltdl_lock(); gp_context_error (context, _("Could not load required " "camera driver '%s' (%s)."), camera->pc->a.library, lt_dlerror ()); lt_dlexit (); + gpi_libltdl_unlock(); return (GP_ERROR_LIBRARY); } /* Initialize the camera */ + gpi_libltdl_lock(); init_func = lt_dlsym (camera->pc->lh, "camera_init"); + gpi_libltdl_unlock(); if (!init_func) { + gpi_libltdl_lock(); lt_dlclose (camera->pc->lh); lt_dlexit (); + gpi_libltdl_unlock(); camera->pc->lh = NULL; gp_context_error (context, _("Camera driver '%s' is " "missing the 'camera_init' function."), @@ -802,8 +813,10 @@ gp_camera_init (Camera *camera, GPContext *context) if (strcasecmp (camera->pc->a.model, "Directory Browse")) { result = gp_port_open (camera->port); if (result < 0) { + gpi_libltdl_lock(); lt_dlclose (camera->pc->lh); lt_dlexit (); + gpi_libltdl_unlock(); camera->pc->lh = NULL; return (result); } @@ -812,8 +825,10 @@ gp_camera_init (Camera *camera, GPContext *context) result = init_func (camera, context); if (result < 0) { gp_port_close (camera->port); + gpi_libltdl_lock(); lt_dlclose (camera->pc->lh); lt_dlexit (); + gpi_libltdl_unlock(); camera->pc->lh = NULL; memset (camera->functions, 0, sizeof (CameraFunctions)); return (result); |