From 320c9bd55fea8db89a6fde64ca74c5848fd7bb27 Mon Sep 17 00:00:00 2001 From: rocky Date: Sat, 23 Apr 2005 01:16:19 +0000 Subject: [PATCH] Patch from Burkhard Plaum: 1. In the function is_cdrom_linux(...) in the file lib/driver/gnu_linux.c, the CDROMREADTOCHDR ioctl gets called, which fails when the drive is empty. The CDROM_GET_CAPABILITY ioctl always succeeds for CDrom drives and fails for hard disks etc. 2. For some reason, at least my (GNU/Linux 2.6.10) Kernel fails to open empty drives, when only O_RDONLY is used. Changing the open flag to O_RDONLY|O_NONBLOCK, the call succeeds also for emtpy drives. By the way, the cdrom header file in the kernel says explicitely, that O_RDONLY|O_NONBLOCK should used whenever a cdrom is touched. rocky: also made a change to eject to continue even if we can't get the drive status -- which we can't with an empty CD-ROM drive. --- lib/driver/_cdio_generic.c | 8 ++++---- lib/driver/generic.h | 4 ++-- lib/driver/gnu_linux.c | 15 +++++++-------- lib/driver/osx.c | 6 +++--- lib/driver/solaris.c | 6 +++--- 5 files changed, 19 insertions(+), 20 deletions(-) diff --git a/lib/driver/_cdio_generic.c b/lib/driver/_cdio_generic.c index f9ddfb5e..d58bc4fd 100644 --- a/lib/driver/_cdio_generic.c +++ b/lib/driver/_cdio_generic.c @@ -1,5 +1,5 @@ /* - $Id: _cdio_generic.c,v 1.18 2005/03/01 00:40:39 rocky Exp $ + $Id: _cdio_generic.c,v 1.19 2005/04/23 01:16:19 rocky Exp $ Copyright (C) 2004, 2005 Rocky Bernstein @@ -25,7 +25,7 @@ # include "config.h" #endif -static const char _rcsid[] = "$Id: _cdio_generic.c,v 1.18 2005/03/01 00:40:39 rocky Exp $"; +static const char _rcsid[] = "$Id: _cdio_generic.c,v 1.19 2005/04/23 01:16:19 rocky Exp $"; #include #include @@ -105,7 +105,7 @@ cdio_generic_free (void *p_user_data) Initialize CD device. */ bool -cdio_generic_init (void *user_data) +cdio_generic_init (void *user_data, int open_flags) { generic_img_private_t *p_env = user_data; if (p_env->init) { @@ -113,7 +113,7 @@ cdio_generic_init (void *user_data) return false; } - p_env->fd = open (p_env->source_name, O_RDONLY, 0); + p_env->fd = open (p_env->source_name, open_flags, 0); if (p_env->fd < 0) { diff --git a/lib/driver/generic.h b/lib/driver/generic.h index 2cb56dbf..85e28ccb 100644 --- a/lib/driver/generic.h +++ b/lib/driver/generic.h @@ -1,5 +1,5 @@ /* - $Id: generic.h,v 1.13 2005/03/01 00:40:39 rocky Exp $ + $Id: generic.h,v 1.14 2005/04/23 01:16:19 rocky Exp $ Copyright (C) 2004, 2005 Rocky Bernstein @@ -101,7 +101,7 @@ extern "C" { /*! Initialize CD device. */ - bool cdio_generic_init (void *p_env); + bool cdio_generic_init (void *p_env, int open_mode); /*! Reads into buf the next size bytes. diff --git a/lib/driver/gnu_linux.c b/lib/driver/gnu_linux.c index e53e3bc2..4ffb82be 100644 --- a/lib/driver/gnu_linux.c +++ b/lib/driver/gnu_linux.c @@ -1,5 +1,5 @@ /* - $Id: gnu_linux.c,v 1.12 2005/03/29 12:00:23 rocky Exp $ + $Id: gnu_linux.c,v 1.13 2005/04/23 01:16:19 rocky Exp $ Copyright (C) 2001 Herbert Valerio Riedel Copyright (C) 2002, 2003, 2004, 2005 Rocky Bernstein @@ -27,7 +27,7 @@ # include "config.h" #endif -static const char _rcsid[] = "$Id: gnu_linux.c,v 1.12 2005/03/29 12:00:23 rocky Exp $"; +static const char _rcsid[] = "$Id: gnu_linux.c,v 1.13 2005/04/23 01:16:19 rocky Exp $"; #include @@ -610,6 +610,9 @@ eject_media_linux (void *p_user_data) { ret = DRIVER_OP_ERROR; } break; + default: + cdio_info ("Unknown state of CD-ROM (%d)\n", status); + /* Fall through */ case CDS_DISC_OK: if((ret = ioctl(p_env->gen.fd, CDROMEJECT)) != 0) { int eject_error = errno; @@ -624,9 +627,6 @@ eject_media_linux (void *p_user_data) { /* force kernel to reread partition table when new disc inserted */ ret = ioctl(p_env->gen.fd, BLKRRPART); break; - default: - cdio_warn ("Unknown CD-ROM (%d)\n", status); - ret = DRIVER_OP_ERROR; } } else { cdio_warn ("CDROM_DRIVE_STATUS failed: %s\n", strerror(errno)); @@ -724,7 +724,6 @@ is_cdrom_linux(const char *drive, char *mnttype) { bool is_cd=false; int cdfd; - struct cdrom_tochdr tochdr; /* If it doesn't exist, return -1 */ if ( !cdio_is_device_quiet_generic(drive) ) { @@ -734,7 +733,7 @@ is_cdrom_linux(const char *drive, char *mnttype) /* If it does exist, verify that it's an available CD-ROM */ cdfd = open(drive, (O_RDONLY|O_NONBLOCK), 0); if ( cdfd >= 0 ) { - if ( ioctl(cdfd, CDROMREADTOCHDR, &tochdr) != -1 ) { + if ( ioctl(cdfd, CDROM_GET_CAPABILITY, 0) != -1 ) { is_cd = true; } close(cdfd); @@ -1499,7 +1498,7 @@ cdio_open_am_linux (const char *psz_orig_source, const char *access_mode) ret->driver_id = DRIVER_LINUX; - if (cdio_generic_init(_data)) { + if (cdio_generic_init(_data, O_RDONLY|O_NONBLOCK)) { return ret; } else { cdio_generic_free (_data); diff --git a/lib/driver/osx.c b/lib/driver/osx.c index d5e516df..7155942d 100644 --- a/lib/driver/osx.c +++ b/lib/driver/osx.c @@ -1,5 +1,5 @@ /* - $Id: osx.c,v 1.2 2005/03/13 04:42:38 rocky Exp $ + $Id: osx.c,v 1.3 2005/04/23 01:16:19 rocky Exp $ Copyright (C) 2003, 2004, 2005 Rocky Bernstein from vcdimager code: @@ -34,7 +34,7 @@ #include "config.h" #endif -static const char _rcsid[] = "$Id: osx.c,v 1.2 2005/03/13 04:42:38 rocky Exp $"; +static const char _rcsid[] = "$Id: osx.c,v 1.3 2005/04/23 01:16:19 rocky Exp $"; #include #include @@ -1821,7 +1821,7 @@ cdio_open_osx (const char *psz_orig_source) ret->driver_id = DRIVER_OSX; - if (cdio_generic_init(_data) && init_osx(_data)) + if (cdio_generic_init(_data, O_RDONLY) && init_osx(_data)) return ret; else { cdio_generic_free (_data); diff --git a/lib/driver/solaris.c b/lib/driver/solaris.c index e38b8198..d4f500b9 100644 --- a/lib/driver/solaris.c +++ b/lib/driver/solaris.c @@ -1,5 +1,5 @@ /* - $Id: solaris.c,v 1.9 2005/03/19 18:50:46 rocky Exp $ + $Id: solaris.c,v 1.10 2005/04/23 01:16:19 rocky Exp $ Copyright (C) 2001 Herbert Valerio Riedel Copyright (C) 2002, 2003, 2004, 2005 Rocky Bernstein @@ -38,7 +38,7 @@ #ifdef HAVE_SOLARIS_CDROM -static const char _rcsid[] = "$Id: solaris.c,v 1.9 2005/03/19 18:50:46 rocky Exp $"; +static const char _rcsid[] = "$Id: solaris.c,v 1.10 2005/04/23 01:16:19 rocky Exp $"; #ifdef HAVE_GLOB_H #include @@ -258,7 +258,7 @@ static bool init_solaris (_img_private_t *p_env) { - if (!cdio_generic_init(p_env)) return false; + if (!cdio_generic_init(p_env, O_RDONLY)) return false; p_env->access_mode = _AM_SUN_CTRL_SCSI;