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.
-
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).
-
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