Calling ioctl() under linux - problem
-
wrote on 24 Apr 2011, 18:41 last edited by
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. -
wrote on 24 Apr 2011, 18:58 last edited by
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.
-
wrote on 25 Apr 2011, 18:35 last edited by
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.
-
wrote on 25 Apr 2011, 19:52 last edited by
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.
-
wrote on 26 Apr 2011, 05:51 last edited by
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:-).
-
wrote on 26 Apr 2011, 20:18 last edited by
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.
-
wrote on 26 Apr 2011, 20:34 last edited by
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).
-
wrote on 27 Apr 2011, 05:42 last edited by
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.
-
wrote on 27 Apr 2011, 09:47 last edited by
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!
-
wrote on 27 Apr 2011, 10:33 last edited by
I was actually kind of hoping the program wouldn't be released into the wild like that.
-
wrote on 27 Apr 2011, 19:59 last edited by
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]
-
wrote on 27 Apr 2011, 21:00 last edited by
Did you try to compile this yourself?
-
wrote on 27 Apr 2011, 21:06 last edited by
Some copy issue that was. Both gcc and g++ give the same result for me. (Gentoo, gcc 4.5.2)
-
wrote on 28 Apr 2011, 07:18 last edited by
paa123456, please use @ to highlight code
1/14