问题
I'm trying to playback an audio CD from my app by using the cdaudio
library + a USB DVD drive attached to a Raspi 3B. Trying to eject the CD after playback always makes me end up with errno #5. This is my code:
void sound::Eject ()
{
struct disc_status cd_stat;
if (sound::current_sound_source == CD) {
sound::Stop ();
cd_poll (sound::cd_drive_handler, &cd_stat);
if (sound::is_cd_stopped && cd_stat.status_present == 1) {
if ((cd_eject (sound::cd_drive_handler)) < 0) cout << "Ejecting CD failed! Error: " << strerror (errno) << endl;
}
}
}
This is the output I get:
ioctl returned -1
Ejecting CD failed! Error: Input/output error
When trying to eject the CD, I hear a noise in the drive, as if it was about to access the CD, for about half a second. This is the drive I'm using:
pi@autoradio:~ $ ls -al /dev/sr*
brw-rw----+ 1 root cdrom 11, 0 Mai 1 21:38 /dev/sr0
Ejecting the CD from the command line (eject /dev/sr0
), does work, though.
Does anybody know what may cause this error? Thank you.
UPDATE #1: I gave cdcd
(the command-line tool for audio CDs) a try, and I could reproduce the error there, too (even under sudo
):
cdcd> eject
ioctl returned -1
UPDATE #2: I found out that cdaudio
calls ioctl
with the CDAUDIO_EJECT
command (see sourcecode), but I can't find such a command anywhere in the linux/cdrom.h file. According to one of the developers of the cdaudio library, this is just an alias for CDROMEJECT
and not a bug.
UPDATE #3: strace
give me this output. I hope this is sufficient:
ioctl(3, CDROM_DISC_STATUS, 0) = 100
ioctl(3, CDROMSUBCHNL, 0x7e93e308) = 0
ioctl(3, CDROMEJECT, 0x1) = -1 EIO (Input/output error)
write(1, "ioctl returned -1\n", 18) = 18
In contrast, when tracing the eject
utility, I get something slightly different:
geteuid32() = 1000
open("/dev/sr0", O_RDWR|O_NONBLOCK) = 3
ioctl(3, CDROMEJECT, 0x1) = 0
close(3) = 0
exit_group(0) = ?
+++ exited with 0 +++
A comparison of the open ()
calls reveals that the cdaudio
library apparently opens the drive on read-only mode (which is theoretically correct, but, on the other hand, seems to choke the eject
command):
open("/dev/sr0", O_RDONLY|O_NONBLOCK) = 3
SEE ALSO: Question #26240195
回答1:
OK, after a couple of weeks of studying the eject
utility, I found out that at least some CD drives wouldn't accept a CDROMEJECT
command via ioctl ()
, but require a bunch of SCSI commands. In fact, eject
contains a method, which is used as a fallback in such situations: eject_scsi (). I implanted this method into cdaudio
. Tests were successful. So I asked the maintainers of cdaudio
for a respective patch.
来源:https://stackoverflow.com/questions/55942194/how-can-ejecting-an-audio-cd-by-using-cdaudios-cd-eject-method-produce-errno