Как извлечь аудио-CD с помощью метода cdaudio cdaudio, чтобы получить errno # 5? - PullRequest
2 голосов
/ 01 мая 2019

Я пытаюсь воспроизвести аудио-CD из моего приложения, используя библиотеку cdaudio + USB-привод DVD, подключенный к Raspi 3B.Попытка извлечь диск после воспроизведения всегда приводит к ошибке # 5.Это мой код:

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;
    }
  }
}

Это вывод, который я получаю:

ioctl returned -1
Ejecting CD failed! Error: Input/output error

При попытке извлечь компакт-диск я слышу шум в дисководе, как будто это былочтобы получить доступ к компакт-диску, в течение примерно половины секунды.Это привод, который я использую:

pi@autoradio:~ $ ls -al /dev/sr*
brw-rw----+ 1 root cdrom 11, 0 Mai  1 21:38 /dev/sr0

Извлечение компакт-диска из командной строки (eject /dev/sr0), работает, хотя.

Кто-нибудь знает, что может вызвать эту ошибку?Спасибо.

ОБНОВЛЕНИЕ № 1: Я попробовал cdcd (инструмент командной строки для аудио компакт-дисков), и я тоже мог воспроизвести ошибку там (даже при sudo):

cdcd> eject
ioctl returned -1

ОБНОВЛЕНИЕ № 2: Я обнаружил, что cdaudio вызывает ioctl с помощью команды CDAUDIO_EJECT (см. исходный код ), но я не могу найти такую ​​команду нигде в файле linux / cdrom.h . По словам одного из разработчиков библиотеки cdaudio , это просто псевдоним для CDROMEJECT, а не ошибка.

ОБНОВЛЕНИЕ № 3: strace дай мне этот вывод.Надеюсь, этого достаточно:

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

Напротив, при трассировке утилиты eject я получаю что-то немного другое:

geteuid32()                             = 1000
open("/dev/sr0", O_RDWR|O_NONBLOCK)     = 3
ioctl(3, CDROMEJECT, 0x1)               = 0
close(3)                                = 0
exit_group(0)                           = ?
+++ exited with 0 +++

Сравнение вызовов open () показываетчто библиотека cdaudio, по-видимому, открывает привод в режиме «только чтение» (что теоретически правильно, но, с другой стороны, похоже, душит команду eject):

open("/dev/sr0", O_RDONLY|O_NONBLOCK)   = 3

СМОТРИ ТАКЖЕ: Вопрос # 26240195

1 Ответ

0 голосов
/ 11 мая 2019

ОК, после нескольких недель изучения утилиты eject я обнаружил, что по крайней мере некоторые приводы компакт-дисков не принимают команду CDROMEJECT через ioctl (), но требуют кучу команд SCSI.Фактически, eject содержит метод, который используется в качестве запасного варианта в таких ситуациях: eject_scsi ().Я имплантировал этот метод в cdaudio.Испытания прошли успешно.Поэтому я спросил у сопровождающих cdaudio соответствующий патч .

...