[sane-devel] DLL backend doesn't work on 680x0 machines

Dave Huang khym@azeotrope.org
Sat, 12 Apr 2003 20:09:22 -0500


On Sat, Apr 12, 2003 at 01:51:11PM +0200, Henning Meier-Geinitz wrote:
> But this is with "./configure --enable-warnings", the default setting
> in the CVS version of SANE.

Ah, okay... I used --enable-warnings and see the warnings now :)
It's complaining about the casts not having a full prototype for the
function arguments. Changing
  status = (*(SANE_Status(*)())be->op[OP_INIT]) (&version, auth_callback);
to
  status = (*(SANE_Status(*)(SANE_Int *, SANE_Auth_Callback))be->op[OP_INIT]) (&version, auth_callback);

fixes the warning. However, it's messy and hard to read :) David 
Stevenson's suggestion to use typedefs is a good one... so what about 
the following patch?

Also, a question about sane_open()... its second argument is declared as
SANE_Handle * in the backends, but the dll backend is passing &handle,
which is a SANE_Handle **. After adding the prototypes, I got the
following warning:
dll.c:949: warning: passing arg 2 of pointer to function from incompatible pointer type

I added a cast to (SANE_Handle *), but I wanted to make sure that it was
correct to be passing &handle:

-  status = (long) (*be->op[OP_OPEN]) (dev_name, &handle);
+  status = (*(op_open_t)be->op[OP_OPEN]) (dev_name, (SANE_Handle *)&handle);
 
The patched version compiles and seems to work fine on NetBSD/i386, 
NetBSD/m68k, NetBSD/alpha, and MacOS X/powerpc, except for one thing. I 
ran scanimage -T, and scanned a page from all of those machines... the 
scanner is hooked up to the NetBSD/m68k machine; the other machines 
used the net backend. That all worked fine, but scanimage -h from a 
remote machine causes saned on the m68k machine to crash trying to 
write to a null pointer when scanimage gets the list of options... 
here's the end of the log from saned with SANE_DEBUG_DLL set to 4:

[dll] sane_control_option(handle=0x101e0,option=15,action=0,value=0x10180,info=0xffffc8dc)
[dll] sane_control_option(handle=0x101e0,option=18,action=0,value=0x10180,info=0xffffc8dc)
[dll] sane_control_option(handle=0x101e0,option=19,action=0,value=0x0,info=0xffffc8dc)

note that value is 0x0... it's correct for all the previous calls to
sane_control_option, so I don't know why it's different for option=19.
Also, I don't know if this is caused by my patch, or if this is a
completely unrelated problem.

In any case, here's the patch:

--- backend/dll.c.orig	Wed Dec  4 14:30:26 2002
+++ backend/dll.c	Sat Apr 12 17:37:57 2003
@@ -121,6 +121,23 @@
   NUM_OPS
 };
 
+typedef SANE_Status (*op_init_t) (SANE_Int *, SANE_Auth_Callback);
+typedef void (*op_exit_t) (void);
+typedef SANE_Status (*op_get_devs_t) (const SANE_Device ***, SANE_Bool);
+typedef SANE_Status (*op_open_t) (SANE_String_Const, SANE_Handle *);
+typedef void (*op_close_t) (SANE_Handle);
+typedef const SANE_Option_Descriptor * (*op_get_option_desc_t) (SANE_Handle,
+    SANE_Int);
+typedef SANE_Status (*op_ctl_option_t) (SANE_Handle, SANE_Int, SANE_Action,
+    void *, SANE_Int *);
+typedef SANE_Status (*op_get_params_t) (SANE_Handle, SANE_Parameters *);
+typedef SANE_Status (*op_start_t) (SANE_Handle);
+typedef SANE_Status (*op_read_t) (SANE_Handle, SANE_Byte *, SANE_Int,
+    SANE_Int *);
+typedef void (*op_cancel_t) (SANE_Handle);
+typedef SANE_Status (*op_set_io_mode_t) (SANE_Handle, SANE_Bool);
+typedef SANE_Status (*op_get_select_fd_t) (SANE_Handle, SANE_Int *);
+
 struct backend
 {
   struct backend *next;
@@ -481,7 +498,7 @@
 
   DBG (3, "init: initializing backend `%s'\n", be->name);
 
-  status = (long) (*be->op[OP_INIT]) (&version, auth_callback);
+  status = (*(op_init_t)be->op[OP_INIT]) (&version, auth_callback);
   if (status != SANE_STATUS_GOOD)
     return status;
 
@@ -694,7 +711,7 @@
 	    {
 	      DBG (3, "sane_exit: calling backend `%s's exit function\n",
 		   be->name);
-	      (*be->op[OP_EXIT]) ();
+	      (*(op_exit_t)be->op[OP_EXIT]) ();
 	    }
 #ifdef HAVE_DLL
 
@@ -790,7 +807,7 @@
 	if (init (be) != SANE_STATUS_GOOD)
 	  continue;
 
-      status = (long) (*be->op[OP_GET_DEVS]) (&be_list, local_only);
+      status = (*(op_get_devs_t)be->op[OP_GET_DEVS]) (&be_list, local_only);
       if (status != SANE_STATUS_GOOD || !be_list)
 	continue;
 
@@ -929,7 +946,7 @@
 	return status;
     }
 
-  status = (long) (*be->op[OP_OPEN]) (dev_name, &handle);
+  status = (*(op_open_t)be->op[OP_OPEN]) (dev_name, (SANE_Handle *)&handle);
   if (status != SANE_STATUS_GOOD)
     return status;
 
@@ -950,7 +967,7 @@
   struct meta_scanner *s = handle;
 
   DBG (3, "sane_close(handle=%p)\n", handle);
-  (*s->be->op[OP_CLOSE]) (s->handle);
+  (*(op_close_t)s->be->op[OP_CLOSE]) (s->handle);
   free (s);
 }
 
@@ -961,7 +978,7 @@
 
   DBG (3, "sane_get_option_descriptor(handle=%p,option=%d)\n", handle,
        option);
-  return (*s->be->op[OP_GET_OPTION_DESC]) (s->handle, option);
+  return (*(op_get_option_desc_t)s->be->op[OP_GET_OPTION_DESC]) (s->handle, option);
 }
 
 SANE_Status
@@ -973,7 +990,7 @@
   DBG (3,
        "sane_control_option(handle=%p,option=%d,action=%d,value=%p,info=%p)\n",
        handle, option, action, value, info);
-  return (long) (*s->be->op[OP_CTL_OPTION]) (s->handle, option, action, value,
+  return (*(op_ctl_option_t)s->be->op[OP_CTL_OPTION]) (s->handle, option, action, value,
 					     info);
 }
 
@@ -983,7 +1000,7 @@
   struct meta_scanner *s = handle;
 
   DBG (3, "sane_get_parameters(handle=%p,params=%p)\n", handle, params);
-  return (long) (*s->be->op[OP_GET_PARAMS]) (s->handle, params);
+  return (*(op_get_params_t)s->be->op[OP_GET_PARAMS]) (s->handle, params);
 }
 
 SANE_Status
@@ -992,7 +1009,7 @@
   struct meta_scanner *s = handle;
 
   DBG (3, "sane_start(handle=%p)\n", handle);
-  return (long) (*s->be->op[OP_START]) (s->handle);
+  return (*(op_start_t)s->be->op[OP_START]) (s->handle);
 }
 
 SANE_Status
@@ -1003,7 +1020,7 @@
 
   DBG (3, "sane_read(handle=%p,data=%p,maxlen=%d,lenp=%p)\n",
        handle, data, max_length, length);
-  return (long) (*s->be->op[OP_READ]) (s->handle, data, max_length, length);
+  return (*(op_read_t)s->be->op[OP_READ]) (s->handle, data, max_length, length);
 }
 
 void
@@ -1012,7 +1029,7 @@
   struct meta_scanner *s = handle;
 
   DBG (3, "sane_cancel(handle=%p)\n", handle);
-  (*s->be->op[OP_CANCEL]) (s->handle);
+  (*(op_cancel_t)s->be->op[OP_CANCEL]) (s->handle);
 }
 
 SANE_Status
@@ -1022,7 +1039,7 @@
 
   DBG (3, "sane_set_io_mode(handle=%p,nonblocking=%d)\n", handle,
        non_blocking);
-  return (long) (*s->be->op[OP_SET_IO_MODE]) (s->handle, non_blocking);
+  return (*(op_set_io_mode_t)s->be->op[OP_SET_IO_MODE]) (s->handle, non_blocking);
 }
 
 SANE_Status
@@ -1031,5 +1048,5 @@
   struct meta_scanner *s = handle;
 
   DBG (3, "sane_get_select_fd(handle=%p,fdp=%p)\n", handle, fd);
-  return (long) (*s->be->op[OP_GET_SELECT_FD]) (s->handle, fd);
+  return (*(op_get_select_fd_t)s->be->op[OP_GET_SELECT_FD]) (s->handle, fd);
 }
-- 
Name: Dave Huang         |  Mammal, mammal / their names are called /
INet: khym@azeotrope.org |  they raise a paw / the bat, the cat /
FurryMUCK: Dahan         |  dolphin and dog / koala bear and hog -- TMBG
Dahan: Hani G Y+C 27 Y++ L+++ W- C++ T++ A+ E+ S++ V++ F- Q+++ P+ B+ PA+ PL++