Changeset 0030eef in mainline
- Timestamp:
- 2012-03-02T13:55:54Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 560d79f
- Parents:
- 5869ce0
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
abi/include/syscall.h
r5869ce0 r0030eef 92 92 SYS_IRQ_UNREGISTER, 93 93 94 SYS_SYSINFO_GET_KEYS_SIZE, 95 SYS_SYSINFO_GET_KEYS, 94 96 SYS_SYSINFO_GET_VAL_TYPE, 95 97 SYS_SYSINFO_GET_VALUE, -
kernel/generic/include/sysinfo/sysinfo.h
r5869ce0 r0030eef 143 143 extern void sysinfo_dump(sysinfo_item_t *); 144 144 145 extern sysarg_t sys_sysinfo_get_keys_size(void *, size_t, void *); 146 extern sysarg_t sys_sysinfo_get_keys(void *, size_t, void *, size_t, size_t *); 145 147 extern sysarg_t sys_sysinfo_get_val_type(void *, size_t); 146 148 extern sysarg_t sys_sysinfo_get_value(void *, size_t, void *); -
kernel/generic/src/syscall/syscall.c
r5869ce0 r0030eef 184 184 185 185 /* Sysinfo syscalls. */ 186 (syshandler_t) sys_sysinfo_get_keys_size, 187 (syshandler_t) sys_sysinfo_get_keys, 186 188 (syshandler_t) sys_sysinfo_get_val_type, 187 189 (syshandler_t) sys_sysinfo_get_value, -
kernel/generic/src/sysinfo/sysinfo.c
r5869ce0 r0030eef 110 110 * @param subtree Current sysinfo (sub)tree root item. 111 111 * @param ret If the return value is NULL, this argument 112 * can be either also NULL (i.e. no item was112 * can be set either to NULL (i.e. no item was 113 113 * found and no data was generated) or the 114 114 * original pointer is used to store the value … … 125 125 { 126 126 ASSERT(subtree != NULL); 127 ASSERT(ret != NULL);128 127 129 128 sysinfo_item_t *cur = subtree; … … 151 150 case SYSINFO_SUBTREE_FUNCTION: 152 151 /* Get generated data */ 153 **ret = cur->subtree.generator.fn(name + i + 1, dry_run, 154 cur->subtree.generator.data); 152 if (ret != NULL) 153 **ret = cur->subtree.generator.fn(name + i + 1, 154 dry_run, cur->subtree.generator.data); 155 155 156 return NULL; 156 157 default: 157 158 /* Not found, no data generated */ 158 *ret = NULL; 159 if (ret != NULL) 160 *ret = NULL; 161 159 162 return NULL; 160 163 } … … 165 168 166 169 /* Not found, no data generated */ 167 *ret = NULL; 170 if (ret != NULL) 171 *ret = NULL; 172 168 173 return NULL; 169 174 } … … 653 658 } 654 659 660 /** Return sysinfo keys determined by name 661 * 662 * Should be called with sysinfo_lock held. 663 * 664 * @param name Sysinfo path. 665 * @param root Root item of the sysinfo (sub)tree. 666 * If it is NULL then consider the global 667 * sysinfo tree. 668 * @param dry_run Do not actually get any generated 669 * binary data, just calculate the size. 670 * 671 * @return Item value (constant or generated). 672 * 673 */ 674 NO_TRACE static sysinfo_return_t sysinfo_get_keys(const char *name, 675 sysinfo_item_t **root, bool dry_run) 676 { 677 if (root == NULL) 678 root = &global_root; 679 680 /* Try to find the item */ 681 sysinfo_item_t *item = sysinfo_find_item(name, *root, NULL, 682 dry_run); 683 684 sysinfo_return_t ret; 685 686 if ((item != NULL) && (item->subtree_type == SYSINFO_SUBTREE_TABLE)) { 687 /* 688 * Subtree found in the fixed sysinfo tree. 689 * Calculate the size of subkeys. 690 */ 691 size_t size = 0; 692 for (sysinfo_item_t *cur = item->subtree.table; cur; 693 cur = cur->next) 694 size += str_size(cur->name) + 1; 695 696 if (dry_run) { 697 ret.tag = SYSINFO_VAL_FUNCTION_DATA; 698 ret.data.data = NULL; 699 ret.data.size = size; 700 } else { 701 /* Allocate buffer for subkeys */ 702 char *names = (char *) malloc(size, FRAME_ATOMIC); 703 if (names == NULL) 704 return ret; 705 706 size_t pos = 0; 707 for (sysinfo_item_t *cur = item->subtree.table; cur; 708 cur = cur->next) { 709 str_cpy(names + pos, size - pos, cur->name); 710 pos += str_size(cur->name) + 1; 711 } 712 713 /* Correct return value */ 714 ret.tag = SYSINFO_VAL_FUNCTION_DATA; 715 ret.data.data = (void *) names; 716 ret.data.size = size; 717 } 718 } else { 719 /* No item in the fixed sysinfo tree */ 720 ret.tag = SYSINFO_VAL_UNDEFINED; 721 } 722 723 return ret; 724 } 725 726 /** Return sysinfo keys determined by name from user space 727 * 728 * The path string passed from the user space has to be properly 729 * null-terminated (the last passed character must be null). 730 * 731 * @param ptr Sysinfo path in the user address space. 732 * @param size Size of the path string. 733 * @param dry_run Do not actually get any generated 734 * binary data, just calculate the size. 735 * 736 */ 737 NO_TRACE static sysinfo_return_t sysinfo_get_keys_uspace(void *ptr, size_t size, 738 bool dry_run) 739 { 740 sysinfo_return_t ret; 741 ret.tag = SYSINFO_VAL_UNDEFINED; 742 743 if (size > SYSINFO_MAX_PATH) 744 return ret; 745 746 char *path = (char *) malloc(size + 1, 0); 747 ASSERT(path); 748 749 if ((copy_from_uspace(path, ptr, size + 1) == 0) && 750 (path[size] == 0)) { 751 /* 752 * Prevent other functions from messing with sysinfo while we 753 * are reading it. 754 */ 755 mutex_lock(&sysinfo_lock); 756 ret = sysinfo_get_keys(path, NULL, dry_run); 757 mutex_unlock(&sysinfo_lock); 758 } 759 760 free(path); 761 return ret; 762 } 763 764 /** Get the sysinfo keys size (syscall) 765 * 766 * The path string passed from the user space has 767 * to be properly null-terminated (the last passed 768 * character must be null). 769 * 770 * @param path_ptr Sysinfo path in the user address space. 771 * @param path_size Size of the path string. 772 * @param size_ptr User space pointer where to store the 773 * keys size. 774 * 775 * @return Error code (EOK in case of no error). 776 * 777 */ 778 sysarg_t sys_sysinfo_get_keys_size(void *path_ptr, size_t path_size, 779 void *size_ptr) 780 { 781 int rc; 782 783 /* 784 * Get the keys. 785 * 786 * N.B.: There is no need to free any potential keys 787 * since we request a dry run. 788 */ 789 sysinfo_return_t ret = 790 sysinfo_get_keys_uspace(path_ptr, path_size, true); 791 792 /* Check return data tag */ 793 if (ret.tag == SYSINFO_VAL_DATA) 794 rc = copy_to_uspace(size_ptr, &ret.data.size, 795 sizeof(ret.data.size)); 796 else 797 rc = EINVAL; 798 799 return (sysarg_t) rc; 800 } 801 802 /** Get the sysinfo keys (syscall) 803 * 804 * The path string passed from the user space has 805 * to be properly null-terminated (the last passed 806 * character must be null). 807 * 808 * If the user space buffer size does not equal 809 * the actual size of the returned data, the data 810 * is truncated. 811 * 812 * The actual size of data returned is stored to 813 * size_ptr. 814 * 815 * @param path_ptr Sysinfo path in the user address space. 816 * @param path_size Size of the path string. 817 * @param buffer_ptr User space pointer to the buffer where 818 * to store the binary data. 819 * @param buffer_size User space buffer size. 820 * @param size_ptr User space pointer where to store the 821 * binary data size. 822 * 823 * @return Error code (EOK in case of no error). 824 * 825 */ 826 sysarg_t sys_sysinfo_get_keys(void *path_ptr, size_t path_size, 827 void *buffer_ptr, size_t buffer_size, size_t *size_ptr) 828 { 829 int rc; 830 831 /* Get the keys */ 832 sysinfo_return_t ret = sysinfo_get_keys_uspace(path_ptr, path_size, 833 false); 834 835 /* Check return data tag */ 836 if (ret.tag == SYSINFO_VAL_DATA) { 837 size_t size = min(ret.data.size, buffer_size); 838 rc = copy_to_uspace(buffer_ptr, ret.data.data, size); 839 if (rc == EOK) 840 rc = copy_to_uspace(size_ptr, &size, sizeof(size)); 841 842 free(ret.data.data); 843 } else 844 rc = EINVAL; 845 846 return (sysarg_t) rc; 847 } 848 655 849 /** Get the sysinfo value type (syscall) 656 850 *
Note:
See TracChangeset
for help on using the changeset viewer.