kern_sysctl.c (5204129576334ea59d9a214f848fb841897ca994) kern_sysctl.c (4b2af45f4ba1f8d8d5a56c4b18f29da6d08146e9)
1/*-
2 * Copyright (c) 1982, 1986, 1989, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Mike Karels at Berkeley Software Design, Inc.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 20 unchanged lines hidden (view full) ---

29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 *
36 * @(#)kern_sysctl.c 8.4 (Berkeley) 4/14/94
1/*-
2 * Copyright (c) 1982, 1986, 1989, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Mike Karels at Berkeley Software Design, Inc.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 20 unchanged lines hidden (view full) ---

29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 *
36 * @(#)kern_sysctl.c 8.4 (Berkeley) 4/14/94
37 * $Id: kern_sysctl.c,v 1.50 1995/11/14 20:43:29 phk Exp $
37 * $Id: kern_sysctl.c,v 1.51 1995/11/16 18:59:49 phk Exp $
38 */
39
40/*
41 * sysctl system call.
42 */
43
44#include <sys/param.h>
45#include <sys/systm.h>
46#include <sys/sysproto.h>
47#include <sys/kernel.h>
48#include <sys/vnode.h>
49#include <sys/unistd.h>
50#include <sys/conf.h>
51#include <sys/sysctl.h>
52
38 */
39
40/*
41 * sysctl system call.
42 */
43
44#include <sys/param.h>
45#include <sys/systm.h>
46#include <sys/sysproto.h>
47#include <sys/kernel.h>
48#include <sys/vnode.h>
49#include <sys/unistd.h>
50#include <sys/conf.h>
51#include <sys/sysctl.h>
52
53/*
54 * Locking and stats
55 */
56static struct sysctl_lock {
57 int sl_lock;
58 int sl_want;
59 int sl_locked;
60} memlock;
61
62static int sysctl_root SYSCTL_HANDLER_ARGS;
63
53extern struct linker_set sysctl_;
54
55/* BEGIN_MIB */
56SYSCTL_NODE(, 0, sysctl, CTLFLAG_RW, 0,
57 "Sysctl internal magic");
58SYSCTL_NODE(, CTL_KERN, kern, CTLFLAG_RW, 0,
59 "High kernel, proc, limits &c");
60SYSCTL_NODE(, CTL_VM, vm, CTLFLAG_RW, 0,

--- 79 unchanged lines hidden (view full) ---

140 &vfs_update_interval, 0, sysctl_kern_updateinterval, "");
141
142
143char hostname[MAXHOSTNAMELEN];
144
145SYSCTL_STRING(_kern, KERN_HOSTNAME, hostname, CTLFLAG_RW,
146 hostname, sizeof(hostname), "");
147
64extern struct linker_set sysctl_;
65
66/* BEGIN_MIB */
67SYSCTL_NODE(, 0, sysctl, CTLFLAG_RW, 0,
68 "Sysctl internal magic");
69SYSCTL_NODE(, CTL_KERN, kern, CTLFLAG_RW, 0,
70 "High kernel, proc, limits &c");
71SYSCTL_NODE(, CTL_VM, vm, CTLFLAG_RW, 0,

--- 79 unchanged lines hidden (view full) ---

151 &vfs_update_interval, 0, sysctl_kern_updateinterval, "");
152
153
154char hostname[MAXHOSTNAMELEN];
155
156SYSCTL_STRING(_kern, KERN_HOSTNAME, hostname, CTLFLAG_RW,
157 hostname, sizeof(hostname), "");
158
159int securelevel = -1;
160
148static int
161static int
162sysctl_kern_securelvl SYSCTL_HANDLER_ARGS
163{
164 int error, level;
165
166 level = securelevel;
167 error = sysctl_handle_int(oidp, &level, 0, req);
168 if (error || !req->newptr)
169 return (error);
170 if (level < securelevel && req->p->p_pid != 1)
171 return (EPERM);
172 securelevel = level;
173 return (error);
174}
175
176SYSCTL_PROC(_kern, KERN_SECURELVL, securelevel, CTLTYPE_INT|CTLFLAG_RW,
177 0, 0, sysctl_kern_securelvl, "");
178
179static int
180sysctl_kern_dumpdev SYSCTL_HANDLER_ARGS
181{
182 int error;
183 dev_t ndumpdev;
184
185 ndumpdev = dumpdev;
186 error = sysctl_handle_opaque(oidp, &ndumpdev, sizeof ndumpdev, req);
187 if (!error && ndumpdev != dumpdev) {
188 error = setdumpdev(ndumpdev);
189 }
190 return (error);
191}
192
193SYSCTL_PROC(_kern, KERN_DUMPDEV, dumpdev, CTLTYPE_OPAQUE|CTLFLAG_RW,
194 0, sizeof dumpdev, sysctl_kern_dumpdev, "");
195
196static int
197sysctl_hw_physmem SYSCTL_HANDLER_ARGS
198{
199 int error = sysctl_handle_int(oidp, 0, ctob(physmem), req);
200 return (error);
201}
202
203SYSCTL_PROC(_hw, HW_PHYSMEM, physmem, CTLTYPE_INT|CTLFLAG_RD,
204 0, 0, sysctl_hw_physmem, "");
205
206static int
207sysctl_hw_usermem SYSCTL_HANDLER_ARGS
208{
209 int error = sysctl_handle_int(oidp, 0,
210 ctob(physmem - cnt.v_wire_count), req);
211 return (error);
212}
213
214SYSCTL_PROC(_hw, HW_USERMEM, usermem, CTLTYPE_INT|CTLFLAG_RD,
215 0, 0, sysctl_hw_usermem, "");
216
217/* END_MIB */
218
219static int
149sysctl_order_cmp(const void *a, const void *b)
150{
151 const struct sysctl_oid **pa, **pb;
152
153 pa = (const struct sysctl_oid **)a;
154 pb = (const struct sysctl_oid **)b;
155 if (*pa == NULL)
156 return (1);

--- 208 unchanged lines hidden (view full) ---

365/*
366 * Transfer function to/from user space.
367 */
368static int
369sysctl_old_user(struct sysctl_req *req, void *p, int l)
370{
371 int error = 0, i = 0;
372
220sysctl_order_cmp(const void *a, const void *b)
221{
222 const struct sysctl_oid **pa, **pb;
223
224 pa = (const struct sysctl_oid **)a;
225 pb = (const struct sysctl_oid **)b;
226 if (*pa == NULL)
227 return (1);

--- 208 unchanged lines hidden (view full) ---

436/*
437 * Transfer function to/from user space.
438 */
439static int
440sysctl_old_user(struct sysctl_req *req, void *p, int l)
441{
442 int error = 0, i = 0;
443
444 if (req->lock == 1 && req->oldptr) {
445 vslock(req->oldptr, req->oldlen);
446 req->lock = 2;
447 }
373 if (req->oldptr) {
374 i = min(req->oldlen - req->oldidx, l);
375 if (i > 0)
376 error = copyout(p, req->oldptr + req->oldidx, i);
377 }
378 req->oldidx += l;
379 if (error)
380 return (error);

--- 12 unchanged lines hidden (view full) ---

393 if (req->newlen - req->newidx < l)
394 return (EINVAL);
395 error = copyin(req->newptr + req->newidx, p, l);
396 req->newidx += l;
397 return (error);
398}
399
400/*
448 if (req->oldptr) {
449 i = min(req->oldlen - req->oldidx, l);
450 if (i > 0)
451 error = copyout(p, req->oldptr + req->oldidx, i);
452 }
453 req->oldidx += l;
454 if (error)
455 return (error);

--- 12 unchanged lines hidden (view full) ---

468 if (req->newlen - req->newidx < l)
469 return (EINVAL);
470 error = copyin(req->newptr + req->newidx, p, l);
471 req->newidx += l;
472 return (error);
473}
474
475/*
401 * Locking and stats
402 */
403static struct sysctl_lock {
404 int sl_lock;
405 int sl_want;
406 int sl_locked;
407} memlock;
408
409
410
411/*
412 * Traverse our tree, and find the right node, execute whatever it points
413 * at, and return the resulting error code.
476 * Traverse our tree, and find the right node, execute whatever it points
477 * at, and return the resulting error code.
414 * We work entirely in kernel-space at this time.
415 */
416
478 */
479
417
418int
419sysctl_root SYSCTL_HANDLER_ARGS
420{
421 int *name = (int *) arg1;
422 int namelen = arg2;
423 int indx, i, j;
424 struct sysctl_oid **oidpp;
425 struct linker_set *lsp = &sysctl_;
426
427 j = lsp->ls_length;
428 oidpp = (struct sysctl_oid **) lsp->ls_items;
429
430 indx = 0;
431 while (j-- && indx < CTL_MAXNAME) {
432 if (*oidpp && ((*oidpp)->oid_number == name[indx])) {
433 indx++;
480int
481sysctl_root SYSCTL_HANDLER_ARGS
482{
483 int *name = (int *) arg1;
484 int namelen = arg2;
485 int indx, i, j;
486 struct sysctl_oid **oidpp;
487 struct linker_set *lsp = &sysctl_;
488
489 j = lsp->ls_length;
490 oidpp = (struct sysctl_oid **) lsp->ls_items;
491
492 indx = 0;
493 while (j-- && indx < CTL_MAXNAME) {
494 if (*oidpp && ((*oidpp)->oid_number == name[indx])) {
495 indx++;
496 if ((*oidpp)->oid_kind & CTLFLAG_NOLOCK)
497 req->lock = 0;
434 if (((*oidpp)->oid_kind & CTLTYPE) == CTLTYPE_NODE) {
435 if ((*oidpp)->oid_handler)
436 goto found;
437 if (indx == namelen)
438 return ENOENT;
439 lsp = (struct linker_set*)(*oidpp)->oid_arg1;
440 j = lsp->ls_length;
441 oidpp = (struct sysctl_oid **)lsp->ls_items;

--- 35 unchanged lines hidden (view full) ---

477 void *old;
478 size_t *oldlenp;
479 void *new;
480 size_t newlen;
481};
482#endif
483
484int
498 if (((*oidpp)->oid_kind & CTLTYPE) == CTLTYPE_NODE) {
499 if ((*oidpp)->oid_handler)
500 goto found;
501 if (indx == namelen)
502 return ENOENT;
503 lsp = (struct linker_set*)(*oidpp)->oid_arg1;
504 j = lsp->ls_length;
505 oidpp = (struct sysctl_oid **)lsp->ls_items;

--- 35 unchanged lines hidden (view full) ---

541 void *old;
542 size_t *oldlenp;
543 void *new;
544 size_t newlen;
545};
546#endif
547
548int
485__sysctl(p, uap, retval)
486 struct proc *p;
487 register struct sysctl_args *uap;
488 int *retval;
549__sysctl(struct proc *p, struct sysctl_args *uap, int *retval)
489{
490 int error, i, j, name[CTL_MAXNAME];
491
492 if (uap->namelen > CTL_MAXNAME || uap->namelen < 2)
493 return (EINVAL);
494
495 error = copyin(uap->name, &name, uap->namelen * sizeof(int));
496 if (error)

--- 7 unchanged lines hidden (view full) ---

504 if (uap->oldlenp) {
505 i = copyout(&j, uap->oldlenp, sizeof(j));
506 if (i)
507 return (i);
508 }
509 return (error);
510}
511
550{
551 int error, i, j, name[CTL_MAXNAME];
552
553 if (uap->namelen > CTL_MAXNAME || uap->namelen < 2)
554 return (EINVAL);
555
556 error = copyin(uap->name, &name, uap->namelen * sizeof(int));
557 if (error)

--- 7 unchanged lines hidden (view full) ---

565 if (uap->oldlenp) {
566 i = copyout(&j, uap->oldlenp, sizeof(j));
567 if (i)
568 return (i);
569 }
570 return (error);
571}
572
512static sysctlfn kern_sysctl;
513
514/*
515 * This is used from various compatibility syscalls too. That's why name
516 * must be in kernel space.
517 */
518int
519userland_sysctl(struct proc *p, int *name, u_int namelen, void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen, int *retval)
520{
573/*
574 * This is used from various compatibility syscalls too. That's why name
575 * must be in kernel space.
576 */
577int
578userland_sysctl(struct proc *p, int *name, u_int namelen, void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen, int *retval)
579{
521 int error = 0, dolock = 1, oldlen = 0;
522 u_int savelen = 0;
523 sysctlfn *fn;
580 int error = 0;
524 struct sysctl_req req;
525
526 bzero(&req, sizeof req);
527
528 req.p = p;
529
530 if (new != NULL && (error = suser(p->p_ucred, &p->p_acflag)))
531 return (error);

--- 18 unchanged lines hidden (view full) ---

550 if (!useracc(new, req.newlen, B_READ))
551 return (EFAULT);
552 req.newlen = newlen;
553 req.newptr = new;
554 }
555
556 req.oldfunc = sysctl_old_user;
557 req.newfunc = sysctl_new_user;
581 struct sysctl_req req;
582
583 bzero(&req, sizeof req);
584
585 req.p = p;
586
587 if (new != NULL && (error = suser(p->p_ucred, &p->p_acflag)))
588 return (error);

--- 18 unchanged lines hidden (view full) ---

607 if (!useracc(new, req.newlen, B_READ))
608 return (EFAULT);
609 req.newlen = newlen;
610 req.newptr = new;
611 }
612
613 req.oldfunc = sysctl_old_user;
614 req.newfunc = sysctl_new_user;
615 req.lock = 1;
558
616
617 /* XXX this should probably be done in a general way */
618 while (memlock.sl_lock) {
619 memlock.sl_want = 1;
620 (void) tsleep((caddr_t)&memlock, PRIBIO+1, "sysctl", 0);
621 memlock.sl_locked++;
622 }
623 memlock.sl_lock = 1;
624
559 error = sysctl_root(0, name, namelen, &req);
560
625 error = sysctl_root(0, name, namelen, &req);
626
561/*
627 if (req.lock == 2)
628 vsunlock(req.oldptr, req.oldlen, B_WRITE);
629
630 memlock.sl_lock = 0;
631
632 if (memlock.sl_want) {
633 memlock.sl_want = 0;
634 wakeup((caddr_t)&memlock);
635 }
636
562 if (error && error != ENOMEM)
563 return (error);
637 if (error && error != ENOMEM)
638 return (error);
564*/
565 if (error == ENOENT)
566 goto oldstuff;
567
568 if (retval) {
569 if (req.oldptr && req.oldidx > req.oldlen)
570 *retval = req.oldlen;
571 else
572 *retval = req.oldidx;
573 }
574 return (error);
639
640 if (retval) {
641 if (req.oldptr && req.oldidx > req.oldlen)
642 *retval = req.oldlen;
643 else
644 *retval = req.oldidx;
645 }
646 return (error);
575
576oldstuff:
577 oldlen = req.oldlen;
578
579 switch (name[0]) {
580 case CTL_KERN:
581 fn = kern_sysctl;
582 if (name[1] != KERN_VNODE) /* XXX */
583 dolock = 0;
584 break;
585 case CTL_HW:
586 fn = hw_sysctl;
587 break;
588 case CTL_FS:
589 fn = fs_sysctl;
590 break;
591 default:
592 return (EOPNOTSUPP);
593 }
594 if (old != NULL) {
595 if (!useracc(old, oldlen, B_WRITE))
596 return (EFAULT);
597 while (memlock.sl_lock) {
598 memlock.sl_want = 1;
599 (void) tsleep((caddr_t)&memlock, PRIBIO+1, "sysctl", 0);
600 memlock.sl_locked++;
601 }
602 memlock.sl_lock = 1;
603 if (dolock)
604 vslock(old, oldlen);
605 savelen = oldlen;
606 }
607
608
609 error = (*fn)(name + 1, namelen - 1, old, &oldlen,
610 new, newlen, p);
611
612
613 if (old != NULL) {
614 if (dolock)
615 vsunlock(old, savelen, B_WRITE);
616 memlock.sl_lock = 0;
617 if (memlock.sl_want) {
618 memlock.sl_want = 0;
619 wakeup((caddr_t)&memlock);
620 }
621 }
622#if 0
623 if (error) {
624 printf("SYSCTL_ERROR: ");
625 for(i=0;i<namelen;i++)
626 printf("%d ", name[i]);
627 printf("= %d\n", error);
628 }
629#endif
630 if (error)
631 return (error);
632 if (retval)
633 *retval = oldlen;
634 return (error);
635}
636
647}
648
637/*
638 * Attributes stored in the kernel.
639 */
640int securelevel = -1;
641
642/*
643 * kernel related system variables.
644 */
645static int
646kern_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
647 int *name;
648 u_int namelen;
649 void *oldp;
650 size_t *oldlenp;
651 void *newp;
652 size_t newlen;
653 struct proc *p;
654{
655
656 /* all sysctl names at this level are terminal */
657 if (namelen != 1 && !(name[0] == KERN_PROC || name[0] == KERN_PROF
658 || name[0] == KERN_NTP_PLL))
659 return (ENOTDIR); /* overloaded */
660
661 switch (name[0]) {
662
663 case KERN_VNODE:
664 return (sysctl_vnode(oldp, oldlenp));
665#ifdef GPROF
666 case KERN_PROF:
667 return (sysctl_doprof(name + 1, namelen - 1, oldp, oldlenp,
668 newp, newlen));
669#endif
670 default:
671 return (EOPNOTSUPP);
672 }
673 /* NOTREACHED */
674}
675
676static int
677sysctl_kern_securelvl SYSCTL_HANDLER_ARGS
678{
679 int error, level;
680
681 level = securelevel;
682 error = sysctl_handle_int(oidp, &level, 0, req);
683 if (error || !req->newptr)
684 return (error);
685 if (level < securelevel && req->p->p_pid != 1)
686 return (EPERM);
687 securelevel = level;
688 return (error);
689}
690
691SYSCTL_PROC(_kern, KERN_SECURELVL, securelevel, CTLTYPE_INT|CTLFLAG_RW,
692 0, 0, sysctl_kern_securelvl, "");
693
694static int
695sysctl_kern_dumpdev SYSCTL_HANDLER_ARGS
696{
697 int error;
698 dev_t ndumpdev;
699
700 ndumpdev = dumpdev;
701 error = sysctl_handle_opaque(oidp, &ndumpdev, sizeof ndumpdev, req);
702 if (!error && ndumpdev != dumpdev) {
703 error = setdumpdev(ndumpdev);
704 }
705 return (error);
706}
707
708SYSCTL_PROC(_kern, KERN_DUMPDEV, dumpdev, CTLTYPE_OPAQUE|CTLFLAG_RW,
709 0, sizeof dumpdev, sysctl_kern_dumpdev, "");
710/*
711 * hardware related system variables.
712 */
713int
714hw_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
715 int *name;
716 u_int namelen;
717 void *oldp;
718 size_t *oldlenp;
719 void *newp;
720 size_t newlen;
721 struct proc *p;
722{
723 /* almost all sysctl names at this level are terminal */
724 if (namelen != 1 && name[0] != HW_DEVCONF)
725 return (ENOTDIR); /* overloaded */
726
727 switch (name[0]) {
728 case HW_PHYSMEM:
729 return (sysctl_rdint(oldp, oldlenp, newp, ctob(physmem)));
730 case HW_USERMEM:
731 return (sysctl_rdint(oldp, oldlenp, newp,
732 ctob(physmem - cnt.v_wire_count)));
733 case HW_DEVCONF:
734 return (dev_sysctl(name + 1, namelen - 1, oldp, oldlenp,
735 newp, newlen, p));
736 default:
737 return (EOPNOTSUPP);
738 }
739 /* NOTREACHED */
740}
741
742/*
743 * Validate parameters and get old / set new parameters
744 * for an integer-valued sysctl function.
745 */
746int
747sysctl_int(oldp, oldlenp, newp, newlen, valp)
748 void *oldp;
749 size_t *oldlenp;
750 void *newp;
751 size_t newlen;
752 int *valp;
753{
754 int error = 0;
755
756 if (oldp && *oldlenp < sizeof(int))
757 return (ENOMEM);
758 if (newp && newlen != sizeof(int))
759 return (EINVAL);
760 *oldlenp = sizeof(int);
761 if (oldp)
762 error = copyout(valp, oldp, sizeof(int));
763 if (error == 0 && newp)
764 error = copyin(newp, valp, sizeof(int));
765 return (error);
766}
767
768/*
769 * As above, but read-only.
770 */
771int
772sysctl_rdint(oldp, oldlenp, newp, val)
773 void *oldp;
774 size_t *oldlenp;
775 void *newp;
776 int val;
777{
778 int error = 0;
779
780 if (oldp && *oldlenp < sizeof(int))
781 return (ENOMEM);
782 if (newp)
783 return (EPERM);
784 *oldlenp = sizeof(int);
785 if (oldp)
786 error = copyout((caddr_t)&val, oldp, sizeof(int));
787 return (error);
788}
789
790/*
791 * Validate parameters and get old / set new parameters
792 * for a string-valued sysctl function.
793 */
794int
795sysctl_string(oldp, oldlenp, newp, newlen, str, maxlen)
796 void *oldp;
797 size_t *oldlenp;
798 void *newp;
799 size_t newlen;
800 char *str;
801 int maxlen;
802{
803 int len, error = 0, rval = 0;
804
805 len = strlen(str) + 1;
806 if (oldp && *oldlenp < len) {
807 len = *oldlenp;
808 rval = ENOMEM;
809 }
810 if (newp && newlen >= maxlen)
811 return (EINVAL);
812 if (oldp) {
813 *oldlenp = len;
814 error = copyout(str, oldp, len);
815 if (error)
816 rval = error;
817 }
818 if ((error == 0 || error == ENOMEM) && newp) {
819 error = copyin(newp, str, newlen);
820 if (error)
821 rval = error;
822 str[newlen] = 0;
823 }
824 return (rval);
825}
826
827/*
828 * As above, but read-only.
829 */
830int
831sysctl_rdstring(oldp, oldlenp, newp, str)
832 void *oldp;
833 size_t *oldlenp;
834 void *newp;
835 char *str;
836{
837 int len, error = 0, rval = 0;
838
839 len = strlen(str) + 1;
840 if (oldp && *oldlenp < len) {
841 len = *oldlenp;
842 rval = ENOMEM;
843 }
844 if (newp)
845 return (EPERM);
846 *oldlenp = len;
847 if (oldp)
848 error = copyout(str, oldp, len);
849 if (error)
850 rval = error;
851 return (rval);
852}
853
854/*
855 * Validate parameters and get old / set new parameters
856 * for a structure oriented sysctl function.
857 */
858int
859sysctl_struct(oldp, oldlenp, newp, newlen, sp, len)
860 void *oldp;
861 size_t *oldlenp;
862 void *newp;
863 size_t newlen;
864 void *sp;
865 int len;
866{
867 int error = 0;
868
869 if (oldp && *oldlenp < len)
870 return (ENOMEM);
871 if (newp && newlen > len)
872 return (EINVAL);
873 if (oldp) {
874 *oldlenp = len;
875 error = copyout(sp, oldp, len);
876 }
877 if (error == 0 && newp)
878 error = copyin(newp, sp, len);
879 return (error);
880}
881
882/*
883 * Validate parameters and get old parameters
884 * for a structure oriented sysctl function.
885 */
886int
887sysctl_rdstruct(oldp, oldlenp, newp, sp, len)
888 void *oldp;
889 size_t *oldlenp;
890 void *newp, *sp;
891 int len;
892{
893 int error = 0;
894
895 if (oldp && *oldlenp < len)
896 return (ENOMEM);
897 if (newp)
898 return (EPERM);
899 *oldlenp = len;
900 if (oldp)
901 error = copyout(sp, oldp, len);
902 return (error);
903}
904
905#ifdef COMPAT_43
906#include <sys/socket.h>
907#define KINFO_PROC (0<<8)
908#define KINFO_RT (1<<8)
909#define KINFO_VNODE (2<<8)
910#define KINFO_FILE (3<<8)
911#define KINFO_METER (4<<8)
912#define KINFO_LOADAVG (5<<8)

--- 51 unchanged lines hidden (view full) ---

964 int op;
965 char *where;
966 int *size;
967 int arg;
968};
969#endif
970
971int
649#ifdef COMPAT_43
650#include <sys/socket.h>
651#define KINFO_PROC (0<<8)
652#define KINFO_RT (1<<8)
653#define KINFO_VNODE (2<<8)
654#define KINFO_FILE (3<<8)
655#define KINFO_METER (4<<8)
656#define KINFO_LOADAVG (5<<8)

--- 51 unchanged lines hidden (view full) ---

708 int op;
709 char *where;
710 int *size;
711 int arg;
712};
713#endif
714
715int
972ogetkerninfo(p, uap, retval)
973 struct proc *p;
974 register struct getkerninfo_args *uap;
975 int *retval;
716ogetkerninfo(struct proc *p, struct getkerninfo_args *uap, int *retval)
976{
977 int error, name[6];
978 u_int size;
979
980 switch (uap->op & 0xff00) {
981
982 case KINFO_RT:
983 name[0] = CTL_NET;
984 name[1] = PF_ROUTE;
985 name[2] = 0;
986 name[3] = (uap->op & 0xff0000) >> 16;
987 name[4] = uap->op & 0xff;
988 name[5] = uap->arg;
989 error = userland_sysctl(p, name, 6, uap->where, uap->size,
717{
718 int error, name[6];
719 u_int size;
720
721 switch (uap->op & 0xff00) {
722
723 case KINFO_RT:
724 name[0] = CTL_NET;
725 name[1] = PF_ROUTE;
726 name[2] = 0;
727 name[3] = (uap->op & 0xff0000) >> 16;
728 name[4] = uap->op & 0xff;
729 name[5] = uap->arg;
730 error = userland_sysctl(p, name, 6, uap->where, uap->size,
990 0, 0, 0, 0);
731 0, 0, 0, &size);
991 break;
992
993 case KINFO_VNODE:
994 name[0] = CTL_KERN;
995 name[1] = KERN_VNODE;
996 error = userland_sysctl(p, name, 2, uap->where, uap->size,
732 break;
733
734 case KINFO_VNODE:
735 name[0] = CTL_KERN;
736 name[1] = KERN_VNODE;
737 error = userland_sysctl(p, name, 2, uap->where, uap->size,
997 0, 0, 0, 0);
738 0, 0, 0, &size);
998 break;
999
1000 case KINFO_PROC:
1001 name[0] = CTL_KERN;
1002 name[1] = KERN_PROC;
1003 name[2] = uap->op & 0xff;
1004 name[3] = uap->arg;
1005 error = userland_sysctl(p, name, 4, uap->where, uap->size,
739 break;
740
741 case KINFO_PROC:
742 name[0] = CTL_KERN;
743 name[1] = KERN_PROC;
744 name[2] = uap->op & 0xff;
745 name[3] = uap->arg;
746 error = userland_sysctl(p, name, 4, uap->where, uap->size,
1006 0, 0, 0, 0);
747 0, 0, 0, &size);
1007 break;
1008
1009 case KINFO_FILE:
1010 name[0] = CTL_KERN;
1011 name[1] = KERN_FILE;
1012 error = userland_sysctl(p, name, 2, uap->where, uap->size,
748 break;
749
750 case KINFO_FILE:
751 name[0] = CTL_KERN;
752 name[1] = KERN_FILE;
753 error = userland_sysctl(p, name, 2, uap->where, uap->size,
1013 0, 0, 0, 0);
754 0, 0, 0, &size);
1014 break;
1015
1016 case KINFO_METER:
1017 name[0] = CTL_VM;
1018 name[1] = VM_METER;
1019 error = userland_sysctl(p, name, 2, uap->where, uap->size,
755 break;
756
757 case KINFO_METER:
758 name[0] = CTL_VM;
759 name[1] = VM_METER;
760 error = userland_sysctl(p, name, 2, uap->where, uap->size,
1020 0, 0, 0, 0);
761 0, 0, 0, &size);
1021 break;
1022
1023 case KINFO_LOADAVG:
1024 name[0] = CTL_VM;
1025 name[1] = VM_LOADAVG;
1026 error = userland_sysctl(p, name, 2, uap->where, uap->size,
762 break;
763
764 case KINFO_LOADAVG:
765 name[0] = CTL_VM;
766 name[1] = VM_LOADAVG;
767 error = userland_sysctl(p, name, 2, uap->where, uap->size,
1027 0, 0, 0, 0);
768 0, 0, 0, &size);
1028 break;
1029
1030 case KINFO_CLOCKRATE:
1031 name[0] = CTL_KERN;
1032 name[1] = KERN_CLOCKRATE;
1033 error = userland_sysctl(p, name, 2, uap->where, uap->size,
769 break;
770
771 case KINFO_CLOCKRATE:
772 name[0] = CTL_KERN;
773 name[1] = KERN_CLOCKRATE;
774 error = userland_sysctl(p, name, 2, uap->where, uap->size,
1034 0, 0, 0, 0);
775 0, 0, 0, &size);
1035 break;
1036
1037 case KINFO_BSDI_SYSINFO: {
1038 /*
1039 * this is pretty crude, but it's just enough for uname()
1040 * from BSDI's 1.x libc to work.
1041 *
1042 * In particular, it doesn't return the same results when

--- 70 unchanged lines hidden ---
776 break;
777
778 case KINFO_BSDI_SYSINFO: {
779 /*
780 * this is pretty crude, but it's just enough for uname()
781 * from BSDI's 1.x libc to work.
782 *
783 * In particular, it doesn't return the same results when

--- 70 unchanged lines hidden ---