When I carry my laptop around from one room to the other I often open the DVD tray accidentally. This is only a minor annoyance, but nevertheless I decided that I wanted to do something against it. For this, I needed to learn two things: a) how to lock and unlock the tray from the command line, and b) how to run arbitrary commands when the lid is closed and when it’s opened. It was quite easy to find a solution for both of those problems.

Locking the CD/DVD tray from the command line

Searching a bit I found out that trays can be locked and unlocked using the CDROM_LOCKDOOR ioctrl (and you don’t even need to be root for that). I also found a little C application written by Meethune Bhowmick which wraps that call around a nice (although overly simplistic) command line interface.

You can grab the file here and compile it with «gcc ulcdrom.c -o ulcdrom» (ensure you have package build-essentials installed first).

Update: Martijn let me known that the new version of eject in Jaunty does have an option to do this («eject -i 1» and «eject -i 0»). I’ve created a backport for Intrepid in my PPA.

Run commands when the laptop’s lid is opened or closed

Now, this was even easier. Whenever the lid is opened or closed (I’m talking about Ubuntu Intrepid, I don’t know if it’s the same with other systems) the contents of file /etc/acpi/lid.sh are executed. Note that on a standard installation anything below the line «if [ `CheckPolicy` = 0 ]; then exit; fi» won’t be executed, as that line tells the script to abort if some power management tool is running.

Putting it all together

So, to achieve the objective first we need to get the mentioned application, doing the following:

sudo aptitude install build-essentials # Install gcc
wget http://bloc.eurion.net/wp-content/uploads/2009/01/ulcdrom.c # Get the code
# IMPORTANT: Edit file ulcdrom.c to change "/dev/scd0" to whatever your tray is called.
# (Note that if you use a symlink, like /dev/cdrom, you may have permission problems).
gcc ulcdrom.c -o ulcdrom # Compile it
sudo mv ulcdrom /usr/local/bin/ # Make the binary available system-wide

Now ulcdrom is installed and you can use it whenever you want to lock or unlock the tray, doing «ulcdrom -l» or «ulcdrom -l», respectively. We proceed by adding the following lines to file /etc/acpi/lid.sh, before line «if [ `CheckPolicy` = 0 ]; then exit; fi»:

grep -q closed /proc/acpi/button/lid/*/state
if [ $? = 0 ]; then
    [ ! -f /usr/local/bin/ulcdrom ] || /usr/local/bin/ulcdrom -l
else
    [ ! -f /usr/local/bin/ulcdrom ] || /usr/local/bin/ulcdrom -u
fi

And, that’s it. Now the laptop can be carried without any fear that the CD tray may be opened :).

Note: Just so that you know, I haven’t tried this but if some application has locked the tray and you close and open the lid, that lock may be removed; if this is so, ulcdrom could easily be improved to avoid this (tell me if you need this and I may do the necessary changes for you).

Going further

In case you haven’t realised, you can adapt the above code snippet (the one for lid.sh) to do anything you want, like for example playing a sound every time you close the lid or other fancy stuff. Be creative!