Heath Putnam <hp@heathputnam.com> writes:
> I'm trying to make a TFTP server with scsh. I'm using OpenBSD and
> 0.6.6 (King Conan). I have not patched in Mike's stuff for process
> forms.
>
> To my horror, I'm getting a low-level error that appears random to
> me. Exactly when (and how) seems non-deterministic.
>
> This is really concerning and depressing for me.
>
> I've hacked my TFTP server down just for this bug report (no thread
> for the transfer, no file input --- just datagram i/o), but it still
> seems broken just the same.
>
> I'm using the "King Conan" version --- I haven't patched in Mike's
> stuff to make the extended processes and so on more like normal scheme
> objects. I'm doing this with OpenBSD, if that helps.
>
> If you need more info on my system, please say. I'm assuming not.
>
> I'd love any help on this. I'm totally stuck.
This is indeed a bug in send_substring, the following patch shoud fix
it:
Index: scsh/network1.c
===================================================================
RCS file: /cvsroot/scsh/scsh/scsh/network1.c,v
retrieving revision 1.33
diff -u -r1.33 network1.c
--- scsh/network1.c 17 Feb 2003 16:05:26 -0000 1.33
+++ scsh/network1.c 22 Feb 2005 09:20:11 -0000
@@ -321,12 +321,12 @@
int flags = s48_extract_fixnum (scm_flags);
int start = s48_extract_fixnum (scm_start);
int end = s48_extract_fixnum (scm_end);
- char* buf_part = s48_extract_string (buf) + start;
switch(s48_extract_fixnum (scm_family))
{
case 0: /* only with connected sockets */
{
+ char* buf_part = s48_extract_string (buf) + start;
n = send(s, buf_part, end-start, flags);
break;
}
@@ -334,6 +334,7 @@
{
struct sockaddr_un name;
int scheme_length=S48_STRING_LENGTH(scheme_name);
+ char* buf_part = s48_extract_string (buf) + start;
memset(&name, 0, sizeof(name));
@@ -353,8 +354,16 @@
case AF_INET:
{
struct sockaddr_in name;
- u_long addr = htonl (s48_extract_unsigned_integer (S48_CAR
(scheme_name)));
- u_short port = htons(s48_extract_fixnum (S48_CDR (scheme_name)));
+ u_long addr;
+ u_short port;
+ char* buf_part;
+ S48_DECLARE_GC_PROTECT(2);
+
+ S48_GC_PROTECT_2 (scheme_name,buf);
+
+ addr = htonl (s48_extract_unsigned_integer (S48_CAR (scheme_name)));
+ port = htons (s48_extract_fixnum (S48_CDR (scheme_name)));
+ buf_part = s48_extract_string (buf) + start;
memset(&name, 0, sizeof(name));
@@ -372,7 +381,7 @@
s48_raise_argument_type_error (s48_extract_fixnum (scm_family));
/* error unknown address family */
}
-
+ S48_GC_UNPROTECT();
if (n >= 0)
return s48_enter_fixnum (n);
I'm sorry, by the time I was writing the code I wasn't aware that
s48_extract_(unsigned_)integer could trigger a GC. There are some
other unprotected uses of this function in the code but they will hurt
only in extreme cases (if a pid/uid/gid is bigger than 2^29 for
example). I'll fix them as soon as possible.
I still get an error after some time but I guess that's a problem in
your code (ASCII->CHAR is applied to 256):
Error: exception
"wrong-type-argument"
(ascii->char 256)
"note: INTEGER->CHAR doesn't use ASCII; open ASCII and use ASCII->CHAR"
--
Martin
|