static int
netbsd32_timer_create_fetch(const void *src, void *dst, size_t size)
{
	struct sigevent *evp = dst;
	struct netbsd32_sigevent ev32;
	int error;

	error = copyin(src, &ev32, sizeof(ev32));
	if (error)
		return error;

	netbsd32_to_sigevent(&ev32, evp);
	return 0;
}
示例#2
0
int
netbsd32_mq_notify(struct lwp *l, const struct netbsd32_mq_notify_args *uap,
    register_t *result)
{
	/* {
		syscallarg(mqd_t) mqdes;
		syscallarg(const netbsd32_sigeventp_t) notification;
	} */
	struct mqueue *mq;
	struct netbsd32_sigevent sig32;
	int error;

	if (SCARG_P32(uap, notification)) {
		/* Get the signal from user-space */
		error = copyin(SCARG_P32(uap, notification), &sig32,
		    sizeof(sig32));
		if (error)
			return error;
		if (sig32.sigev_notify == SIGEV_SIGNAL &&
		    (sig32.sigev_signo <=0 || sig32.sigev_signo >= NSIG))
			return EINVAL;
	}

	error = mqueue_get(SCARG(uap, mqdes), 0, &mq);
	if (error) {
		return error;
	}
	if (SCARG_P32(uap, notification)) {
		/* Register notification: set the signal and target process */
		if (mq->mq_notify_proc == NULL) {
			netbsd32_to_sigevent(&sig32, &mq->mq_sig_notify);
			mq->mq_notify_proc = l->l_proc;
		} else {
			/* Fail if someone else already registered */
			error = EBUSY;
		}
	} else {
		/* Unregister the notification */
		mq->mq_notify_proc = NULL;
	}
	mutex_exit(&mq->mq_mtx);
	fd_putfile((int)SCARG(uap, mqdes));

	return error;
}