diff options
author | mpp <mpp@FreeBSD.org> | 1995-07-31 10:07:31 +0000 |
---|---|---|
committer | mpp <mpp@FreeBSD.org> | 1995-07-31 10:07:31 +0000 |
commit | 08d1bb1b892e340765b0d6e348481660b3d28481 (patch) | |
tree | c68f5661bbddc7b6f4e72669121642bef37ac4e0 /sys | |
parent | c8b0e9e03740c203c7108cfb7946efad6d2c3355 (diff) | |
download | FreeBSD-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.c | 38 |
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); } /* |