ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
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.
Introduction to Linux - A Hands on Guide
This guide was created as an overview of the Linux Operating System, geared toward new users as an exploration tour and getting started guide, with exercises at the end of each chapter.
For more advanced trainees it can be a desktop reference, and a collection of the base knowledge needed to proceed with system and network administration. This book contains many real life examples derived from the author's experience as a Linux system and network administrator, trainer and consultant. They hope these examples will help you to get a better understanding of the Linux system and that you feel encouraged to try out things on your own.
Click Here to receive this Complete Guide absolutely free.
So here's my problem, I'm writing a small application in C++ using kdevelop, and for this application, I want to have some kind of a drop-down list listing the available drives on the system.
I'm more interested in CD/DVD drives to be exact, on windows, the drop-down list would look like this:
You get the picture... how do I get my program to fetch a list of the available mountpoints? I mean, I don't want to make a dumb system call out of the program like "cd /media" "ls", there has to be a better way, besides, I've heard only Suse mounts in /media, so it would be trouble with other distros...
I've found QDir::drives() but it only seems to work on Windows, the reference saying that one other system, only root "/" will be returned.
I thought of that, but, and that's where it gets tricky, there are no mention of my optical drives in /etc/fstab. I guess it has to do with that hotplug feature, I only see the CD/DVD drive in konqueror (media:/). When OpenSuSE mounts CD/DVD drives, it adds a line in /etc/mtab and mounts them to /media, but there are exceptions, like it won't add the mtab entry, nor mount it to /media, if the CD/DVD is either an Audio CD or a movie DVD.
They'll still show up in konqueror (media:/) though, what the f...!?
You see, I'd like a solution that somewhat guarantees that I'll get a list of optical drives on any distro. There's got to be some sort of an API call to do that through KDE. System calls to the shell are kind of an ugly way to do this anyway.
If you are trying to find cd/dvd drives, you might be able to scan through the /sys/block directory. In there you will find subdirectories for each block device, and in those diretories you will find a file called "removable". If it is a cd/dvd, this file will contain "1".
you may be able to get even more specific exploring /sys a little further.
Thanks guys for your answers, I thought for a second that I was on my own on this one :-)
Well, it seems that I will have to make a system call in the end. Don't get me wrong, I appreciate your answers, but I just can't believe there is no C++ class, or method to fetch a list of drives.
I mean, on Windows, there's this .NET API call, "System.IO.Directory.GetLogicalDrives" or something, I did it before and you get your list back.
I checked the source code of k3b for example, because of the drive selection dialog it has. The program is somehow capable of finding my optical drives and the vendor description.
Well, it didn't help me because it goes in all directions, ihheriting classes from classes of classes, and that's just too much for my modest C++ knowledge. Beside, I couldn't really tell what was doing what and couldn't find the code that realizes this particular feature.
I've been combing the kdevelop QT and KDE reference and I couldn't find anything, it's weird.
So let's say I go for it and use a system call, like in C++:
and so on...
By the way, _john_i_, your solution works, I checked it out using the shell.
How do I get the result of the query? The system method only returns an int for SUCCESS or FAIL? Do I have the shell write the result in a temporary file to later parse it with my program? Now, that sounds ugly...
You can read through the various system files mentioned here either using the C++ iostream library, or the KDE/Qt helper classes such as QFile - http://doc.trolltech.com/3.3/qfile.html. There is example code there too.
Using the system(3) call is very inefficient as it spawns another process to execute the command line in a shell.
I'm not sure why KDE doesn't include anything for this. It could in principle, but you need to distinguish between what pure C++ does (just a language with supporting libraries), what KDE does (a desktop environment, but not strictly Linux specific) and what the operating system provides (via the libc system calls and supporting system files). The KDE designers may have decided that it isn't KDE's place to provide disk device information(?)
I totally agree with you that using the "system" call is plain inefficient. I mean, first the call to have the shell write the output of the command in a file, then a C++ method to parse the content of the output file, this all would work, but I will never allow my name to appear in the header of such code.
I mean, even in the 80's, it would have looked ridiculous
I have to be honest with all of you, I hate C++ from the bottom of my heart, this language just doesn't work well with my brain. I understand that some people feel confortable using it, but it brings me in such a rage every time I'm dealing with strings, you have no idea, I find myself screaming in pain every once in a while...
So I looked at other options today, modern languages that take the burden of C++ away. I can use C++ just fine, but it costs me 4 times the effort I need to do the same thing in C#, VB.NET, java, or even C (I know, not object oriented).
I wrote in a previous post about how easy it was using .NET to get such a list of drives, guess what, I did a small test program in C#, ran it on linux using mono, and here's my output:
My CDs are in media, there you go, it's all I freaking wanted... 5mn of work...
I'll have a look into the limitations of that .NET option, I mean, displaying a list of drives isn't the only thing I want my program to do, but it's the base of it all.
Besides, I'll still have to parse /etc/fstab or /etc/mtab and /sys/block to make sure it's a CD (removable file contains "1"). Maybe a method of the System.IO.Directory namespace does it anyway.
// Collect a list of available drives
string drives = System.IO.Directory.GetLogicalDrives();
// Output the available drives
foreach (string str in drives)
Still, thanks to all you, it's good to know there really is a linux community of people helping eachother.
There's no need to resort to running shell commands for this. The /sys filesystem entities will appear to be just regular files to a program. You can use the libc api calls to list out the files in the directory and read them as normal files.
To see how to open and enumerate files in a directory.
Once you get the list of files, jsut open them to read the contents.
So I looked at other options today, modern languages that take the burden of C++ away.
I wrote in a previous post about how easy it was using .NET to get such a list of drives, guess what, I did a small test program in C#, ran it on linux using mono, and here's my output
OK. But my point was that you should distinguish between a language, its libraries, and the operating environment it's running under.
I don't want to start a language flame-war(!), but I think the problem you're having isn't with C++ itself, but with the KDE class libraries that you're using. The C# libraries (evidently) include the device support you need as standard. This could perfectly well be provided in KDE's C++ libraries, though as I mentioned, the KDE designers may not consider "disk drive support" as KDE's business (it's the operating system's business), whereas the C# designers do, probably because they have a Windows mindset where "disk drives" are much more visible to general applications (just a guess).
Small point. Doesn't help anyone, I know. I'll shut up
Oh no, no programming flame-war, it wouldn't take anyone anywhere
You're right in what you say though, it could just be that KDE didn't consider the hardware device handling being its responsibility. As for my complaining about C++, it wasn't only related to this specific problem I'm having, it's just a general issue that I have with the language, which is why I wrote that it doesn't work well with my brain.
I hated C++ on Windows too, I just can't understand the whole MFC, ATL, and so on...
My main problem is that thing with the strings, I remember trying to use SQLite with C++, the TextBox on the Form would give me a System::String back, and SQLite wanted a C string, it took me 6 hours to figure out how to convert the string and finding the header file hosting that function. I was slowly thinking about just doing a for... loop for each character of the string and casting them one by one into a C string.
I saw today that I will have to wait for Mono .NET 2 to be able to use the DriveInfo class, it's being implemented as we speak. In the meantime, I can implement that whole shell solution that you all helped me put together.