Beispiel #1
0
/*
 * 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);
}
Beispiel #2
0
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);
}
Beispiel #3
0
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;
}
Beispiel #4
0
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;
}
Beispiel #5
0
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);
}
Beispiel #6
0
/*
 * 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);
}
Beispiel #7
0
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;
}