sane-project-website/old-archive/1999-01/0226.html

227 wiersze
9.1 KiB
HTML

<!-- received="Tue Jan 26 04:24:50 1999 PST" -->
<!-- sent="Tue, 26 Jan 1999 00:23:14 -0700 (MST)" -->
<!-- name="Andreas Dilger" -->
<!-- email="adilger@enel.ucalgary.ca" -->
<!-- subject="Strange memcpy in sanei_scsi.c" -->
<!-- id="199901260723.AAA04578@andreas.dilger.net" -->
<!-- inreplyto="" -->
<title>sane-devel: Strange memcpy in sanei_scsi.c</title>
<h1>Strange memcpy in sanei_scsi.c</h1>
<b>Andreas Dilger</b> (<a href="mailto:adilger@enel.ucalgary.ca"><i>adilger@enel.ucalgary.ca</i></a>)<br>
<i>Tue, 26 Jan 1999 00:23:14 -0700 (MST)</i>
<p>
<ul>
<li> <b>Messages sorted by:</b> <a href="date.html#226">[ date ]</a><a href="index.html#226">[ thread ]</a><a href="subject.html#226">[ subject ]</a><a href="author.html#226">[ author ]</a>
<!-- next="start" -->
<li> <b>Next message:</b> <a href="0227.html">Andreas Dilger: "Re: Frontend XSane-0.06 available"</a>
<li> <b>Previous message:</b> <a href="0225.html">Petter Reinholdtsen: "Re: SG_BIG_BUFF woes on Linux"</a>
<!-- nextthread="start" -->
<!-- reply="end" -->
</ul>
<!-- body="start" -->
I was looking at whether I could change the code in sanei_scsi.c to use<br>
a dynamically allocated data buffer (SG_BIG_BUFF related), and I came<br>
across something strange in sanei_scsi.c:<br>
<p>
In the function sanei_scsi_req_enter(), we do a<br>
memcpy (&amp;req-&gt;cdb.data, src, src_size);<br>
<p>
but in the function sanei_scsi_req_wait(), there is a call<br>
memcpy (req-&gt;dst, req-&gt;cdb.data, nread);<br>
<p>
which is not properly getting the address of the statically allocated<br>
data buffer when it is doing the memcpy. This should fail miserably,<br>
but is it possible that this part of sanei_scsi_req_wait() function<br>
isn't used very often?<br>
<p>
Hope to hear from someone in the know...<br>
<p>
Also below is a preliminary patch to allow for dynamic SG_BIG_BUFF under<br>
Linux. It compiles, but has not been tested at all, so YMMV.<br>
The patch quiets one minor compiler warning at the beginning, and also<br>
closes the file descriptor used to read from /proc/sys/kernel/sg-big-buff.<br>
Good luck...<br>
<p>
Cheers, Andreas<br>
_______________________________________________<br>
--- sanei_scsi.c.orig Mon Jan 25 22:27:33 1999<br>
+++ sanei_scsi.c Tue Jan 26 00:11:59 1999<br>
@@ -211,11 +211,13 @@<br>
}<br>
*fd_info;<br>
<br>
+#if USE != LINUX_INTERFACE<br>
static u_char cdb_sizes[8] =<br>
{<br>
6, 10, 10, 12, 12, 12, 10, 10<br>
};<br>
#define CDB_SIZE(opcode) cdb_sizes[(((opcode) &gt;&gt; 5) &amp; 7)]<br>
+#endif<br>
<br>
<br>
#if USE == DOMAINOS_INTERFACE<br>
@@ -608,6 +610,7 @@<br>
sanei_scsi_max_request_size = atoi (buf);<br>
DBG (1, "sanei_scsi_open: sanei_scsi_max_request_size=%d bytes\n",<br>
sanei_scsi_max_request_size);<br>
+ close (fd);<br>
}<br>
}<br>
#endif<br>
@@ -1224,11 +1227,10 @@<br>
size_t *dst_len;<br>
void *dst;<br>
struct<br>
- {<br>
- struct sg_header hdr;<br>
- u_int8_t data[SG_BIG_BUFF];<br>
- }<br>
- cdb;<br>
+ {<br>
+ struct sg_header *hdr;<br>
+ u_int8_t *data;<br>
+ } cdb;<br>
struct req *next;<br>
}<br>
*qhead, *qtail, *free_list;<br>
@@ -1244,9 +1246,9 @@<br>
DBG (4, "sanei_scsi.issue: %p\n", req);<br>
<br>
ATOMIC (req-&gt;running = 1;<br>
- nwritten = write (req-&gt;fd, &amp;req-&gt;cdb, req-&gt;cdb.hdr.pack_len));<br>
+ nwritten = write (req-&gt;fd, req-&gt;cdb.hdr, req-&gt;cdb.hdr-&gt;pack_len));<br>
<br>
- if (nwritten != req-&gt;cdb.hdr.pack_len)<br>
+ if (nwritten != req-&gt;cdb.hdr-&gt;pack_len)<br>
{<br>
DBG (1, "sanei_scsi.issue: bad write (errno=%s)\n",<br>
strerror (errno));<br>
@@ -1270,7 +1272,7 @@<br>
for (req = qhead; req; req = next_req)<br>
{<br>
if (req-&gt;running &amp;&amp; !req-&gt;done)<br>
- read (req-&gt;fd, &amp;req-&gt;cdb, req-&gt;cdb.hdr.reply_len);<br>
+ read (req-&gt;fd, req-&gt;cdb.hdr, req-&gt;cdb.hdr-&gt;reply_len);<br>
next_req = req-&gt;next;<br>
<br>
req-&gt;next = free_list;<br>
@@ -1293,13 +1295,34 @@<br>
}<br>
else<br>
{<br>
- req = malloc (sizeof (*req));<br>
- if (!req)<br>
+ req = (struct req *) malloc (sizeof (struct req));<br>
+ if (req == NULL)<br>
{<br>
- DBG (1, "sanei_scsi_req_enter: failed to malloc %lu bytes\n",<br>
- (u_long) sizeof (*req));<br>
+ DBG (1, "sanei_scsi_req_enter: failed to malloc %lu bytes for req\n",<br>
+ (u_long) sizeof (struct req));<br>
return SANE_STATUS_NO_MEM;<br>
}<br>
+<br>
+ /* Allocate enough space for both the header and the buffer (whatever<br>
+ * the kernel max buffer size is currently configured as), to ensure they<br>
+ * are contiguous, but then set the .data pointer separately, so we can<br>
+ * access the data directly. It appears, from the read and write calls<br>
+ * to the SCSI device that the .hdr and .data segments must be contiguous.<br>
+ * If that isn't the case, we don't have to be so convoluted.<br>
+ * Make sure we only free .hdr and not .data (if freeing is ever done)!<br>
+ */<br>
+ req-&gt;cdb.hdr = (struct sg_header *) malloc (sizeof (struct sg_header) +<br>
+ sanei_scsi_max_request_size);<br>
+ if (req-&gt;cdb.hdr == NULL)<br>
+ {<br>
+ DBG (1, "sanei_scsi_req_enter: failed to malloc %lu bytes for cdb\n",<br>
+ (u_long) (sizeof (struct sg_header) +<br>
+ sanei_scsi_max_request_size));<br>
+ free (req);<br>
+ return SANE_STATUS_NO_MEM;<br>
+ }<br>
+ else<br>
+ req-&gt;cdb.data = (u_int8_t *) (req-&gt;cdb.hdr + sizeof (struct sg_header));<br>
}<br>
req-&gt;fd = fd;<br>
req-&gt;running = 0;<br>
@@ -1307,11 +1330,11 @@<br>
req-&gt;status = SANE_STATUS_GOOD;<br>
req-&gt;dst = dst;<br>
req-&gt;dst_len = dst_size;<br>
- memset (&amp;req-&gt;cdb.hdr, 0, sizeof (req-&gt;cdb.hdr));<br>
- req-&gt;cdb.hdr.pack_id = pack_id++;<br>
- req-&gt;cdb.hdr.pack_len = src_size + sizeof (req-&gt;cdb.hdr);<br>
- req-&gt;cdb.hdr.reply_len = (dst_size ? *dst_size : 0) + sizeof (req-&gt;cdb.hdr);<br>
- memcpy (&amp;req-&gt;cdb.data, src, src_size);<br>
+ memset (req-&gt;cdb.hdr, 0, sizeof (struct sg_header));<br>
+ req-&gt;cdb.hdr-&gt;pack_id = pack_id++;<br>
+ req-&gt;cdb.hdr-&gt;pack_len = src_size + sizeof (struct sg_header);<br>
+ req-&gt;cdb.hdr-&gt;reply_len = (dst_size ? *dst_size : 0) + sizeof (struct sg_header);<br>
+ memcpy (req-&gt;cdb.data, src, src_size);<br>
<br>
req-&gt;next = 0;<br>
ATOMIC (if (qtail)<br>
@@ -1355,7 +1378,7 @@<br>
select (req-&gt;fd + 1, &amp;readable, 0, 0, 0);<br>
<br>
/* now atomically read result and set DONE: */<br>
- ATOMIC (nread = read (req-&gt;fd, &amp;req-&gt;cdb, req-&gt;cdb.hdr.reply_len);<br>
+ ATOMIC (nread = read (req-&gt;fd, req-&gt;cdb.hdr, req-&gt;cdb.hdr-&gt;reply_len);<br>
req-&gt;done = 1);<br>
<br>
/* Now issue next command asap, if any. We can't do this<br>
@@ -1373,25 +1396,25 @@<br>
}<br>
else<br>
{<br>
- nread -= sizeof (req-&gt;cdb.hdr);<br>
+ nread -= sizeof (struct sg_header);<br>
<br>
/* check for errors, but let the sense_handler decide.... */<br>
- if ((req-&gt;cdb.hdr.result != 0) ||<br>
- ((req-&gt;cdb.hdr.sense_buffer[0] &amp; 0x7f) != 0))<br>
+ if ((req-&gt;cdb.hdr-&gt;result != 0) ||<br>
+ ((req-&gt;cdb.hdr-&gt;sense_buffer[0] &amp; 0x7f) != 0))<br>
{<br>
SANEI_SCSI_Sense_Handler handler<br>
= fd_info[req-&gt;fd].sense_handler;<br>
void *arg = fd_info[req-&gt;fd].sense_handler_arg;<br>
<br>
DBG (1, "sanei_scsi_req_wait: SCSI command complained: %s\n",<br>
- strerror (req-&gt;cdb.hdr.result));<br>
+ strerror (req-&gt;cdb.hdr-&gt;result));<br>
<br>
- if (req-&gt;cdb.hdr.result == EBUSY)<br>
+ if (req-&gt;cdb.hdr-&gt;result == EBUSY)<br>
status = SANE_STATUS_DEVICE_BUSY;<br>
else if (handler)<br>
/* sense handler should return SANE_STATUS_GOOD if it<br>
decided all was ok afterall */<br>
- status = (*handler) (req-&gt;fd, req-&gt;cdb.hdr.sense_buffer, arg);<br>
+ status = (*handler) (req-&gt;fd, req-&gt;cdb.hdr-&gt;sense_buffer, arg);<br>
else<br>
status = SANE_STATUS_IO_ERROR;<br>
}<br>
________________________<br>
<pre>
--
Andreas Dilger University of Calgary \ "If a man ate a pound of pasta and
Micronet Research Group \ a pound of antipasto, would they
Dept of Electrical &amp; Computer Engineering \ cancel out, leaving him still
&lt;<a href="http://www-mddsp.enel.ucalgary.ca/People/adilger/">http://www-mddsp.enel.ucalgary.ca/People/adilger/</a>&gt; hungry?" -- Dogbert
<p>
<pre>
--
Source code, list archive, and docs: <a href="http://www.mostang.com/sane/">http://www.mostang.com/sane/</a>
To unsubscribe: echo unsubscribe sane-devel | mail <a href="mailto:majordomo@mostang.com">majordomo@mostang.com</a>
</pre>
<!-- body="end" -->
<p>
<ul>
<!-- next="start" -->
<li> <b>Next message:</b> <a href="0227.html">Andreas Dilger: "Re: Frontend XSane-0.06 available"</a>
<li> <b>Previous message:</b> <a href="0225.html">Petter Reinholdtsen: "Re: SG_BIG_BUFF woes on Linux"</a>
<!-- nextthread="start" -->
<!-- reply="end" -->
</ul>