Subject: Re: gethostname and getdomainname
To: Christos Zoulas <christos@zoulas.com>
From: Ignatios Souvatzis <is@jocelyn.rhein.de>
List: tech-userlevel
Date: 11/17/1999 23:36:47
--u3/rZRmxL6MmkK24
Content-Type: text/plain; charset=us-ascii
Hi,
here is my new kern_sysctl.c diff for review.
I'm running a kernel with this right now, so it can't be too bad.
To summarize, changes from old:
- strings handled by the common functions sysctl_string() and sysctl_rdstring()
are handled as arrays; that is, a truncated old value is returned, alongside
with ENOMEM, if the buffer is too small.
- in all int, quad, and single struct cases, and all specials handled inside
this file, oldlenp semantics are now as documented in the manual page, that
is, a NULL oldp, but non-NULL oldlenp returns the needed size
[I had to change the oldlenp handling, so I thought I should make it as
advertized. Formerly, the subroutines would not know when a NULL oldlenp
was passed, do the work anyway, and the value would be thrown away.]
Regards,
Ignatios
--u3/rZRmxL6MmkK24
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="kern_sysctl.c.diffs"
--- kern_sysctl.c.orig Wed Nov 17 23:14:20 1999
+++ kern_sysctl.c Wed Nov 17 23:01:07 1999
@@ -104,6 +104,7 @@
size_t savelen = 0, oldlen = 0;
sysctlfn *fn;
int name[CTL_MAXNAME];
+ size_t *koldlenp;
/*
* all top-level sysctl names are non-terminal
@@ -162,9 +163,12 @@
return (EOPNOTSUPP);
}
- if (SCARG(uap, oldlenp) &&
- (error = copyin(SCARG(uap, oldlenp), &oldlen, sizeof(oldlen))))
- return (error);
+ koldlenp = SCARG(uap, oldlenp);
+ if (koldlenp) {
+ if ((error = copyin(koldlenp, &oldlen, sizeof(oldlen))))
+ return (error);
+ koldlenp = &oldlen;
+ }
if (SCARG(uap, old) != NULL) {
if (!uvm_useracc(SCARG(uap, old), oldlen, B_WRITE))
return (EFAULT);
@@ -192,7 +196,7 @@
savelen = oldlen;
}
error = (*fn)(name + 1, SCARG(uap, namelen) - 1, SCARG(uap, old),
- &oldlen, SCARG(uap, new), SCARG(uap, newlen), p);
+ koldlenp, SCARG(uap, new), SCARG(uap, newlen), p);
if (SCARG(uap, old) != NULL) {
if (dolock)
uvm_vsunlock(p, SCARG(uap, old), savelen);
@@ -574,8 +578,11 @@
* area during the process, so we have to do it by hand.
*/
curlen = strlen(ptmp->p_limit->pl_corename) + 1;
- if (oldp && *oldlenp < curlen)
+ if (oldlenp && *oldlenp < curlen) {
+ if (!oldp)
+ *oldlenp = curlen;
return (ENOMEM);
+ }
if (newp) {
if (securelevel > 2)
return EPERM;
@@ -606,7 +613,7 @@
goto cleanup;
}
}
- if (oldp) {
+ if (oldp && oldlenp) {
*oldlenp = curlen;
error = copyout(ptmp->p_limit->pl_corename, oldp,
curlen);
@@ -658,6 +665,39 @@
}
/*
+ * Convenience macros.
+ */
+
+#define SYSCTL_SCALAR_CORE_LEN(oldp, oldlenp, valp, len) \
+ if (oldlenp) { \
+ if (!oldp) \
+ *oldlenp = len; \
+ else { \
+ if (*oldlenp < len) \
+ return(ENOMEM); \
+ *oldlenp = len; \
+ error = copyout((caddr_t)valp, oldp, len); \
+ } \
+ }
+
+#define SYSCTL_SCALAR_CORE_TYP(oldp, oldlenp, valp, typ) \
+ SYSCTL_SCALAR_CORE_LEN(oldp, oldlenp, valp, sizeof(typ))
+
+#define SYSCTL_SCALAR_NEWPCHECK_LEN(newp, newlen, len) \
+ if (newp && newlen != len) \
+ return (EINVAL);
+
+#define SYSCTL_SCALAR_NEWPCHECK_TYP(newp, newlen, typ) \
+ SYSCTL_SCALAR_NEWPCHECK_LEN(newp, newlen, sizeof(typ))
+
+#define SYSCTL_SCALAR_NEWPCOP_LEN(newp, valp, len) \
+ if (error == 0 && newp) \
+ error = copyin(newp, valp, len);
+
+#define SYSCTL_SCALAR_NEWPCOP_TYP(newp, valp, typ) \
+ SYSCTL_SCALAR_NEWPCOP_LEN(newp, valp, sizeof(typ))
+
+/*
* Validate parameters and get old / set new parameters
* for an integer-valued sysctl function.
*/
@@ -671,18 +711,14 @@
{
int error = 0;
- if (oldp && *oldlenp < sizeof(int))
- return (ENOMEM);
- if (newp && newlen != sizeof(int))
- return (EINVAL);
- *oldlenp = sizeof(int);
- if (oldp)
- error = copyout(valp, oldp, sizeof(int));
- if (error == 0 && newp)
- error = copyin(newp, valp, sizeof(int));
+ SYSCTL_SCALAR_NEWPCHECK_TYP(newp, newlen, int)
+ SYSCTL_SCALAR_CORE_TYP(oldp, oldlenp, valp, int)
+ SYSCTL_SCALAR_NEWPCOP_TYP(newp, valp, int)
+
return (error);
}
+
/*
* As above, but read-only.
*/
@@ -695,13 +731,11 @@
{
int error = 0;
- if (oldp && *oldlenp < sizeof(int))
- return (ENOMEM);
if (newp)
return (EPERM);
- *oldlenp = sizeof(int);
- if (oldp)
- error = copyout((caddr_t)&val, oldp, sizeof(int));
+
+ SYSCTL_SCALAR_CORE_TYP(oldp, oldlenp, &val, int)
+
return (error);
}
@@ -719,15 +753,10 @@
{
int error = 0;
- if (oldp && *oldlenp < sizeof(quad_t))
- return (ENOMEM);
- if (newp && newlen != sizeof(quad_t))
- return (EINVAL);
- *oldlenp = sizeof(quad_t);
- if (oldp)
- error = copyout(valp, oldp, sizeof(quad_t));
- if (error == 0 && newp)
- error = copyin(newp, valp, sizeof(quad_t));
+ SYSCTL_SCALAR_NEWPCHECK_TYP(newp, newlen, quad_t)
+ SYSCTL_SCALAR_CORE_TYP(oldp, oldlenp, valp, quad_t)
+ SYSCTL_SCALAR_NEWPCOP_TYP(newp, valp, quad_t)
+
return (error);
}
@@ -743,16 +772,30 @@
{
int error = 0;
- if (oldp && *oldlenp < sizeof(quad_t))
- return (ENOMEM);
if (newp)
return (EPERM);
- *oldlenp = sizeof(quad_t);
- if (oldp)
- error = copyout((caddr_t)&val, oldp, sizeof(quad_t));
+
+ SYSCTL_SCALAR_CORE_TYP(oldp, oldlenp, &val, quad_t)
+
return (error);
}
+#define SYSCTL_STRING_CORE(oldp, oldlenp, str) \
+ if (oldlenp) { \
+ len = strlen(str) + 1; \
+ if (!oldp) \
+ *oldlenp = len; \
+ else { \
+ if (*oldlenp < len) { \
+ err2 = ENOMEM; \
+ len = *oldlenp; \
+ } else \
+ *oldlenp = len; \
+ error = copyout(str, oldp, len);\
+ if (error == 0) \
+ error = err2; \
+ } \
+ }
/*
* Validate parameters and get old / set new parameters
@@ -767,16 +810,13 @@
char *str;
int maxlen;
{
- int len, error = 0;
+ int len, error = 0, err2 = 0;
- len = strlen(str) + 1;
- if (oldp && *oldlenp < len)
- return (ENOMEM);
if (newp && newlen >= maxlen)
return (EINVAL);
- *oldlenp = len;
- if (oldp)
- error = copyout(str, oldp, len);
+
+ SYSCTL_STRING_CORE(oldp, oldlenp, str);
+
if (error == 0 && newp) {
error = copyin(newp, str, newlen);
str[newlen] = 0;
@@ -794,16 +834,13 @@
void *newp;
char *str;
{
- int len, error = 0;
+ int len, error = 0, err2 = 0;
- len = strlen(str) + 1;
- if (oldp && *oldlenp < len)
- return (ENOMEM);
if (newp)
return (EPERM);
- *oldlenp = len;
- if (oldp)
- error = copyout(str, oldp, len);
+
+ SYSCTL_STRING_CORE(oldp, oldlenp, str);
+
return (error);
}
@@ -822,16 +859,10 @@
{
int error = 0;
- if (oldp && *oldlenp < len)
- return (ENOMEM);
- if (newp && newlen > len)
- return (EINVAL);
- if (oldp) {
- *oldlenp = len;
- error = copyout(sp, oldp, len);
- }
- if (error == 0 && newp)
- error = copyin(newp, sp, len);
+ SYSCTL_SCALAR_NEWPCHECK_LEN(newp, newlen, len)
+ SYSCTL_SCALAR_CORE_LEN(oldp, oldlenp, sp, len)
+ SYSCTL_SCALAR_NEWPCOP_LEN(newp, sp, len)
+
return (error);
}
@@ -848,13 +879,11 @@
{
int error = 0;
- if (oldp && *oldlenp < len)
- return (ENOMEM);
if (newp)
return (EPERM);
- *oldlenp = len;
- if (oldp)
- error = copyout(sp, oldp, len);
+
+ SYSCTL_SCALAR_CORE_LEN(oldp, oldlenp, sp, len)
+
return (error);
}
--u3/rZRmxL6MmkK24--