This is an old revision of the document!
dvd_drive_status
This program is a successor to the small program trayopen (which also inspired this one). trayopen
works great, but it doesn't poll two things: if the drive is busy or if it has media. dvd_drive_status
adds that feature plus a few more.
To build, just download the dvd_drive_status.c file and compile it.
https://raw2.github.com/beandog/dvd_tools/master/dvd_drive_status.c && gcc -o dvd_drive_status dvd_drive_status.c
Context
The reason this program was written, was because I was having problems having programs access the DVD drive before it is ready. Duplication is simple.
- Open your DVD tray
- Put a DVD in (yes I realize these steps are stupid, bear with me)
- Leave the tray open, and run a command that accesses the drive, such as
lsdvd
- The DVD tray will close
lsdvd
(or whatever program) will try to access the disc while the drive is still not ready- get frustrated and have to re-run your program once the drive is ready
The problem here is that the OS will close the tray, and pass off control of the device back to the user, while the device is still in a non-ready status. So, using the above example, even closing it with eject
, it will still complain, because eject finishes before the drive is ready:
$ eject -t /dev/dvd $ lsdvd /dev/dvd
To fix this, we need to properly check if a drive is ready to be accessed or not. Just being “closed” doesn't mean it is. I wanted to solve that problem, so this is what I came up with.
Drive and Tray States
For reference, here are the possible states that a drive / tray can have. Or, at least, can be determined programatically:
- tray is open
- tray is opening / closing
- tray is closed, no media
- tray is closed, has media
In every state, the DVD drive is ready to send commands to it, and not have your program puke, except for if it is opening or closing.
I should clarify. When I say “opening or closing” I don't mean just the physical state of the tray, this also includes the time that either the OS or the drive has to poll the tray and see what's going on. If your drive has an LED on front, you'll see it lighting up after you close the tray.
It's that state where the drive is not ready to be accessed. And when the drive's not ready to access, then automated programs will complain because it thinks there's not a DVD in the drive – even if there is. Basically, you can't effectively know if something is in a proper state.
Checking Drive / Tray Status
Anyway, inspired by trayopen and having a desire to learn C myself, I came up with this little program, dvd_drive_status
. And by little, I mean that. ALL it does is just query the state of the DVD drive using the Linux cdrom.h.
A nice bonus from the CD driver is that it lets you see if there is media in the tray or not, while the tray is closed. So again, this is very helpful for scripts that want to automate querying the status of your DVD drive.
Scripting
The program reports status to stdout, but returns with an exit code indicating status as well.
Here's the exit codes:
- 1 - no disc (closed, no media)
- 2 - tray open
- 3 - drive not ready (opening or polling)
- 4 - drive ready (closed, has media)
- 5 - device exists, but is NOT a DVD drive
- 6 - cannot access device
If you want to see if the tray is closed, then exit codes 1 and 4 would indicate that.
If you want to see if there is no disc, then exit codes 1 and 2 would apply.
If you just want to see if the tray is closed and has media, that would be exit code 4.
Here's a really simple shell script that you could use to wait until the device is ready to access:
wait_for_drive.sh:
#!/bin/bash # Accept first argument as DVD device, or use /dev/dvd as default device=$1 if [[ -z "$1" ]]; then device=/dev/dvd fi # Run dvd_drive_status, and dump all output to /dev/null for silence dvd_drive_status &> /dev/null # Get the exit code exit_code=$? # Quit if it's already ready already! :) if [[ $exit_code -ne 3 ]]; then exit 0 fi # Otherwise, wait patiently (one second) and try again, until it is ready until [[ $exit_code -ne 3 ]]; do dvd_drive_status &> /dev/null exit_code=$? sleep 1 done