LinuxQuestions.org
View the Most Wanted LQ Wiki articles.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Software
User Name
Password
Linux - Software This 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

Reply
 
Search this Thread
Old 08-17-2004, 07:48 PM   #1
g4c9z
Member
 
Registered: May 2004
Location: Canada
Distribution: Gentoo
Posts: 36

Rep: Reputation: 15
Program to check whether a disk is in a drive?


Hello,

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.
 
Old 08-17-2004, 09:21 PM   #2
arvind_sv
Member
 
Registered: Oct 2002
Location: Bangalore
Distribution: Gentoo Linux
Posts: 96

Rep: Reputation: 15
How about a small hack which uses the Workman library used by KDE? Here's the program:

Code:
int main (void) {
    if (wm_cd_init (0, "/dev/cdrom", 0, 0, 0) == 10) {
        return (1);
    }
    return (0);
}
Compile using:
gcc diskin.c -L`kde-config --prefix`/lib -lworkman -I `kde-config --prefix`/include -o diskin

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/

Arvind

Last edited by arvind_sv; 08-17-2004 at 09:23 PM.
 
Old 08-17-2004, 09:26 PM   #3
arvind_sv
Member
 
Registered: Oct 2002
Location: Bangalore
Distribution: Gentoo Linux
Posts: 96

Rep: Reputation: 15
I forgot to mention. If argv[1] is an invalid device, it still returns 0. I don't believe it's that much of a big problem.

Arvind
 
Old 08-17-2004, 09:57 PM   #4
g4c9z
Member
 
Registered: May 2004
Location: Canada
Distribution: Gentoo
Posts: 36

Original Poster
Rep: Reputation: 15
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.
 
Old 08-17-2004, 11:24 PM   #5
arvind_sv
Member
 
Registered: Oct 2002
Location: Bangalore
Distribution: Gentoo Linux
Posts: 96

Rep: Reputation: 15
Quote:
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.

Arvind
 
Old 08-18-2004, 07:38 AM   #6
g4c9z
Member
 
Registered: May 2004
Location: Canada
Distribution: Gentoo
Posts: 36

Original Poster
Rep: Reputation: 15
Of course; I didn't mean it that way. I meant it's worth my while to do the checking. I'm grateful for your suggestions.
 
Old 08-20-2004, 08:59 AM   #7
g4c9z
Member
 
Registered: May 2004
Location: Canada
Distribution: Gentoo
Posts: 36

Original Poster
Rep: Reputation: 15
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?
 
Old 08-26-2004, 04:06 AM   #8
arvind_sv
Member
 
Registered: Oct 2002
Location: Bangalore
Distribution: Gentoo Linux
Posts: 96

Rep: Reputation: 15
Hi,

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.

Arvind
 
Old 08-26-2004, 04:38 AM   #9
arvind_sv
Member
 
Registered: Oct 2002
Location: Bangalore
Distribution: Gentoo Linux
Posts: 96

Rep: Reputation: 15
Hi,

/usr/include/linux/cdrom.h says:
Code:
/* 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.

Arvind
 
Old 08-26-2004, 01:12 PM   #10
g4c9z
Member
 
Registered: May 2004
Location: Canada
Distribution: Gentoo
Posts: 36

Original Poster
Rep: Reputation: 15
Thanks a lot! I'll have to try that, but I might not get a chance for a few days. That ioctl looks promising.

Last edited by g4c9z; 08-26-2004 at 04:12 PM.
 
Old 08-26-2004, 08:33 PM   #11
arvind_sv
Member
 
Registered: Oct 2002
Location: Bangalore
Distribution: Gentoo Linux
Posts: 96

Rep: Reputation: 15
Sure. But, tell me how it goes.

Arvind
 
Old 08-27-2004, 02:00 PM   #12
g4c9z
Member
 
Registered: May 2004
Location: Canada
Distribution: Gentoo
Posts: 36

Original Poster
Rep: Reputation: 15
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.*/
}
Thanks for all your help!
 
Old 08-27-2004, 08:12 PM   #13
arvind_sv
Member
 
Registered: Oct 2002
Location: Bangalore
Distribution: Gentoo Linux
Posts: 96

Rep: Reputation: 15
Hi,

Quote:
Do you think it's a bug in the Linux kernel?
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...
*/
So, maybe the capability is not present in some drives. Who knows? But, this has been a known "bug" from kernel 2.2.12, going by http://www.mail-archive.com/linux-de.../msg00071.html

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?

If I get some time, I'll see what's going on.

Arvind
 
Old 08-27-2004, 08:16 PM   #14
arvind_sv
Member
 
Registered: Oct 2002
Location: Bangalore
Distribution: Gentoo Linux
Posts: 96

Rep: Reputation: 15
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:

http://www.ussg.iu.edu/hypermail/lin...02.2/0281.html

Arvind
 
Old 08-27-2004, 08:41 PM   #15
g4c9z
Member
 
Registered: May 2004
Location: Canada
Distribution: Gentoo
Posts: 36

Original Poster
Rep: Reputation: 15
Quote:
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.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Total recovery: Which program? ghost4linux, YaST2? Best drive imaging program? lagu2653 Linux - Software 1 06-20-2005 01:44 PM
how to check disk SlipAway172 Mandriva 2 03-01-2005 03:16 AM
Disk check question XPediTioN Slackware 2 06-23-2004 09:07 AM
Boot disk; check. CD in drive; check. Doesn't work; check. Hal DamnSmallLinux 7 02-04-2004 02:10 AM
Forced disk check nabil Linux - General 7 05-25-2001 12:12 PM


All times are GMT -5. The time now is 05:26 AM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration