summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authormpp <mpp@FreeBSD.org>1995-07-31 10:07:31 +0000
committermpp <mpp@FreeBSD.org>1995-07-31 10:07:31 +0000
commit08d1bb1b892e340765b0d6e348481660b3d28481 (patch)
treec68f5661bbddc7b6f4e72669121642bef37ac4e0 /sys
parentc8b0e9e03740c203c7108cfb7946efad6d2c3355 (diff)
downloadFreeBSD-src-08d1bb1b892e340765b0d6e348481660b3d28481.zip
FreeBSD-src-08d1bb1b892e340765b0d6e348481660b3d28481.tar.gz
Fix the sysctl string routines to return as much of the
string as possible and return ENOMEM if the entire string cannot be returned. This brings the routines in line with how the man page says they work, and how the calling routines are expecting them to work. This allows the dummy uname() routine in libc to obtain the version string, since the kernel version string is longer than that normally returned by the uname() routine. This is 3/4 of the fix for PR# 462. Reviewed by: Bruce Evans
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/kern_sysctl.c38
1 files changed, 25 insertions, 13 deletions
diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c
index 472dce8..c1e3386 100644
--- a/sys/kern/kern_sysctl.c
+++ b/sys/kern/kern_sysctl.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)kern_sysctl.c 8.4 (Berkeley) 4/14/94
- * $Id: kern_sysctl.c,v 1.26 1995/07/09 02:49:30 peter Exp $
+ * $Id: kern_sysctl.c,v 1.27 1995/07/28 18:04:47 davidg Exp $
*/
/*
@@ -250,14 +250,16 @@ kern_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
case KERN_HOSTNAME:
error = sysctl_string(oldp, oldlenp, newp, newlen,
hostname, sizeof(hostname));
- if (newp && !error)
- hostnamelen = newlen;
+ if (newp)
+ if (error == 0 || error == ENOMEM)
+ hostnamelen = newlen;
return (error);
case KERN_DOMAINNAME:
error = sysctl_string(oldp, oldlenp, newp, newlen,
domainname, sizeof(domainname));
- if (newp && !error)
- domainnamelen = newlen;
+ if (newp)
+ if (error == 0 || error == ENOMEM)
+ domainnamelen = newlen;
return (error);
case KERN_HOSTID:
inthostid = hostid; /* XXX assumes sizeof long <= sizeof int */
@@ -458,22 +460,28 @@ sysctl_string(oldp, oldlenp, newp, newlen, str, maxlen)
char *str;
int maxlen;
{
- int len, error = 0;
+ int len, error = 0, rval = 0;
len = strlen(str) + 1;
- if (oldp && *oldlenp < len)
+ if (oldp && *oldlenp < len) {
len = *oldlenp;
+ rval = ENOMEM;
+ }
if (newp && newlen >= maxlen)
return (EINVAL);
if (oldp) {
*oldlenp = len;
error = copyout(str, oldp, len);
+ if (error)
+ rval = error;
}
- if (error == 0 && newp) {
+ if ((error == 0 || error == ENOMEM) && newp) {
error = copyin(newp, str, newlen);
+ if (error)
+ rval = error;
str[newlen] = 0;
}
- return (error);
+ return (rval);
}
/*
@@ -486,17 +494,21 @@ sysctl_rdstring(oldp, oldlenp, newp, str)
void *newp;
char *str;
{
- int len, error = 0;
+ int len, error = 0, rval = 0;
len = strlen(str) + 1;
- if (oldp && *oldlenp < len)
- return (ENOMEM);
+ if (oldp && *oldlenp < len) {
+ len = *oldlenp;
+ rval = ENOMEM;
+ }
if (newp)
return (EPERM);
*oldlenp = len;
if (oldp)
error = copyout(str, oldp, len);
- return (error);
+ if (error)
+ rval = error;
+ return (rval);
}
/*
OpenPOWER on IntegriCloud