As Philipp Mergenthaler wrote:
> I saw something like this some time ago, too. In my case it was
> because in kern_sysctl:ogetkerninfo(), in "case KINFO_BSDI_SYSINFO:",
> the variable "size" is not always given a value. Maybe the patch in
> http://www.FreeBSD.org/cgi/query-pr.cgi?pr=25476
> fixes it for you, too?
Yep.
> (Hm, now I think my patch could need a comment: "size" will only be
> returned if needed==0. There are two ways this can happen:
After taking a look at the BSD/OS source code (which we are now
allowed to do), i decided to slightly modify the patch. Here's the
result for review.
Index: kern_sysctl.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/kern_sysctl.c,v
retrieving revision 1.112
diff -u -r1.112 kern_sysctl.c
--- kern_sysctl.c 25 Jul 2001 17:21:15 -0000 1.112
+++ kern_sysctl.c 30 Aug 2001 20:34:57 -0000
@@ -1237,6 +1237,7 @@
{
int error, name[6];
size_t size;
+ u_int needed = 0;
switch (uap->op & 0xff00) {
@@ -1300,16 +1301,15 @@
* this is pretty crude, but it's just enough for uname()
* from BSDI's 1.x libc to work.
*
- * In particular, it doesn't return the same results when
- * the supplied buffer is too small. BSDI's version apparently
- * will return the amount copied, and set the *size to how
- * much was needed. The emulation framework here isn't capable
- * of that, so we just set both to the amount copied.
- * BSDI's 2.x product apparently fails with ENOMEM in this
- * scenario.
+ * *size gives the size of the buffer before the call, and
+ * the amount of data copied after a successful call.
+ * If successful, the return value is the amount of data
+ * available, which can be larger than *size.
+ *
+ * BSDI's 2.x product apparently fails with ENOMEM if *size
+ * is too small.
*/
- u_int needed;
u_int left;
char *s;
@@ -1338,11 +1338,13 @@
error = 0;
break;
}
-
-
- /* if too much buffer supplied, trim it down */
- if (size > needed)
- size = needed;
+ if ((error = copyin(uap->size, &size, sizeof(size))) != 0)
+ break;
+ if (size < needed) {
+ error = ENOMEM;
+ break;
+ }
+ size = needed;
/* how much of the buffer is remaining */
left = size;
@@ -1364,7 +1366,7 @@
}
if (error)
return (error);
- p->p_retval[0] = size;
+ p->p_retval[0] = needed ? needed : size;
if (uap->size)
error = copyout((caddr_t)&size, (caddr_t)uap->size,
sizeof(size));
--
cheers, J"org .-.-. --... ...-- -.. . DL8DTL
http://www.sax.de/~joerg/ NIC: JW11-RIPE
Never trust an operating system you don't have sources for. ;-)
To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-current" in the body of the message