kern_conf.c (b17f9ad2c9da34e8544d02c3d530fe9fb41fdbe2) | kern_conf.c (68f7a0139232f7ab92e2b10edf578342a50e0c8a) |
---|---|
1/*- 2 * Copyright (c) 1999-2002 Poul-Henning Kamp 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 668 unchanged lines hidden (view full) --- 677 devsw->d_flags |= D_INIT; 678 679 if (dsw2 != NULL) 680 cdevsw_free_devlocked(dsw2); 681 return (0); 682} 683 684static int | 1/*- 2 * Copyright (c) 1999-2002 Poul-Henning Kamp 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 668 unchanged lines hidden (view full) --- 677 devsw->d_flags |= D_INIT; 678 679 if (dsw2 != NULL) 680 cdevsw_free_devlocked(dsw2); 681 return (0); 682} 683 684static int |
685prep_devname(struct cdev *dev, const char *fmt, va_list ap) 686{ 687 int len; 688 char *from, *q, *s, *to; 689 690 mtx_assert(&devmtx, MA_OWNED); 691 692 len = vsnrprintf(dev->__si_namebuf, sizeof(dev->__si_namebuf), 32, 693 fmt, ap); 694 if (len > sizeof(dev->__si_namebuf) - 1) 695 return (ENAMETOOLONG); 696 697 /* Strip leading slashes. */ 698 for (from = dev->__si_namebuf; *from == '/'; from++) 699 ; 700 701 for (to = dev->__si_namebuf; *from != '\0'; from++, to++) { 702 /* Treat multiple sequential slashes as single. */ 703 while (from[0] == '/' && from[1] == '/') 704 from++; 705 /* Trailing slash is considered invalid. */ 706 if (from[0] == '/' && from[1] == '\0') 707 return (EINVAL); 708 *to = *from; 709 } 710 *to = '\0'; 711 712 if (dev->__si_namebuf[0] == '\0') 713 return (EINVAL); 714 715 /* Disallow "." and ".." components. */ 716 for (s = dev->__si_namebuf;;) { 717 for (q = s; *q != '/' && *q != '\0'; q++) 718 ; 719 if (q - s == 1 && s[0] == '.') 720 return (EINVAL); 721 if (q - s == 2 && s[0] == '.' && s[1] == '.') 722 return (EINVAL); 723 if (*q != '/') 724 break; 725 s = q + 1; 726 } 727 728 if (devfs_dev_exists(dev->__si_namebuf) != 0) 729 return (EEXIST); 730 731 return (0); 732} 733 734static int |
|
685make_dev_credv(int flags, struct cdev **dres, struct cdevsw *devsw, int unit, 686 struct ucred *cr, uid_t uid, gid_t gid, int mode, const char *fmt, 687 va_list ap) 688{ | 735make_dev_credv(int flags, struct cdev **dres, struct cdevsw *devsw, int unit, 736 struct ucred *cr, uid_t uid, gid_t gid, int mode, const char *fmt, 737 va_list ap) 738{ |
689 struct cdev *dev; 690 int i, res; | 739 struct cdev *dev, *dev_new; 740 int res; |
691 692 KASSERT((flags & MAKEDEV_WAITOK) == 0 || (flags & MAKEDEV_NOWAIT) == 0, 693 ("make_dev_credv: both WAITOK and NOWAIT specified")); | 741 742 KASSERT((flags & MAKEDEV_WAITOK) == 0 || (flags & MAKEDEV_NOWAIT) == 0, 743 ("make_dev_credv: both WAITOK and NOWAIT specified")); |
694 dev = devfs_alloc(flags); 695 if (dev == NULL) | 744 dev_new = devfs_alloc(flags); 745 if (dev_new == NULL) |
696 return (ENOMEM); 697 dev_lock(); 698 res = prep_cdevsw(devsw, flags); 699 if (res != 0) { 700 dev_unlock(); | 746 return (ENOMEM); 747 dev_lock(); 748 res = prep_cdevsw(devsw, flags); 749 if (res != 0) { 750 dev_unlock(); |
701 devfs_free(dev); | 751 devfs_free(dev_new); |
702 return (res); 703 } | 752 return (res); 753 } |
704 dev = newdev(devsw, unit, dev); | 754 dev = newdev(devsw, unit, dev_new); 755 if ((dev->si_flags & SI_NAMED) == 0) 756 res = prep_devname(dev, fmt, ap); 757 if (res != 0) { 758 if ((flags & MAKEDEV_CHECKNAME) == 0) { 759 panic( 760 "make_dev_credv: bad si_name (error=%d, si_name=%s)", 761 res, dev->si_name); 762 } 763 if (dev == dev_new) { 764 LIST_REMOVE(dev, si_list); 765 dev_unlock(); 766 devfs_free(dev); 767 } 768 return (res); 769 } |
705 if (flags & MAKEDEV_REF) 706 dev_refl(dev); 707 if (flags & MAKEDEV_ETERNAL) 708 dev->si_flags |= SI_ETERNAL; 709 if (dev->si_flags & SI_CHEAPCLONE && 710 dev->si_flags & SI_NAMED) { 711 /* 712 * This is allowed as it removes races and generally 713 * simplifies cloning devices. 714 * XXX: still ?? 715 */ 716 dev_unlock_and_free(); 717 *dres = dev; 718 return (0); 719 } 720 KASSERT(!(dev->si_flags & SI_NAMED), 721 ("make_dev() by driver %s on pre-existing device (min=%x, name=%s)", 722 devsw->d_name, dev2unit(dev), devtoname(dev))); | 770 if (flags & MAKEDEV_REF) 771 dev_refl(dev); 772 if (flags & MAKEDEV_ETERNAL) 773 dev->si_flags |= SI_ETERNAL; 774 if (dev->si_flags & SI_CHEAPCLONE && 775 dev->si_flags & SI_NAMED) { 776 /* 777 * This is allowed as it removes races and generally 778 * simplifies cloning devices. 779 * XXX: still ?? 780 */ 781 dev_unlock_and_free(); 782 *dres = dev; 783 return (0); 784 } 785 KASSERT(!(dev->si_flags & SI_NAMED), 786 ("make_dev() by driver %s on pre-existing device (min=%x, name=%s)", 787 devsw->d_name, dev2unit(dev), devtoname(dev))); |
723 724 i = vsnrprintf(dev->__si_namebuf, sizeof dev->__si_namebuf, 32, fmt, ap); 725 if (i > (sizeof dev->__si_namebuf - 1)) { 726 printf("WARNING: Device name truncated! (%s)\n", 727 dev->__si_namebuf); 728 } 729 | |
730 dev->si_flags |= SI_NAMED; 731 if (cr != NULL) 732 dev->si_cred = crhold(cr); 733 dev->si_uid = uid; 734 dev->si_gid = gid; 735 dev->si_mode = mode; 736 737 devfs_create(dev); --- 13 unchanged lines hidden (view full) --- 751 struct cdev *dev; 752 va_list ap; 753 int res; 754 755 va_start(ap, fmt); 756 res = make_dev_credv(0, &dev, devsw, unit, NULL, uid, gid, mode, fmt, 757 ap); 758 va_end(ap); | 788 dev->si_flags |= SI_NAMED; 789 if (cr != NULL) 790 dev->si_cred = crhold(cr); 791 dev->si_uid = uid; 792 dev->si_gid = gid; 793 dev->si_mode = mode; 794 795 devfs_create(dev); --- 13 unchanged lines hidden (view full) --- 809 struct cdev *dev; 810 va_list ap; 811 int res; 812 813 va_start(ap, fmt); 814 res = make_dev_credv(0, &dev, devsw, unit, NULL, uid, gid, mode, fmt, 815 ap); 816 va_end(ap); |
759 KASSERT(res == 0 && dev != NULL, ("make_dev: failed make_dev_credv")); | 817 KASSERT(res == 0 && dev != NULL, 818 ("make_dev: failed make_dev_credv (error=%d)", res)); |
760 return (dev); 761} 762 763struct cdev * 764make_dev_cred(struct cdevsw *devsw, int unit, struct ucred *cr, uid_t uid, 765 gid_t gid, int mode, const char *fmt, ...) 766{ 767 struct cdev *dev; 768 va_list ap; 769 int res; 770 771 va_start(ap, fmt); 772 res = make_dev_credv(0, &dev, devsw, unit, cr, uid, gid, mode, fmt, ap); 773 va_end(ap); 774 775 KASSERT(res == 0 && dev != NULL, | 819 return (dev); 820} 821 822struct cdev * 823make_dev_cred(struct cdevsw *devsw, int unit, struct ucred *cr, uid_t uid, 824 gid_t gid, int mode, const char *fmt, ...) 825{ 826 struct cdev *dev; 827 va_list ap; 828 int res; 829 830 va_start(ap, fmt); 831 res = make_dev_credv(0, &dev, devsw, unit, cr, uid, gid, mode, fmt, ap); 832 va_end(ap); 833 834 KASSERT(res == 0 && dev != NULL, |
776 ("make_dev_cred: failed make_dev_credv")); | 835 ("make_dev_cred: failed make_dev_credv (error=%d)", res)); |
777 return (dev); 778} 779 780struct cdev * 781make_dev_credf(int flags, struct cdevsw *devsw, int unit, struct ucred *cr, 782 uid_t uid, gid_t gid, int mode, const char *fmt, ...) 783{ 784 struct cdev *dev; 785 va_list ap; 786 int res; 787 788 va_start(ap, fmt); 789 res = make_dev_credv(flags, &dev, devsw, unit, cr, uid, gid, mode, 790 fmt, ap); 791 va_end(ap); 792 | 836 return (dev); 837} 838 839struct cdev * 840make_dev_credf(int flags, struct cdevsw *devsw, int unit, struct ucred *cr, 841 uid_t uid, gid_t gid, int mode, const char *fmt, ...) 842{ 843 struct cdev *dev; 844 va_list ap; 845 int res; 846 847 va_start(ap, fmt); 848 res = make_dev_credv(flags, &dev, devsw, unit, cr, uid, gid, mode, 849 fmt, ap); 850 va_end(ap); 851 |
793 KASSERT((flags & MAKEDEV_NOWAIT) != 0 || res == 0, 794 ("make_dev_credf: failed make_dev_credv")); | 852 KASSERT(((flags & MAKEDEV_NOWAIT) != 0 && res == ENOMEM) || 853 ((flags & MAKEDEV_CHECKNAME) != 0 && res != ENOMEM) || res == 0, 854 ("make_dev_credf: failed make_dev_credv (error=%d)", res)); |
795 return (res == 0 ? dev : NULL); 796} 797 798int 799make_dev_p(int flags, struct cdev **cdev, struct cdevsw *devsw, 800 struct ucred *cr, uid_t uid, gid_t gid, int mode, const char *fmt, ...) 801{ 802 va_list ap; 803 int res; 804 805 va_start(ap, fmt); 806 res = make_dev_credv(flags, cdev, devsw, 0, cr, uid, gid, mode, 807 fmt, ap); 808 va_end(ap); 809 | 855 return (res == 0 ? dev : NULL); 856} 857 858int 859make_dev_p(int flags, struct cdev **cdev, struct cdevsw *devsw, 860 struct ucred *cr, uid_t uid, gid_t gid, int mode, const char *fmt, ...) 861{ 862 va_list ap; 863 int res; 864 865 va_start(ap, fmt); 866 res = make_dev_credv(flags, cdev, devsw, 0, cr, uid, gid, mode, 867 fmt, ap); 868 va_end(ap); 869 |
810 KASSERT((flags & MAKEDEV_NOWAIT) != 0 || res == 0, 811 ("make_dev_p: failed make_dev_credv")); | 870 KASSERT(((flags & MAKEDEV_NOWAIT) != 0 && res == ENOMEM) || 871 ((flags & MAKEDEV_CHECKNAME) != 0 && res != ENOMEM) || res == 0, 872 ("make_dev_p: failed make_dev_credv (error=%d)", res)); |
812 return (res); 813} 814 815static void 816dev_dependsl(struct cdev *pdev, struct cdev *cdev) 817{ 818 819 cdev->si_parent = pdev; --- 11 unchanged lines hidden (view full) --- 831 dev_unlock(); 832} 833 834struct cdev * 835make_dev_alias(struct cdev *pdev, const char *fmt, ...) 836{ 837 struct cdev *dev; 838 va_list ap; | 873 return (res); 874} 875 876static void 877dev_dependsl(struct cdev *pdev, struct cdev *cdev) 878{ 879 880 cdev->si_parent = pdev; --- 11 unchanged lines hidden (view full) --- 892 dev_unlock(); 893} 894 895struct cdev * 896make_dev_alias(struct cdev *pdev, const char *fmt, ...) 897{ 898 struct cdev *dev; 899 va_list ap; |
839 int i; | 900 int error; |
840 841 KASSERT(pdev != NULL, ("NULL pdev")); 842 dev = devfs_alloc(MAKEDEV_WAITOK); 843 dev_lock(); 844 dev->si_flags |= SI_ALIAS; | 901 902 KASSERT(pdev != NULL, ("NULL pdev")); 903 dev = devfs_alloc(MAKEDEV_WAITOK); 904 dev_lock(); 905 dev->si_flags |= SI_ALIAS; |
845 dev->si_flags |= SI_NAMED; | |
846 va_start(ap, fmt); | 906 va_start(ap, fmt); |
847 i = vsnrprintf(dev->__si_namebuf, sizeof dev->__si_namebuf, 32, fmt, ap); 848 if (i > (sizeof dev->__si_namebuf - 1)) { 849 printf("WARNING: Device name truncated! (%s)\n", 850 dev->__si_namebuf); 851 } | 907 error = prep_devname(dev, fmt, ap); |
852 va_end(ap); | 908 va_end(ap); |
853 | 909 if (error != 0) { 910 panic("make_dev_alias: bad si_name (error=%d, si_name=%s)", 911 error, dev->si_name); 912 } 913 dev->si_flags |= SI_NAMED; |
854 devfs_create(dev); 855 dev_dependsl(pdev, dev); 856 clean_unrhdrl(devfs_inos); 857 dev_unlock(); 858 859 notify_create(dev, MAKEDEV_WAITOK); 860 861 return (dev); --- 438 unchanged lines hidden --- | 914 devfs_create(dev); 915 dev_dependsl(pdev, dev); 916 clean_unrhdrl(devfs_inos); 917 dev_unlock(); 918 919 notify_create(dev, MAKEDEV_WAITOK); 920 921 return (dev); --- 438 unchanged lines hidden --- |