[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: getsockopt() hurd/glibc mismatch

Weeks ago, I wrote:

> > I'll try doing that tonight, when/if I get at the machine.
> > Because getsockopt(sock, 0, ...) is definitely horked, it always
> > returns the same bogus data, without flagging an error.

The culprit is libc, this short function, to be exact:

getsockopt (fd, level, optname, optval, optlen)
     int fd;
     int level;
     int optname;
     void *optval;
     size_t *optlen;
  error_t err;
  char *buf = optval;
  mach_msg_type_number_t buflen = *optlen;

  if (err = HURD_DPORT_USE (fd, __socket_getopt (port,
						 level, optname,
						 &buf, &buflen)))
    return __hurd_dfail (fd, err);

  if (buf != optval)
      if (*optlen < buflen)
	*optlen = buflen;
      memcpy (optval, buf, *optlen);
      __vm_deallocate (__mach_task_self (), (vm_address_t) buf, buflen);

  return 0;

When buf has changed (which seems always to be the case in my tests),
*optlen is NOT updated. Furthermore, I think the length comparison is
backwards. So I propose:

--- glibc-2.2.2/sysdeps/mach/hurd/getsockopt.c	Tue May 27 00:23:15 1997
+++ ../_glibc/getsockopt.c	Wed Jun  6 10:49:49 2001
@@ -45,10 +45,10 @@
 						 &buf, &buflen)))
     return __hurd_dfail (fd, err);
+  if (*optlen > buflen)
+    *optlen = buflen;
   if (buf != optval)
-      if (*optlen < buflen)
-	*optlen = buflen;
       memcpy (optval, buf, *optlen);
       __vm_deallocate (__mach_task_self (), (vm_address_t) buf, buflen);

which works[1] for me. Does this look correct?

[1] Compiling a working (i.e. not 2.2.3) libc with that fix to try
actually took the better part of the hours spent on that thing.


Attachment: signature.ng
Description: PGP signature

Reply to: