cdiskioctlsector

ioctl and hdreg to get information on harddrives


I want to get basic information from a hard-drive and print it out. The most important is that the physical sector size is correct.

For the past few hours I have been fighting with ioctl to get what I want but I can't figure it out.

I have never used ioctl before and I can't seem to find an easy explanation on what exactly you have to do.

Anyway my code looks something like this

int main () {
    FILE *driveptr;
    int sectorsize;
    struct hd_driveid hd;

    driveptr=fopen("/dev/sda","r");

    if (ioctl(driveptr,HDIO_GET_IDENTITY, &hd)!=0) { 
        printf("Hard disk model: %s\n",hd.model); 
        printf("Serial number: %s\n",hd.serial_no); 
        printf("Sector size: %i\n",hd.sector_bytes);
        sectorsize=hd.sector_bytes;
    } else { 
        printf("Error fetching device data.\n");
    }
}

In the compiler it throws these warnings, it compiles but the strings are empty when printed.

gcc -o test source.c
source.c: In function ‘main’:
source.c:67:9: warning: passing argument 1 of ‘ioctl’ makes integer from pointer without a cast [enabled by default]
/usr/include/x86_64-linux-gnu/sys/ioctl.h:42:12: note: expected ‘int’ but argument is of type ‘struct FILE *’

I hope somebody can explain to me what goes wrong!


Solution

  • Instead of

    if (ioctl(driveptr,HDIO_GET_IDENTITY, &hd)!=0) { 
    

    you probably want

    if (ioctl(fileno(driveptr),HDIO_GET_IDENTITY, &hd)!= -1) { 
              ^^^^^^^        ^                           ^^
    

    Because ioctl's first argument need to be an integer file descriptor not a FILE *

    fileno() will give you an integer fd from a FILE *.

    Note also that ioctl returns -1 on an error and sets errno.

    Reading the man pages of the functions you are using is probably quicker than posting to StackOverflow.

    See man pages of ioctl, fileno.