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 --- |