summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_environment.c
diff options
context:
space:
mode:
authordas <das@FreeBSD.org>2004-04-28 01:27:33 +0000
committerdas <das@FreeBSD.org>2004-04-28 01:27:33 +0000
commit9df402daa402e2e21ffef311a8c008dc0981c94f (patch)
treee790e511554fc7818e15e46d99819f32e123ed9c /sys/kern/kern_environment.c
parent45c4ca11d3df1082a4c95dd15e54bcfdd7bb40ee (diff)
downloadFreeBSD-src-9df402daa402e2e21ffef311a8c008dc0981c94f.zip
FreeBSD-src-9df402daa402e2e21ffef311a8c008dc0981c94f.tar.gz
If the buffer supplied to kenv(KENV_DUMP, ...) isn't big enough,
return the number of bytes needed instead of 0. The manpage claims that we do this anyway.
Diffstat (limited to 'sys/kern/kern_environment.c')
-rw-r--r--sys/kern/kern_environment.c39
1 files changed, 18 insertions, 21 deletions
diff --git a/sys/kern/kern_environment.c b/sys/kern/kern_environment.c
index 9511c90..96b57d9 100644
--- a/sys/kern/kern_environment.c
+++ b/sys/kern/kern_environment.c
@@ -87,7 +87,7 @@ kenv(td, uap)
} */ *uap;
{
char *name, *value;
- size_t len, done;
+ size_t len, done, needed;
int error, i;
KASSERT(dynamic_kenv, ("kenv: dynamic_kenv = 0"));
@@ -99,30 +99,27 @@ kenv(td, uap)
if (error)
return (error);
#endif
- len = 0;
- /* Return the size if called with a NULL buffer */
- if (uap->value == NULL) {
- sx_slock(&kenv_lock);
- for (i = 0; kenvp[i] != NULL; i++)
- len += strlen(kenvp[i]) + 1;
- sx_sunlock(&kenv_lock);
- td->td_retval[0] = len;
- return (0);
- }
- done = 0;
+ done = needed = 0;
sx_slock(&kenv_lock);
- for (i = 0; kenvp[i] != NULL && done < uap->len; i++) {
- len = min(strlen(kenvp[i]) + 1, uap->len - done);
- error = copyout(kenvp[i], uap->value + done,
- len);
- if (error) {
- sx_sunlock(&kenv_lock);
- return (error);
+ for (i = 0; kenvp[i] != NULL; i++) {
+ len = strlen(kenvp[i]) + 1;
+ needed += len;
+ len = min(len, uap->len - done);
+ /*
+ * If called with a NULL or insufficiently large
+ * buffer, just keep computing the required size.
+ */
+ if (uap->value != NULL && len > 0) {
+ error = copyout(kenvp[i], uap->value + done,
+ len);
+ if (error)
+ break;
+ done += len;
}
- done += len;
}
sx_sunlock(&kenv_lock);
- return (0);
+ td->td_retval[0] = ((done == needed) ? 0 : needed);
+ return (error);
}
if ((uap->what == KENV_SET) ||
OpenPOWER on IntegriCloud