digitalmars.D - Trouble with ioctl and variadic arguments
- nod (55/55) Mar 14 2005 I go nuts. The appended code works in C but not in D.
- =?ISO-8859-1?Q?Anders_F_Bj=F6rklund?= (9/24) Mar 14 2005 Remember that "long" translates to int in D,
- nod (8/12) Mar 14 2005 Oww, that's a subtle one... I was actually scratching my
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;
}
-----
Mar 14 2005
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
Mar 14 2005
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
Mar 14 2005








nod <nod_member pathlink.com>