Thread overview | |||||
---|---|---|---|---|---|
|
March 14, 2005 Trouble with ioctl and variadic arguments | ||||
---|---|---|---|---|
| ||||
I go nuts. The appended code works in C but not in D. What am I doing wrong? The D version fails on the ioctl call with errno set to 14, or EFAULT, which means that the supplied out pointer points to invalid memory. I have tried other ways of allocating memory, but since the result is the same I only write the shortest way here, and it should work. (68 is the sizeof of the real struct fb_fix_screeninfo) I assume the problem lies in that ioctl takes variadic parameters. Is there a correct way to deal with this, or is this a compiler bug? D version: ----- import std.c.stdio; // for printf import std.c.linux.linux; // for open, close import std.c.stdlib; // for getErrno extern (C) { // from /usr/include/sys/ioctl.h int ioctl (int fd, ulong request, ...); // from /usr/include/linux/fb.h const int FBIOGET_FSCREENINFO = 0x4602; } int main(char[][] args) { int fbd; void* f = malloc(68); if ( (fbd = open("/dev/fb0", O_RDWR)) == -1 ) printf("open() failed. errno == %i\n", getErrno()); if ( ioctl(fbd, FBIOGET_FSCREENINFO, f) != 0 ) printf("ioctl() failed. errno == %i\n", getErrno()); close(fbd); return 0; } ----- C version: ----- #include <errno.h> // for errno #include <stdio.h> // for printf #include <fcntl.h> // for O_RDWR #include <sys/ioctl.h> // for ioctl #include <linux/fb.h> // for FBIOGET_SCREENINFO int main(void) { int fbd; void* f = malloc(68); if ( (fbd = open("/dev/fb0", O_RDWR)) == -1 ) printf("open() failed. errno == %i\n", errno); if ( ioctl(fbd, FBIOGET_FSCREENINFO, f) != 0 ) printf("ioctl() failed. errno == %i\n", errno); close(fbd); return 0; } ----- |
March 14, 2005 Re: Trouble with ioctl and variadic arguments | ||||
---|---|---|---|---|
| ||||
Posted in reply to nod | nod wrote: > I go nuts. The appended code works in C but not in D. > What am I doing wrong? > > extern (C) > { > // from /usr/include/sys/ioctl.h > int ioctl (int fd, ulong request, ...); > > // from /usr/include/linux/fb.h > const int FBIOGET_FSCREENINFO = 0x4602; > } Here is what my C header says: > /* Perform the I/O control operation specified by REQUEST on FD. > One argument may follow; its presence and type depend on REQUEST. > Return value depends on REQUEST. Usually -1 indicates error. */ > extern int ioctl (int __fd, unsigned long int __request, ...) __THROW; Remember that "long" translates to int in D, it is "long long" that translates to long... Thus it becomes: extern(C) int ioctl (int fd, uint request, ...); Another reason why we need a tool to translate these headers, instead of having to do it manually ? --anders |
March 14, 2005 Re: Trouble with ioctl and variadic arguments | ||||
---|---|---|---|---|
| ||||
Posted in reply to Anders F Björklund | In article <d144mn$1m3t$1@digitaldaemon.com>, =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= says... > >Thus it becomes: >extern(C) int ioctl (int fd, uint request, ...); Oww, that's a subtle one... I was actually scratching my head over why the D test program was pushing an extra dword onto the stack. Well it's obvious now isn't it? :) > >Another reason why we need a tool to translate >these headers, instead of having to do it manually ? > Indeed. That would make the switch less painful. Oh, and thanks a million! //nod |
Copyright © 1999-2021 by the D Language Foundation