diff --git a/include/cdio/cdio.h b/include/cdio/cdio.h index f19322fd..a73e5964 100644 --- a/include/cdio/cdio.h +++ b/include/cdio/cdio.h @@ -1,5 +1,5 @@ /* -*- c -*- - $Id: cdio.h,v 1.6 2003/04/22 12:09:08 rocky Exp $ + $Id: cdio.h,v 1.7 2003/05/16 07:18:27 rocky Exp $ Copyright (C) 2001 Herbert Valerio Riedel Copyright (C) 2003 Rocky Bernstein @@ -103,8 +103,9 @@ extern "C" { /*! Eject media in CD drive if there is a routine to do so. Return 0 if success and 1 for failure, and 2 if no routine. + If the CD is ejected *obj is freed and obj set to NULL. */ - int cdio_eject_media (const CdIo *obj); + int cdio_eject_media (CdIo **obj); /*! Free any resources associated with obj. diff --git a/lib/_cdio_bsdi.c b/lib/_cdio_bsdi.c index 1fa12d52..4486ef2d 100644 --- a/lib/_cdio_bsdi.c +++ b/lib/_cdio_bsdi.c @@ -1,5 +1,5 @@ /* - $Id: _cdio_bsdi.c,v 1.9 2003/04/22 12:09:08 rocky Exp $ + $Id: _cdio_bsdi.c,v 1.10 2003/05/16 07:18:27 rocky Exp $ Copyright (C) 2001 Herbert Valerio Riedel Copyright (C) 2002,2003 Rocky Bernstein @@ -27,7 +27,7 @@ # include "config.h" #endif -static const char _rcsid[] = "$Id: _cdio_bsdi.c,v 1.9 2003/04/22 12:09:08 rocky Exp $"; +static const char _rcsid[] = "$Id: _cdio_bsdi.c,v 1.10 2003/05/16 07:18:27 rocky Exp $"; #include #include @@ -314,6 +314,8 @@ _cdio_eject_media (void *user_data) { int status; int fd; + close(_obj->gen.fd); + _obj->gen.fd = -1; if ((fd = open (_obj->source_name, O_RDONLY|O_NONBLOCK)) > -1) { if((status = ioctl(fd, CDROM_DRIVE_STATUS, (void *) CDSL_CURRENT)) > 0) { switch(status) { @@ -334,7 +336,6 @@ _cdio_eject_media (void *user_data) { ret=1; } close(fd); - cdio_generic_free((void *) _obj); } return 2; } diff --git a/lib/_cdio_freebsd.c b/lib/_cdio_freebsd.c index 3d7c2ce4..edea4fa8 100644 --- a/lib/_cdio_freebsd.c +++ b/lib/_cdio_freebsd.c @@ -1,5 +1,5 @@ /* - $Id: _cdio_freebsd.c,v 1.9 2003/04/22 12:09:08 rocky Exp $ + $Id: _cdio_freebsd.c,v 1.10 2003/05/16 07:18:27 rocky Exp $ Copyright (C) 2003 Rocky Bernstein @@ -26,7 +26,7 @@ # include "config.h" #endif -static const char _rcsid[] = "$Id: _cdio_freebsd.c,v 1.9 2003/04/22 12:09:08 rocky Exp $"; +static const char _rcsid[] = "$Id: _cdio_freebsd.c,v 1.10 2003/05/16 07:18:27 rocky Exp $"; #include #include @@ -361,7 +361,6 @@ _cdio_eject_media (void *user_data) { ret = 0; } close(fd); - _cdio_generic_free((void *) _obj); } return ret; diff --git a/lib/_cdio_linux.c b/lib/_cdio_linux.c index 3e5e9868..61a1f9fa 100644 --- a/lib/_cdio_linux.c +++ b/lib/_cdio_linux.c @@ -1,5 +1,5 @@ /* - $Id: _cdio_linux.c,v 1.11 2003/04/22 12:09:09 rocky Exp $ + $Id: _cdio_linux.c,v 1.12 2003/05/16 07:18:27 rocky Exp $ Copyright (C) 2001 Herbert Valerio Riedel Copyright (C) 2002,2003 Rocky Bernstein @@ -27,7 +27,7 @@ # include "config.h" #endif -static const char _rcsid[] = "$Id: _cdio_linux.c,v 1.11 2003/04/22 12:09:09 rocky Exp $"; +static const char _rcsid[] = "$Id: _cdio_linux.c,v 1.12 2003/05/16 07:18:27 rocky Exp $"; #include @@ -58,6 +58,11 @@ static const char _rcsid[] = "$Id: _cdio_linux.c,v 1.11 2003/04/22 12:09:09 rock #include #include +#include +#include +#include +#include + #include #include #include @@ -515,9 +520,63 @@ _cdio_read_toc (_img_private_t *_obj) return true; } +/* + * Eject using SCSI commands. Return 1 if successful, 0 otherwise. + */ +static int +_cdio_eject_scsi(int fd) +{ + int status; + struct sdata { + int inlen; + int outlen; + char cmd[256]; + } scsi_cmd; + + scsi_cmd.inlen = 0; + scsi_cmd.outlen = 0; + scsi_cmd.cmd[0] = ALLOW_MEDIUM_REMOVAL; + scsi_cmd.cmd[1] = 0; + scsi_cmd.cmd[2] = 0; + scsi_cmd.cmd[3] = 0; + scsi_cmd.cmd[4] = 0; + scsi_cmd.cmd[5] = 0; + status = ioctl(fd, SCSI_IOCTL_SEND_COMMAND, (void *)&scsi_cmd); + if (status != 0) + return 0; + + scsi_cmd.inlen = 0; + scsi_cmd.outlen = 0; + scsi_cmd.cmd[0] = START_STOP; + scsi_cmd.cmd[1] = 0; + scsi_cmd.cmd[2] = 0; + scsi_cmd.cmd[3] = 0; + scsi_cmd.cmd[4] = 1; + scsi_cmd.cmd[5] = 0; + status = ioctl(fd, SCSI_IOCTL_SEND_COMMAND, (void *)&scsi_cmd); + if (status != 0) + return 0; + + scsi_cmd.inlen = 0; + scsi_cmd.outlen = 0; + scsi_cmd.cmd[0] = START_STOP; + scsi_cmd.cmd[1] = 0; + scsi_cmd.cmd[2] = 0; + scsi_cmd.cmd[3] = 0; + scsi_cmd.cmd[4] = 2; + scsi_cmd.cmd[5] = 0; + status = ioctl(fd, SCSI_IOCTL_SEND_COMMAND, (void *)&scsi_cmd); + if (status != 0) + return 0; + + /* force kernel to reread partition table when new disc inserted */ + status = ioctl(fd, BLKRRPART); + return (status == 0); +} + /*! - Eject media in CD drive. If successful, as a side effect we - also free obj. + Eject media in CD drive. + Return 0 if success and 1 for failure, and 2 if no routine. */ static int _cdio_eject_media (void *user_data) { @@ -527,27 +586,38 @@ _cdio_eject_media (void *user_data) { int status; int fd; + close(_obj->gen.fd); + _obj->gen.fd = -1; if ((fd = open (_obj->gen.source_name, O_RDONLY|O_NONBLOCK)) > -1) { if((status = ioctl(fd, CDROM_DRIVE_STATUS, CDSL_CURRENT)) > 0) { switch(status) { case CDS_TRAY_OPEN: if((ret = ioctl(fd, CDROMCLOSETRAY)) != 0) { cdio_error ("ioctl CDROMCLOSETRAY failed: %s\n", strerror(errno)); + ret = 1; } break; case CDS_DISC_OK: if((ret = ioctl(fd, CDROMEJECT)) != 0) { - cdio_error("ioctl CDROMEJECT failed: %s\n", strerror(errno)); + int eject_error = errno; + /* Try ejecting the SCSI way... */ + ret = _cdio_eject_scsi(fd); + if (0 != ret) { + cdio_error("ioctl CDROMEJECT failed: %s\n", strerror(eject_error)); + ret = 1; + } } break; + default: + cdio_error ("Unknown CD-ROM (%d)\n", status); + ret = 1; } - ret=0; } else { cdio_error ("CDROM_DRIVE_STATUS failed: %s\n", strerror(errno)); ret=1; } close(fd); - cdio_generic_free((void *) _obj); + return ret; } return 2; } diff --git a/lib/_cdio_sunos.c b/lib/_cdio_sunos.c index 3759c687..561984f3 100644 --- a/lib/_cdio_sunos.c +++ b/lib/_cdio_sunos.c @@ -1,5 +1,5 @@ /* - $Id: _cdio_sunos.c,v 1.12 2003/04/22 12:09:09 rocky Exp $ + $Id: _cdio_sunos.c,v 1.13 2003/05/16 07:18:27 rocky Exp $ Copyright (C) 2001 Herbert Valerio Riedel Copyright (C) 2002,2003 Rocky Bernstein @@ -35,7 +35,7 @@ #ifdef HAVE_SOLARIS_CDROM -static const char _rcsid[] = "$Id: _cdio_sunos.c,v 1.12 2003/04/22 12:09:09 rocky Exp $"; +static const char _rcsid[] = "$Id: _cdio_sunos.c,v 1.13 2003/05/16 07:18:27 rocky Exp $"; #include #include @@ -473,13 +473,14 @@ _cdio_eject_media (void *user_data) { _img_private_t *_obj = user_data; int ret; + close(_obj->gen.fd); + _obj->gen.fd = -1; if (_obj->gen.fd > -1) { if ((ret = ioctl(_obj->gen.fd, CDROMEJECT)) != 0) { cdio_generic_free((void *) _obj); cdio_error ("CDROMEJECT failed: %s\n", strerror(errno)); return 1; } else { - cdio_generic_free((void *) _obj); return 0; } } diff --git a/lib/cdio.c b/lib/cdio.c index 59f8468a..fb1e1c32 100644 --- a/lib/cdio.c +++ b/lib/cdio.c @@ -1,5 +1,5 @@ /* - $Id: cdio.c,v 1.11 2003/04/22 12:09:09 rocky Exp $ + $Id: cdio.c,v 1.12 2003/05/16 07:18:27 rocky Exp $ Copyright (C) 2003 Rocky Bernstein Copyright (C) 2001 Herbert Valerio Riedel @@ -35,7 +35,7 @@ #include #include "cdio_private.h" -static const char _rcsid[] = "$Id: cdio.c,v 1.11 2003/04/22 12:09:09 rocky Exp $"; +static const char _rcsid[] = "$Id: cdio.c,v 1.12 2003/05/16 07:18:27 rocky Exp $"; const char *track_format2str[5] = @@ -135,15 +135,24 @@ CdIo_driver_t CdIo_all_drivers[MAX_DRIVER+1] = { /*! Eject media in CD drive if there is a routine to do so. Return 0 if success and 1 for failure, and 2 if no routine. + If the CD is ejected *obj is freed and obj set to NULL. */ int -cdio_eject_media (const CdIo *obj) +cdio_eject_media (CdIo **obj) { - cdio_assert (obj != NULL); + + if ((obj == NULL) || (*obj != NULL)) return 1; - if (obj->op.eject_media) { - return obj->op.eject_media (obj->user_data); + if ((*obj)->op.eject_media) { + int ret = (*obj)->op.eject_media ((*obj)->user_data); + if (0 == ret) { + cdio_destroy(*obj); + obj = NULL; + } + return ret; } else { + cdio_destroy(*obj); + obj = NULL; return 2; } } diff --git a/parse/Makefile b/parse/Makefile index a4c98e55..9909be40 100644 --- a/parse/Makefile +++ b/parse/Makefile @@ -23,3 +23,7 @@ cueparser: lex.cue.o cue.tab.o cuelexer: lex.cuelex.o gcc -g lex.cuelex.o -lfl -o cuelexer + +clean: + rm -f lex.cue.c lex.cuelex.c lex.cue.o lex.cuelex.o cue.tab.c \ + cue.tab.o cueparser cuelexer \ No newline at end of file