Linux - SoftwareThis forum is for Software issues.
Having a problem installing a new program? Want to know which application is best for the job? Post your question in this forum.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Is there a Linux command to check whether there's a disk in a drive? Even an API function in C or C++? Basically, what I'm looking for is something that would be used like this:
if diskin /dev/cdrom
then ...
fi
The best I've been able to come up with is to mount it, then try to unmount it, and if the umount command returns successfully, there was a disk in the drive. But this doesn't work for music CDs, DVDs, or blank CDs - only for media that contain a filesystem that Linux recognizes.
My primary use for this is I want to make all the disks in all my drives get ejected automatically at shutdown, just like on a Mac (I often forget disks in drives), but I don't want my CD trays popping out if there's nothing in them.
Use as you mentioned: (argv[1] = /dev/cdrom not really used)
Code:
if diskin /dev/cdrom
then
unmount and eject
...
fi
As I said, this is just a hack. I don't even know whether it'll work everywhere. The same code, maybe a little more portable and easier to understand six months down the line:
Code:
#include <libwm/wm_cdrom.h>
int main (int argc, char **argv) {
char *DEFAULT_DEV = "/dev/cdrom";
char *dev = DEFAULT_DEV;
if (argc > 1) {
dev = argv[1];
}
if (wm_cd_init (0, dev, 0, 0, 0) == WM_CDM_NO_DISC) {
return (1);
}
return (0);
}
If you don't have KDE, then, you can look at how the "eject" command (http://eject.sourceforge.net/) handles the CD drive or directly use the CDROM interface provided by the Linux kernel. Look at the documentation at: /usr/src/linux/Documentation/cdrom/
Thanks! I'll have to look into that wm_cd_init function.
I think it would definitely be worthwhile to make sure the argument is valid - after all, a program should work every single time and people sometimes make typos. That could be done by checking whether the device file exists. Better still would be to check whether it's actually a disk drive, but I don't know how.
Originally posted by g4c9z I think it would definitely be worthwhile to make sure the argument is valid - after all, a program should work every single time and people sometimes make typos. That could be done by checking whether the device file exists. Better still would be to check whether it's actually a disk drive, but I don't know how.
Oh, of course, the program should work every single time. But, the "worthwhile" part is where I have to disagree. It's certainly not worth MY while to write the whole program with error-checking for you.
The main part of checking if a CD is in is done. You do the rest.
I just got around to trying that wm_cd_init function, and the program wouldn't compile. It seems that I don't have the "workman" library installed. What package is it part of?
Somehow I did not receive the notification for the message of yours. So, I'm this late in replying.
The workman library is a part of "kdemultimedia" package. I think you can use the "eject" command's source directly. You will just have to prevent it from opening the drive if it fails to find a CD. I'm looking at the sources now. I'll tell you if I find out more about it.
/* drive status possibilities returned by CDROM_DRIVE_STATUS ioctl */
#define CDS_NO_INFO 0 /* if not implemented */
#define CDS_NO_DISC 1
#define CDS_TRAY_OPEN 2
#define CDS_DRIVE_NOT_READY 3
#define CDS_DISC_OK 4
Just as a test, I added the following lines to the eject source after the line:
"if (n_option)" [Line 903] [eject-2.0.13]
Code:
#ifdef CDROM_DRIVE_STATUS
int status = 0, xfd = 0;
xfd = OpenDevice(deviceName);
status = ioctl(xfd, CDROM_DRIVE_STATUS);
fprintf (stderr, "Status: %d\n", status);
#endif
As I said, according to cdrom.h, it *should* return 4 when there's a disc in it, and 1 when it's not. It does return 4, but seems to return 2 (instead of 1) when there's a disc in it. If you think it's reliable (fails reliably) enough, try it out.
You can rip out everything you don't want from eject.c.
I've completed the program. You're right that ioctl returns 2 when, according to the documentation, it should return 1. I've tried it on both my internal DVD-ROM and external CD Writer. Strange. Do you think it's a bug in the Linux kernel?
I was just thinking, too bad this only works for CD-ROM drives; I was looking for a way to check whether a disk is in any drive. I guess there's no single command to do that, right, since each piece of hardware is different? Anyway, for my purposes, this is just fine, and is much less of an ugly hack than I was doing before.
Here's the complete C program:
Code:
/*This code may be used in any way, except you may not call it your own
(you need not explicitly say it's mine).*/
#include <linux/cdrom.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
int main(int argc, char** argv) {
int fd, status;
if (argc != 2) {
printf("Usage: %s <device>\n", argv[0]);
}
else if ((fd = open(argv[1], O_RDONLY | O_NONBLOCK)) == -1) { /* Without
O_NONBLOCK and if there's no disk in the drive, it for some reason won't open
it, and perror returns an error message "No medium found".*/
if (errno == EACCES)
fprintf(stderr, "Error: You don't have permission to read from %s\n", argv[1]);
else if (errno == ENOENT)
fprintf(stderr, "Error: There is no such device as: %s\n", argv[1]);
else if (errno == ENXIO || errno == ENODEV)
fprintf(stderr, "Error: The device file \"%s\" exists, but "
"it seems like the device itself is not attached to the computer.\n", argv[1]);
else {
fprintf(stderr, "Error: Couldn't access device: %s. ", argv[1]);
perror("The error message returned by the system is");
}
}
else {
/* For some reason when a disk isn't in but the tray is closed, ioctl returns 2.
It seems from the documentation in linux/cdrom.h that it should return 1. */
status = ioctl(fd, CDROM_DRIVE_STATUS);
close(fd);
#ifdef DEBUG
printf("%d\n", status);
#endif
if (status == -1)
fprintf(stderr, "Error when trying to get the CDROM drive status. "
"Probably %s isn't a CDROM drive.", argv[1]);
else if (status == 0)
fprintf(stderr, "That CDROM drive doesn't seem to support "
"checking its \"disk present\" status.");
else if (status == 4)
return 0;
}
return 1; /*Any alternative except the one leading to "return 0" means there's no disk.*/
}
I don't know. I don't think so. Such blatant bugs are normally found and corrected. Maybe the documentation is wrong. I saw a small note somewhere online:
Quote:
/*
* If not using Mt Fuji extended media tray reports,
* just return TRAY_OPEN since ATAPI doesn't provide
* any other way to detect this...
*/
The cdrom.h is meant to be a uniform CDROM device interfce. I think it supports (or will support) DVD drives. It has some "capability" flags to find out whether the drive is a DVD drive. But, I don't know why it's not working. What happens when you try? Maybe you got the device wrong?
Ah good, the kernel maintainers know about this, and it's specifically introduced so that newer drives will work properly, as far as I can see. See this:
I think it supports (or will support) DVD drives. It has some "capability" flags to find out whether the drive is a DVD drive. But, I don't know why it's not working. What happens when you try?
I would be willing to try it, but I don't know what kind of function to call. cdrom.h gave a bunch of different #defines for DVDs but didn't say how to use them. I don't see why DVDs wouldn't be supported if the stuff is in that file, but if it isn't working for you, just give me some code and I'll try to run it with my DVD drive.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.