/* * prop_array_copy -- * Copy an array. The new array has an initial capacity equal to * the number of objects stored in the original array. The new * array contains references to the original array's objects, not * copies of those objects (i.e. a shallow copy). */ prop_array_t prop_array_copy(prop_array_t opa) { prop_array_t pa; prop_object_t po; unsigned int idx; if (! prop_object_is_array(opa)) return (NULL); _PROP_RWLOCK_RDLOCK(opa->pa_rwlock); pa = _prop_array_alloc(opa->pa_count); if (pa != NULL) { for (idx = 0; idx < opa->pa_count; idx++) { po = opa->pa_array[idx]; prop_object_retain(po); pa->pa_array[idx] = po; } pa->pa_count = opa->pa_count; pa->pa_flags = opa->pa_flags; } _PROP_RWLOCK_UNLOCK(opa->pa_rwlock); return (pa); }
static prop_object_iterator_t _prop_array_iterator_locked(prop_array_t pa) { struct _prop_array_iterator *pai; if (! prop_object_is_array(pa)) return (NULL); pai = _PROP_CALLOC(sizeof(*pai), M_TEMP); if (pai == NULL) return (NULL); pai->pai_base.pi_next_object = _prop_array_iterator_next_object; pai->pai_base.pi_reset = _prop_array_iterator_reset; prop_object_retain(pa); pai->pai_base.pi_obj = pa; _prop_array_iterator_reset_locked(pai); return (&pai->pai_base); }
struct udev_device * udev_device_new_from_dictionary(struct udev *udev_ctx, prop_dictionary_t dict) { struct udev_device *udev_dev; udev_dev = malloc(sizeof(struct udev_device)); if (udev_dev == NULL) return NULL; udev_dev->refs = 1; udev_dev->ev_type = UDEV_EVENT_NONE; if (dict != NULL) prop_object_retain(dict); udev_dev->dict = dict; udev_dev->udev_ctx = udev_ref(udev_ctx); return udev_dev; }
prop_array_t udev_getdevs(int devfd) { prop_dictionary_t pd, rpd; prop_string_t ps; prop_array_t pa; pd = prop_dictionary_create(); if (pd == NULL) { err(1, "prop_dictionary_create()"); } ps = prop_string_create_cstring("getdevs"); if (ps == NULL) { prop_object_release(pd); err(1, "prop_string_create_cstring()"); } if (prop_dictionary_set(pd, "command", ps) == false) { prop_object_release(ps); prop_object_release(pd); err(1, "prop_dictionary_set()"); } prop_object_release(ps); /* Send dictionary to kernel space */ if (prop_dictionary_sendrecv_ioctl(pd, devfd, UDEVPROP, &rpd) != 0) err(1, "prop_array_recv_ioctl()"); prop_object_release(pd); pa = prop_dictionary_get(rpd, "array"); if (pa == NULL) goto out; prop_object_retain(pa); out: prop_object_release(rpd); return pa; }
static bool _prop_array_add(prop_array_t pa, prop_object_t po) { /* * Array must be WRITE-LOCKED. */ _PROP_ASSERT(pa->pa_count <= pa->pa_capacity); if (prop_array_is_immutable(pa) || (pa->pa_count == pa->pa_capacity && _prop_array_expand(pa, pa->pa_capacity + EXPAND_STEP) == false)) return (false); prop_object_retain(po); pa->pa_array[pa->pa_count++] = po; pa->pa_version++; return (true); }
/* * prop_array_set -- * Store a reference to an object at the specified array index. * This method is not allowed to create holes in the array; the * caller must either be setting the object just beyond the existing * count or replacing an already existing object reference. */ bool prop_array_set(prop_array_t pa, unsigned int idx, prop_object_t po) { prop_object_t opo; bool rv = false; if (! prop_object_is_array(pa)) return (false); _PROP_RWLOCK_WRLOCK(pa->pa_rwlock); if (prop_array_is_immutable(pa)) goto out; if (idx == pa->pa_count) { rv = _prop_array_add(pa, po); goto out; } _PROP_ASSERT(idx < pa->pa_count); opo = pa->pa_array[idx]; _PROP_ASSERT(opo != NULL); prop_object_retain(po); pa->pa_array[idx] = po; pa->pa_version++; prop_object_release(opo); rv = true; out: _PROP_RWLOCK_UNLOCK(pa->pa_rwlock); return (rv); }
int quota_handle_cmd(struct mount *mp, struct lwp *l, prop_dictionary_t cmddict) { int error = 0; const char *cmd, *type; prop_array_t datas; int q2type; if (!prop_dictionary_get_cstring_nocopy(cmddict, "command", &cmd)) return EINVAL; if (!prop_dictionary_get_cstring_nocopy(cmddict, "type", &type)) return EINVAL; if (!strcmp(type, QUOTADICT_CLASS_USER)) { q2type = USRQUOTA; } else if (!strcmp(type, QUOTADICT_CLASS_GROUP)) { q2type = GRPQUOTA; } else return EOPNOTSUPP; datas = prop_dictionary_get(cmddict, "data"); if (datas == NULL || prop_object_type(datas) != PROP_TYPE_ARRAY) return EINVAL; prop_object_retain(datas); prop_dictionary_remove(cmddict, "data"); /* prepare for return */ if (strcmp(cmd, "get version") == 0) { error = quota_handle_cmd_get_version(mp, l, cmddict, datas); goto end; } if (strcmp(cmd, "quotaon") == 0) { error = quota_handle_cmd_quotaon(mp, l, cmddict, q2type, datas); goto end; } if (strcmp(cmd, "quotaoff") == 0) { error = quota_handle_cmd_quotaoff(mp, l, cmddict, q2type, datas); goto end; } if (strcmp(cmd, "get") == 0) { error = quota_handle_cmd_get(mp, l, cmddict, q2type, datas); goto end; } if (strcmp(cmd, "set") == 0) { error = quota_handle_cmd_set(mp, l, cmddict, q2type, datas); goto end; } if (strcmp(cmd, "getall") == 0) { error = quota_handle_cmd_getall(mp, l, cmddict, q2type, datas); goto end; } if (strcmp(cmd, "clear") == 0) { error = quota_handle_cmd_clear(mp, l, cmddict, q2type, datas); goto end; } error = EOPNOTSUPP; end: error = (prop_dictionary_set_int8(cmddict, "return", error) ? 0 : ENOMEM); prop_object_release(datas); return error; }