diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 1998-07-07 07:12:54 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 1998-07-07 07:12:54 +0000 |
commit | 92eb952610a47e72b227f82fa5b443acef185daa (patch) | |
tree | cb87ad6c6e14eb1fade24bd87b9eba352868bc5e /sys/kern | |
parent | 8a836816791cedf4b8b9c0387db0bbbffa977a86 (diff) |
per XPG, gethostname() with a short buffer returns truncated data - not ENOMEM.
As permitted, make the truncated buffer be NUL terminated.
make getdomainname() match.
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/kern_sysctl.c | 50 |
1 files changed, 43 insertions, 7 deletions
diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c index c0d0316cfa7..bf8ec43273d 100644 --- a/sys/kern/kern_sysctl.c +++ b/sys/kern/kern_sysctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_sysctl.c,v 1.25 1998/06/02 06:10:28 deraadt Exp $ */ +/* $OpenBSD: kern_sysctl.c,v 1.26 1998/07/07 07:12:40 deraadt Exp $ */ /* $NetBSD: kern_sysctl.c,v 1.17 1996/05/20 17:49:05 mrg Exp $ */ /*- @@ -246,13 +246,13 @@ kern_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p) securelevel = level; return (0); case KERN_HOSTNAME: - error = sysctl_string(oldp, oldlenp, newp, newlen, + error = sysctl_tstring(oldp, oldlenp, newp, newlen, hostname, sizeof(hostname)); if (newp && !error) hostnamelen = newlen; return (error); case KERN_DOMAINNAME: - error = sysctl_string(oldp, oldlenp, newp, newlen, + error = sysctl_tstring(oldp, oldlenp, newp, newlen, domainname, sizeof(domainname)); if (newp && !error) domainnamelen = newlen; @@ -479,16 +479,52 @@ sysctl_string(oldp, oldlenp, newp, newlen, str, maxlen) char *str; int maxlen; { + return sysctl__string(oldp, oldlenp, newp, newlen, str, maxlen, 0); +} + +int +sysctl_tstring(oldp, oldlenp, newp, newlen, str, maxlen) + void *oldp; + size_t *oldlenp; + void *newp; + size_t newlen; + char *str; + int maxlen; +{ + return sysctl__string(oldp, oldlenp, newp, newlen, str, maxlen, 1); +} + +int +sysctl__string(oldp, oldlenp, newp, newlen, str, maxlen, trunc) + void *oldp; + size_t *oldlenp; + void *newp; + size_t newlen; + char *str; + int maxlen; + int trunc; +{ int len, error = 0; + char c; len = strlen(str) + 1; - if (oldp && *oldlenp < len) - return (ENOMEM); + if (oldp && *oldlenp < len) { + if (trunc == 0 || *oldlenp == 0) + return (ENOMEM); + } if (newp && newlen >= maxlen) return (EINVAL); if (oldp) { - *oldlenp = len; - error = copyout(str, oldp, len); + if (trunc && *oldlenp < len) { + /* XXX save & zap NUL terminator while copying */ + c = str[*oldlenp-1]; + str[*oldlenp-1] = '\0'; + error = copyout(str, oldp, *oldlenp); + str[*oldlenp-1] = c; + } else { + *oldlenp = len; + error = copyout(str, oldp, len); + } } if (error == 0 && newp) { error = copyin(newp, str, newlen); |