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