Wednesday, 13 August 2008

C/C++: Check the filesystem is mounted

I'll write and explain the function that checks the /etc/mtab file for the information if the given device is mounted. For this the default C FILE pointer and the mntent structure will be used. More information about the mntent struct and what elements it holds see this page. Three includes are needed before the coding starts:

  1. #include <stdio.h>

  2. #include <mntent.h>

  3. #include <string.h>


First line doesn't need much explanation; just notice it is needed for the file i/o. Second line includes mntent.h where the mntent structure and functions are declared and the third line includes string.h for string manipulation functions (see the string.h documentation).
Here is the code of the is_mounted function:


  1. int is_mounted (char * dev_path) {

  2. FILE * mtab = NULL;

  3. struct mntent * part = NULL;

  4. int is_mounted = 0;


  5. if ( ( mtab = setmntent ("/etc/mtab", "r") ) != NULL) {

  6. while ( ( part = getmntent ( mtab) ) != NULL) {

  7. if ( ( part->mnt_fsname != NULL )

  8. && ( strcmp ( part->mnt_fsname, dev_path ) ) == 0 ) {

  9. is_mounted = 1;

  10. }

  11. }

  12. endmntent ( mtab);

  13. }


  14. return is_mounted;

  15. }


In first three lines of the is_mounted function file pointer mtab, mntent structure pointer part and integer is_mounted are declared; we assign NULL value to pointers and a zero to the is_mounted integer (assumption is the device isn't mounted). Program would work without assigning NULLs to pointers but it's there for security reasons.

In the fourth line the setmntent function is introduced. This function takes two arguments, first is the path to the mtab file (it's location is /etc/mtab on most Linux systems) and the second is short string determines how the file is opened by the program. In this case file /etc/mtab is trying to be opened for reading only. setmntent function is similar to the fopen function declared in stdio.h.
Next, the getmntent function takes a file pointer as argument, reads a line from the mtab file and fills the mntent structure.
While loop in this code reads the /etc/mtab file line by line and checks if it contains the required information. We are actually comparing given device path char * dev_path with the each of the device paths inside the mtab file (part->mnt_fsname). We are using function strcmp for this. If the mtab contains it that means the filesystem (device) is mounted and we assign number one to our is_mounted variable. Also the mnt_fsname element also must not be NULL.
After the while loop the function endmntent closes the file system description file mtab.
At the end the is_mounted variable is returned.

Now the famous main function can be constructed like this:

  1. int main() {

  2. if (is_mounted("/dev/scd0")) {

  3. printf("CDROM mounted!\n");

  4. }

  5. else {

  6. printf("CDROM not mounted!\n");

  7. }

  8. return 0;

  9. }


The /dev/scd0 is a device path of my cd/dvd device. This should be the same on all Debian based systems. If the device path of the filesystem is unknown this check can still be performed by comparing the mount path with the mnt_dir element of the mntent structure.

4 comments:

Graham said...

excellent!

Josh Long said...

Nice post dude, keep it up.

thestr4ng3r said...

Thanks! That's just what I needed!

elboulangero said...

Great !