diff --git a/lib/driver/osx.c b/lib/driver/osx.c index 5c9a63d7..cbb96275 100644 --- a/lib/driver/osx.c +++ b/lib/driver/osx.c @@ -1,5 +1,5 @@ /* - $Id: osx.c,v 1.13 2008/08/30 06:55:50 rocky Exp $ + $Id: osx.c,v 1.14 2008/10/17 11:58:52 rocky Exp $ Copyright (C) 2003, 2004, 2005, 2006, 2008 Rocky Bernstein from vcdimager code: @@ -33,7 +33,7 @@ #include "config.h" #endif -static const char _rcsid[] = "$Id: osx.c,v 1.13 2008/08/30 06:55:50 rocky Exp $"; +static const char _rcsid[] = "$Id: osx.c,v 1.14 2008/10/17 11:58:52 rocky Exp $"; #include #include @@ -246,43 +246,38 @@ get_scsi(_img_private_t *p_env) static bool init_osx(_img_private_t *p_env) { - mach_port_t port; char *psz_devname; kern_return_t ret; io_iterator_t iterator; - - p_env->gen.fd = open( p_env->gen.source_name, O_RDONLY | O_NONBLOCK ); + + /* Only open if not already opened. Otherwise, too many descriptors + are holding the device busy. */ + if (-1 == p_env->gen.fd) + p_env->gen.fd = open( p_env->gen.source_name, O_RDONLY | O_NONBLOCK ); + if (-1 == p_env->gen.fd) { cdio_warn("Failed to open %s: %s", p_env->gen.source_name, strerror(errno)); return false; } - /* get the device name */ + /* Get the device name. */ psz_devname = strrchr( p_env->gen.source_name, '/'); if( NULL != psz_devname ) ++psz_devname; else psz_devname = p_env->gen.source_name; - /* unraw the device name */ + /* Unraw the device name. */ if( *psz_devname == 'r' ) ++psz_devname; - /* get port for IOKit communication */ - ret = IOMasterPort( MACH_PORT_NULL, &port ); - - if( ret != KERN_SUCCESS ) - { - cdio_warn( "IOMasterPort: 0x%08x", ret ); - return false; - } - - ret = IOServiceGetMatchingServices( port, - IOBSDNameMatching(port, 0, psz_devname), + ret = IOServiceGetMatchingServices( kIOMasterPortDefault, + IOBSDNameMatching(kIOMasterPortDefault, + 0, psz_devname), &iterator ); - /* get service iterator for the device */ + /* Get service iterator for the device. */ if( ret != KERN_SUCCESS ) { cdio_warn( "IOServiceGetMatchingServices: 0x%08x", ret ); @@ -292,7 +287,7 @@ init_osx(_img_private_t *p_env) { /* first service */ p_env->MediaClass_service = IOIteratorNext( iterator ); IOObjectRelease( iterator ); - + /* search for kIOCDMediaClass or kIOCDVDMediaClass */ while( p_env->MediaClass_service && (!IOObjectConformsTo(p_env->MediaClass_service, kIOCDMediaClass)) && @@ -874,10 +869,13 @@ static void _free_osx (void *p_user_data) { _img_private_t *p_env = p_user_data; if (NULL == p_env) return; + if (p_env->gen.fd != -1) + close(p_env->gen.fd); + if (p_env->MediaClass_service) + IOObjectRelease( p_env->MediaClass_service ); cdio_generic_free(p_env); if (NULL != p_env->pp_lba) free((void *) p_env->pp_lba); if (NULL != p_env->pTOC) free((void *) p_env->pTOC); - IOObjectRelease( p_env->MediaClass_service ); if (p_env->scsi_task) (*p_env->scsi_task)->Release(p_env->scsi_task); @@ -895,8 +893,6 @@ _free_osx (void *p_user_data) { if (p_env->plugin) IODestroyPlugInInterface(p_env->plugin); - IOObjectRelease(p_env->MediaClass_service); - } /*! @@ -1173,10 +1169,12 @@ read_toc_osx (void *p_user_data) CFDataGetBytes( data, range, (u_char *) p_env->pTOC ); } else { cdio_warn( "Trouble allocating CDROM TOC" ); + CFRelease( propertiesDict ); return false; } } else { cdio_warn( "Trouble reading TOC" ); + CFRelease( propertiesDict ); return false; } @@ -1391,16 +1389,19 @@ static void media_eject_callback(DADiskRef disk, DADissenterRef dissenter, void if ( dissenter ) { CFStringRef status = DADissenterGetStatusString(dissenter); - size_t cstr_size = CFStringGetLength(status); - char *cstr = malloc(cstr_size); - if ( CFStringGetCString( status, + if (status) + { + size_t cstr_size = CFStringGetLength(status); + char *cstr = malloc(cstr_size); + if ( CFStringGetCString( status, cstr, cstr_size, kCFStringEncodingASCII ) ) - CFRelease( status ); + CFRelease( status ); - cdio_warn("%s", cstr); + cdio_warn("%s", cstr); - free(cstr); + free(cstr); + } } dacontext->result = (dissenter ? DRIVER_OP_ERROR : DRIVER_OP_SUCCESS); @@ -1441,6 +1442,10 @@ _eject_media_osx (void *user_data) { return DRIVER_OP_ERROR; } + if (p_env->gen.fd != -1) + close(p_env->gen.fd); + p_env->gen.fd = -1; + dacontext.result = DRIVER_OP_UNINIT; dacontext.completed = FALSE; dacontext.runloop = CFRunLoopGetCurrent(); @@ -1715,7 +1720,7 @@ cdio_get_devices_osx(void) return( NULL ); } - classes_to_match = IOServiceMatching( kIOCDMediaClass ); + classes_to_match = IOServiceMatching( kIOMediaClass ); if( classes_to_match == NULL ) { return( NULL ); @@ -1786,18 +1791,11 @@ cdio_get_default_device_osx(void) return NULL; #else io_object_t next_media; - mach_port_t master_port; kern_return_t kern_result; io_iterator_t media_iterator; CFMutableDictionaryRef classes_to_match; - kern_result = IOMasterPort( MACH_PORT_NULL, &master_port ); - if( kern_result != KERN_SUCCESS ) - { - return( NULL ); - } - - classes_to_match = IOServiceMatching( kIOCDMediaClass ); + classes_to_match = IOServiceMatching( kIOMediaClass ); if( classes_to_match == NULL ) { return( NULL ); @@ -1806,7 +1804,7 @@ cdio_get_default_device_osx(void) CFDictionarySetValue( classes_to_match, CFSTR(kIOMediaEjectableKey), kCFBooleanTrue ); - kern_result = IOServiceGetMatchingServices( master_port, + kern_result = IOServiceGetMatchingServices( kIOMasterPortDefault, classes_to_match, &media_iterator ); if( kern_result != KERN_SUCCESS ) @@ -1881,7 +1879,6 @@ cdio_open_am_osx (const char *psz_source_name, const char *psz_access_mode) CdIo_t * cdio_open_osx (const char *psz_orig_source) { - #ifdef HAVE_DARWIN_CDROM CdIo_t *ret; _img_private_t *_data; @@ -1958,8 +1955,7 @@ cdio_open_osx (const char *psz_orig_source) return NULL; } ret->driver_id = DRIVER_OSX; - - if (cdio_generic_init(_data, O_RDONLY) && init_osx(_data)) + if (cdio_generic_init(_data, O_RDONLY | O_NONBLOCK) && init_osx(_data)) return ret; else { cdio_generic_free (_data);