1 /* $NetBSD: prop_kern.c,v 1.13 2009/10/11 12:13:45 bad Exp $ */
4 * Copyright (c) 2006, 2009 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #if defined(__NetBSD__)
34 #include <sys/types.h>
35 #include <sys/ioctl.h>
37 #include <prop/proplib.h>
39 #if !defined(_KERNEL) && !defined(_STANDALONE)
47 _prop_object_externalize_to_pref(prop_object_t obj, struct plistref *pref, char **bufp)
51 switch (prop_object_type(obj)) {
52 case PROP_TYPE_DICTIONARY:
53 buf = prop_dictionary_externalize(obj);
56 buf = prop_array_externalize(obj);
62 /* Assume we ran out of memory. */
65 pref->pref_plist = buf;
66 pref->pref_len = strlen(buf) + 1;
74 * prop_array_externalize_to_pref --
75 * Externalize an array into a plistref for sending to the kernel.
78 prop_array_externalize_to_pref(prop_array_t array, struct plistref *prefp)
83 rv = _prop_object_externalize_to_pref(array, prefp, &buf);
85 errno = rv; /* pass up error value in errno */
90 * prop_dictionary_externalize_to_pref --
91 * Externalize an dictionary into a plistref for sending to the kernel.
94 prop_dictionary_externalize_to_pref(prop_dictionary_t dict, struct plistref *prefp)
99 rv = _prop_object_externalize_to_pref(dict, prefp, &buf);
101 errno = rv; /* pass up error value in errno */
106 _prop_object_send_ioctl(prop_object_t obj, int fd, unsigned long cmd)
108 struct plistref pref;
112 error = _prop_object_externalize_to_pref(obj, &pref, &buf);
116 if (ioctl(fd, cmd, &pref) == -1)
127 * prop_array_send_ioctl --
128 * Send an array to the kernel using the specified ioctl.
131 prop_array_send_ioctl(prop_array_t array, int fd, unsigned long cmd)
134 return (_prop_object_send_ioctl(array, fd, cmd));
138 * prop_dictionary_send_ioctl --
139 * Send a dictionary to the kernel using the specified ioctl.
142 prop_dictionary_send_ioctl(prop_dictionary_t dict, int fd, unsigned long cmd)
145 return (_prop_object_send_ioctl(dict, fd, cmd));
149 _prop_object_internalize_from_pref(const struct plistref *pref, prop_type_t type,
152 prop_object_t obj = NULL;
156 if (pref->pref_len == 0) {
158 * This should never happen; we should always get the XML
159 * for an empty dictionary if it's really empty.
164 buf = pref->pref_plist;
165 buf[pref->pref_len - 1] = '\0'; /* extra insurance */
167 case PROP_TYPE_DICTIONARY:
168 obj = prop_dictionary_internalize(buf);
170 case PROP_TYPE_ARRAY:
171 obj = prop_array_internalize(buf);
176 (void) munmap(buf, pref->pref_len);
177 if (obj == NULL && error == 0)
188 * prop_array_recv_ioctl --
189 * Receive an array from the kernel using the specified ioctl.
192 prop_array_recv_ioctl(int fd, unsigned long cmd, prop_array_t *arrayp)
194 struct plistref pref;
196 if (ioctl(fd, cmd, &pref) == -1)
199 return (_prop_object_internalize_from_pref(&pref, PROP_TYPE_ARRAY,
200 (prop_object_t *)arrayp));
204 * prop_dictionary_recv_ioctl --
205 * Receive a dictionary from the kernel using the specified ioctl.
208 prop_dictionary_recv_ioctl(int fd, unsigned long cmd, prop_dictionary_t *dictp)
210 struct plistref pref;
212 if (ioctl(fd, cmd, &pref) == -1)
215 return (_prop_object_internalize_from_pref(&pref, PROP_TYPE_DICTIONARY,
216 (prop_object_t *)dictp));
220 * prop_dictionary_sendrecv_ioctl --
221 * Combination send/receive a dictionary to/from the kernel using
222 * the specified ioctl.
225 prop_dictionary_sendrecv_ioctl(prop_dictionary_t dict, int fd,
226 unsigned long cmd, prop_dictionary_t *dictp)
228 struct plistref pref;
232 error = _prop_object_externalize_to_pref(dict, &pref, &buf);
236 if (ioctl(fd, cmd, &pref) == -1)
246 return (_prop_object_internalize_from_pref(&pref, PROP_TYPE_DICTIONARY,
247 (prop_object_t *)dictp));
249 #endif /* !_KERNEL && !_STANDALONE */
252 #include <sys/param.h>
253 #include <sys/mman.h>
254 #include <sys/errno.h>
255 #include <sys/malloc.h>
256 #include <sys/systm.h>
257 #include <sys/proc.h>
258 #include <sys/resource.h>
259 #include <sys/pool.h>
263 #include "prop_object_impl.h"
265 /* Arbitrary limit ioctl input to 64KB */
266 unsigned int prop_object_copyin_limit = 65536;
268 /* initialize proplib for use in the kernel */
272 __link_set_decl(prop_linkpools, struct prop_pool_init);
273 struct prop_pool_init * const *pi;
275 __link_set_foreach(pi, prop_linkpools)
276 pool_init((*pi)->pp, (*pi)->size, 0, 0, 0, (*pi)->wchan,
277 &pool_allocator_nointr, IPL_NONE);
281 _prop_object_copyin(const struct plistref *pref, const prop_type_t type,
284 prop_object_t obj = NULL;
289 * Allocate an extra byte so we can guarantee NUL-termination.
291 * Allow malloc to fail in case pmap would be exhausted.
293 buf = malloc(pref->pref_len + 1, M_TEMP, M_WAITOK | M_CANFAIL);
296 error = copyin(pref->pref_plist, buf, pref->pref_len);
301 buf[pref->pref_len] = '\0';
304 case PROP_TYPE_ARRAY:
305 obj = prop_array_internalize(buf);
307 case PROP_TYPE_DICTIONARY:
308 obj = prop_dictionary_internalize(buf);
326 _prop_object_copyin_ioctl(const struct plistref *pref, const prop_type_t type,
327 const u_long cmd, prop_object_t *objp)
329 if ((cmd & IOC_IN) == 0)
332 return _prop_object_copyin(pref, type, objp);
336 * prop_array_copyin --
337 * Copy in an array passed as a syscall arg.
340 prop_array_copyin(const struct plistref *pref, prop_array_t *arrayp)
342 return (_prop_object_copyin(pref, PROP_TYPE_ARRAY,
343 (prop_object_t *)arrayp));
347 * prop_dictionary_copyin --
348 * Copy in a dictionary passed as a syscall arg.
351 prop_dictionary_copyin(const struct plistref *pref, prop_dictionary_t *dictp)
353 return (_prop_object_copyin(pref, PROP_TYPE_DICTIONARY,
354 (prop_object_t *)dictp));
359 * prop_array_copyin_ioctl --
360 * Copy in an array send with an ioctl.
363 prop_array_copyin_ioctl(const struct plistref *pref, const u_long cmd,
364 prop_array_t *arrayp)
366 return (_prop_object_copyin_ioctl(pref, PROP_TYPE_ARRAY,
367 cmd, (prop_object_t *)arrayp));
371 * prop_dictionary_copyin_ioctl --
372 * Copy in a dictionary sent with an ioctl.
375 prop_dictionary_copyin_ioctl(const struct plistref *pref, const u_long cmd,
376 prop_dictionary_t *dictp)
378 return (_prop_object_copyin_ioctl(pref, PROP_TYPE_DICTIONARY,
379 cmd, (prop_object_t *)dictp));
383 _prop_object_copyout_ioctl(struct plistref *pref, const u_long cmd,
386 struct lwp *l = curlwp; /* XXX */
387 struct proc *p = l->l_proc;
393 if ((cmd & IOC_OUT) == 0)
396 switch (prop_object_type(obj)) {
397 case PROP_TYPE_ARRAY:
398 buf = prop_array_externalize(obj);
400 case PROP_TYPE_DICTIONARY:
401 buf = prop_dictionary_externalize(obj);
409 len = strlen(buf) + 1;
410 rlen = round_page(len);
413 * See sys_mmap() in sys/uvm/uvm_mmap.c.
414 * Let's act as if we were calling mmap(0, ...)
416 uaddr = p->p_emul->e_vm_default_addr(p,
417 (vaddr_t)p->p_vmspace->vm_daddr, rlen);
419 error = uvm_mmap(&p->p_vmspace->vm_map,
421 VM_PROT_READ|VM_PROT_WRITE,
422 VM_PROT_READ|VM_PROT_WRITE,
423 MAP_PRIVATE|MAP_ANON,
425 p->p_rlimit[RLIMIT_MEMLOCK].rlim_cur);
428 error = copyout(buf, (char *)uaddr, len);
430 pref->pref_plist = (char *)uaddr;
431 pref->pref_len = len;
441 * prop_array_copyout_ioctl --
442 * Copy out an array being received with an ioctl.
445 prop_array_copyout_ioctl(struct plistref *pref, const u_long cmd,
448 return (_prop_object_copyout_ioctl(pref, cmd, array));
452 * prop_dictionary_copyout_ioctl --
453 * Copy out a dictionary being received with an ioctl.
456 prop_dictionary_copyout_ioctl(struct plistref *pref, const u_long cmd,
457 prop_dictionary_t dict)
459 return (_prop_object_copyout_ioctl(pref, cmd, dict));
463 #endif /* __NetBSD__ */