8

I'm making an application that requires the knowledge of whether a CD drive is open or closed.

eject opens the CD drive, and checks how long it takes to open (a shorter amount of time says it's open, and a longer, well...), but I cannot use this technique, because the application actually opens the drive (and I do not want to re-open the drive if it's closed, neither do I want to close the drive if it is open).

How would I do this on linux? I saw that it is possible to do this under Windows (might be wrong though), but I haven't seen a way of doing this on linux.

If it's not possible using linux API calls, is it possible to implement a low-level function that could do this?

MiJyn
  • 5,327
  • 4
  • 37
  • 64
  • I'm not sure this is possible. I don't believe that the IDE interface exposes the state of the drive tray, SATA might though. Also, what about slot and caddy drives that don't have any concept of being open or close? – Dai Mar 27 '13 at 05:40
  • @Dai, I wonder then how linux can detect when a CD has been put in the drive then... if I knew that, maybe that could answer my question. – MiJyn Mar 27 '13 at 05:43
  • The drive does notify the system when the media changes, but that's not the same thing as the status of the tray. – Dai Mar 27 '13 at 05:45
  • @Dai, oh... quite disappointing :/ Oh well, I guess my question is solved then :( – MiJyn Mar 27 '13 at 05:47
  • There must be ioctl() controlling the opening/closing behaviour , do check the driver of the cd-drive , to find out if any such ioctl exists , ps: I think , this question is better suited for [unix and linux](http://unix.stackexchange.com/questions) – Barath Ravikumar Mar 27 '13 at 05:52
  • @BarathBushan, thanks, I will repost it there, but AFAICS, there is no `ioctl()` switch to find if it's open or not. I _do_ know how to open/close it, if that's what you meant. – MiJyn Mar 27 '13 at 05:55
  • @MiJyn [ioctl](http://man7.org/linux/man-pages/man2/ioctl.2.html) is not a switch , it is a system call to the driver , to obtain the status or configure the device – Barath Ravikumar Mar 27 '13 at 05:57
  • @BarathBushan, I'm sorry, yes, that's what I meant (I'm bad with terminology, sorry) – MiJyn Mar 27 '13 at 05:58
  • @Dai You are quire correct that slot and caddy drives have no concept of being open or closed - but they do say if there is no disc or if the disc is ok. Check my answer. – fredrik Mar 27 '13 at 06:51
  • @MiJyn You can do just about anything with `ioctl`, you just need to know where to look for the commands :D – fredrik Mar 27 '13 at 06:52

2 Answers2

8

To make the example code work, you should do it this way:

#include <sys/ioctl.h>
#include <linux/cdrom.h>

int result=ioctl(fd, CDROM_DRIVE_STATUS, CDSL_NONE);

switch(result) {
  case CDS_NO_INFO: ... break;
  case CDS_NO_DISC: ... break;
  case CDS_TRAY_OPEN: ... break;
  case CDS_DRIVE_NOT_READY: ... break;
  case CDS_DISC_OK: ... break;
  default: /* error */
}

i.e. the result is returned as ioctl() function result, not into slot argument.

Étienne
  • 4,773
  • 2
  • 33
  • 58
user2846246
  • 236
  • 2
  • 8
  • Is there a reason to use CDSL_NONE? The doc says "Slot number to be tested, always zero except for jukeboxes." – Étienne Jan 07 '16 at 16:46
  • Invoking this ioctl causes the tray to be loaded; is there a way to prevent that? – Jason May 15 '18 at 00:13
  • 1
    @Jason Open the device on non-blocking mode (`O_NONBLOCK`). See [this comment in `linux/cdrom.h`](https://github.com/torvalds/linux/blob/v4.17/include/uapi/linux/cdrom.h#L26). – Jonathon Reinhart Jul 30 '18 at 00:46
6

You can get tray state by using the CDROM_DRIVE_STATUS ioctl. All ioctls for CD-drives can be found in /usr/include/linux/cdrom.h

#define CDROM_DRIVE_STATUS      0x5326  /* Get tray position, etc. */

Taken from here

int slot;
ioctl(fd, CDROM_DRIVE_STATUS, slot);

switch(slot) {
  case CDS_NO_INFO: ... break;
  case CDS_NO_DISC: ... break;
  case CDS_TRAY_OPEN: ... break;
  case CDS_DRIVE_NOT_READY: ... break;
  case CDS_DISC_OK: ... break;
  default: /* error */
}
fredrik
  • 6,483
  • 3
  • 35
  • 45
  • Interesting: `CDS_TRAY_OPEN`, there's our answer. – Dai Mar 27 '13 at 07:05
  • Doesn't work :/ Here is my source code: http://pastebin.com/y48ZYZ8x . It just returns false, regardless if it's open or not – MiJyn Mar 27 '13 at 21:46
  • If you add debug output for the other variables, which do you get? – fredrik Mar 28 '13 at 11:12
  • @fredrik, What do you mean by debug output? – MiJyn Mar 28 '13 at 20:49
  • The simplest debug output would be a `fprintf(stdout, "...\n");` for C or `std::cout << "..." << std::endl;`for C++ – fredrik Mar 28 '13 at 20:51
  • @fredrik, sorry, I meant, what do you want me to print? `slot`? – MiJyn Mar 28 '13 at 21:57
  • Something which lets you know which slot it returned, so that you can determine what your computer thinks the CD is doing. – fredrik Mar 28 '13 at 22:31
  • 1
    @fredrik, thanks, I figured out the issue. I used "switched" `slot` instead of the return value of `ioctl` – MiJyn Mar 28 '13 at 23:13
  • Interesting, the page I picked it from ([here](http://www.mjmwired.net/kernel/Documentation/ioctl/cdrom.txt#682)), used slot and not the return value. Seems like an error in the documentation – fredrik Mar 29 '13 at 07:34
  • 1
    @fredrik, yeah, and the "int slot" without any pointers or default value doesn't seem good either... – MiJyn Mar 29 '13 at 08:19