Calling ioctl() under linux - problem



  • Hi,
    I am using qtcretor under ubuntu 10.10 / 2.6.35 32bit linux - calling a loadable module/driver in a qui application. The simple code fragment is -
    @.......
    open();
    ioctl();
    ...
    ioctl();
    close();
    .......@

    The driver is open ok, however it seems the call to ioctl() does not do anything - the data buffer is not modified, no data returned. I test this in debug mode - step by step running, checking what is the result.
    The qtcreator is started in a way of - sudo /.../qtcreator , to be able to open the driver.

    I did build a similar code fragment with gcc for a command line / terminal app - it works ok, and ioctl() does the job needed, data is returned.

    I will appreciate feedback - did I miss something, what can the issue be?

    Thank you,
    Paul.



  • Please post both code snippets (from your test app and your problem app). The description of the code is not what the code actually does more often than not.



  • Hello Franzk,

    I did found the issue -
    linux kernel headers have a macro -
    _IOWR(....)
    which calculates the ioctl number passed to - ioctl()

    It seems gcc compiler calculates it properly.
    However qt (or g++) makes the ioctl number with 0xa0 added.
    I am not going to dig deeper, I just did subtract 0xa0 from the number in my qt program.

    I suspect the issue is with qt - for ex. the size of 'int' variable is 64bit, versus normally 32bit in most other programs.

    Paul.



  • Qt has no influence on the size of integers. I think it is a rather blunt solution to just subtract 0xa0 from your ioctl number, but if it works for you, I'm not to complain :P.


  • Moderators

    Please do not run Qt Creator as root! Running big applications with plugins and whatnot as root is never a good idea.

    You can always start your application as root inside creator: Just add a custom executable run configuration and call a script that does the sudo and then starts your application.

    I would go deeper and try to figure out this issue: I see no reason why g++ should calculate another offset as gcc. Maybe it is a compiler bug or some issue with include files (you did use extern "C", didn't you?). I would be afraid that this workaround will fail after some upgrade of ubuntu (when the root cause is fixed:-).



  • Hello Tobias,

    If I run qt regularly , not as root, and I run in debug mode to test my app - can I do 'open' of a driver?
    Normally it fails if run not as root .

    How do I do this -

    add a custom executable run configuration and call a script that does the sudo and then starts your application

    Regarding my fix - once the app is built it will run ok regardless of fixes in ubuntu or qt.
    I will pay attention if rebuilding the app with fixed ubuntu or qt.

    Paul.



  • You can also set the permissions for the specific device so that your development user has the necessary rights. This is a much safer approach generally.

    I find it hard to believe that you have to subtract 0xa0 from your file descriptor in order for the ioctl to work and that it is a bug in ubuntu. Please post your code, preferably your entire project (tarred of course).


  • Moderators

    Franzk: You are right, this is most likely not a bug in ubuntu. I just wanted to point out that this will come back to bite paa123456 sooner or later if not properly investigated.



  • And nobody thinks about some brave users who will crash their files by using this program. It is scary that such software will be out in the wild!



  • I was actually kind of hoping the program wouldn't be released into the wild like that.



  • Hi ,

    I wrote -

    I did found the issue – linux kernel headers have a macro – _IOWR(….)
    which calculates the ioctl number passed to – ioctl()

    It seems gcc compiler calculates it properly.
    However qt (or g++) makes the ioctl number with 0xa0 added.
    I am not going to dig deeper, I just did subtract 0xa0 from the number in my qt program.

    Here is the simplified code -

    @
    #include <stdio.h>

    #include <fcntl.h> /* open /
    #include <unistd.h> /
    exit /
    #include <sys/ioctl.h> /
    ioctl */

    #include <pthread.h>

    #include <sys/stat.h>
    #include <sys/types.h>

    #include <sys/mman.h>
    #include <sys/syscall.h>
    #include <sys/utsname.h>

    #define BYTE unsigned char
    #define WORD unsigned short
    #define DWORD unsigned int

    #define TRUE 1
    #define FALSE 0

    #define FILE_DEVICE_UNKNOWN
    #define METHOD_BUFFERED
    #define FILE_ANY_ACCESS
    #define CTL_CODE(a, b,c, d) _IOWR(0, b, int) // !!! linux specific |0x4000

    // usl related
    #define ARS_IOCTL_INDEX 0x000

    #define IOCTL_ARS_IO_INP CTL_CODE(FILE_DEVICE_UNKNOWN,
    ARS_IOCTL_INDEX + 0x2b,
    METHOD_BUFFERED,
    FILE_ANY_ACCESS)

    int main ()
    {
    DWORD dw;
    // void *drvadr;

    dw = IOCTL_ARS_IO_INP;
    printf("\n IOCTL_ARS_IO_INP = %x\n", dw);

    return 0;
    

    }
    @

    You can -

    • save it as file and build it with gcc
    • make a simple qtcreator app and include code

    Paul.

    [edit: code highlighted / Denis Kormalev]



  • Did you try to compile this yourself?



  • Some copy issue that was. Both gcc and g++ give the same result for me. (Gentoo, gcc 4.5.2)



  • paa123456, please use @ to highlight code


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.