diff options
Diffstat (limited to 'libmpdvdkit2/ioctl.c')
-rw-r--r-- | libmpdvdkit2/ioctl.c | 73 |
1 files changed, 43 insertions, 30 deletions
diff --git a/libmpdvdkit2/ioctl.c b/libmpdvdkit2/ioctl.c index f5f90c44dc..119a7afc2a 100644 --- a/libmpdvdkit2/ioctl.c +++ b/libmpdvdkit2/ioctl.c @@ -2,9 +2,6 @@ * ioctl.c: DVD ioctl replacement function ***************************************************************************** * Copyright (C) 1999-2001 VideoLAN - * - * Modified for use with MPlayer, changes contained in libdvdcss_changes.diff. - * detailed CVS changelog at http://www.mplayerhq.hu/cgi-bin/cvsweb.cgi/main/ * $Id$ * * Authors: Markus Kuespert <ltlBeBoy@beosmail.com> @@ -1912,44 +1909,60 @@ static void SolarisInitUSCSI( struct uscsi_cmd *p_sc, int i_type ) * for execution ***************************************************************************** * When available, this function uses the function smedia_uscsi_cmd() - * from solaris' libsmedia library (solaris 9 or newer) to execute the + * from Solaris' libsmedia library (Solaris 9 or newer) to execute the * USCSI command. smedia_uscsi_cmd() allows USCSI commands for - * non-root users on removable media devices on solaris 9; sending the + * non-root users on removable media devices on Solaris 9; sending the * USCSI command directly to the device using the USCSICMD ioctl fails - * with an EPERM error on solaris 9. + * with an EPERM error on Solaris 9. * * The code will fall back to the USCSICMD ioctl method, when * libsmedia.so is not available or does not export the - * smedia_uscsi_cmd() function (on solaris releases upto and including - * solaris 8). Fortunatelly, on these old releases non-root users are + * smedia_uscsi_cmd() function (on Solaris releases upto and including + * Solaris 8). Fortunatelly, on these old releases non-root users are * allowed to perform USCSICMD ioctls on removable media devices. *****************************************************************************/ -static int SolarisSendUSCSI( int i_fd, struct uscsi_cmd *p_sc ) { - void *sm_hdl; - static int initialized; - static void* (*sm_get_handle)(int32_t); - static int (*sm_release_handle)(void*); - static int (*sm_uscsi_cmd)(void*, struct uscsi_cmd *); - - if (!initialized) +static int SolarisSendUSCSI( int i_fd, struct uscsi_cmd *p_sc ) +{ + void *p_handle; + + /* We use static variables to keep track of the libsmedia symbols, which + * is harmless even in a multithreaded program because the library and + * its symbols will always be mapped at the same address. */ + static int b_tried = 0; + static int b_have_sm = 0; + static void * (*p_get_handle) ( int32_t ); + static int (*p_uscsi_cmd) ( void *, struct uscsi_cmd * ); + static int (*p_release_handle) ( void * ); + + if( !b_tried ) { - void *smedia_lib; - - smedia_lib = dlopen("libsmedia.so", RTLD_NOW); - if (smedia_lib) { - sm_get_handle = dlsym(smedia_lib, "smedia_get_handle"); - sm_release_handle = dlsym(smedia_lib, "smedia_release_handle"); - sm_uscsi_cmd = dlsym(smedia_lib, "smedia_uscsi_cmd"); - } - initialized = 1; + void *p_lib; + + p_lib = dlopen( "libsmedia.so", RTLD_NOW ); + if( p_lib ) + { + p_get_handle = dlsym( p_lib, "smedia_get_handle" ); + p_uscsi_cmd = dlsym( p_lib, "smedia_uscsi_cmd" ); + p_release_handle = dlsym( p_lib, "smedia_release_handle" ); + + if( p_get_handle && p_uscsi_cmd && p_release_handle ) + { + b_have_sm = 1; + } + else + { + dlclose( p_lib ); + } + } + + b_tried = 1; } - if (sm_get_handle && sm_uscsi_cmd && sm_release_handle - && (sm_hdl = sm_get_handle(i_fd))) + if( b_have_sm && (p_handle = p_get_handle(i_fd)) ) { - int i_ret = sm_uscsi_cmd(sm_hdl, p_sc); - sm_release_handle(sm_hdl); - return i_ret; + int i_ret = p_uscsi_cmd( p_handle, p_sc ); + p_release_handle( p_handle ); + return i_ret; } return ioctl( i_fd, USCSICMD, p_sc ); |