Example #1
0
int
ksocket_sendmsg(ksocket_t ks, struct nmsghdr *msg, int flags,
    size_t *sent, struct cred *cr)
{
	int error;
	ssize_t len;
	int i;
	struct uio auio;

	/* All Solaris components should pass a cred for this operation. */
	ASSERT(cr != NULL);

	if (!KSOCKET_VALID(ks)) {
		if (sent != NULL)
			*sent = 0;
		return (ENOTSOCK);
	}

	bzero(&auio, sizeof (struct uio));
	auio.uio_loffset = 0;
	auio.uio_iov = msg->msg_iov;
	auio.uio_iovcnt = msg->msg_iovlen;
	if (flags & MSG_USERSPACE)
		auio.uio_segflg = UIO_USERSPACE;
	else
		auio.uio_segflg = UIO_SYSSPACE;
	auio.uio_extflg = UIO_COPY_DEFAULT;
	auio.uio_limit = 0;
	auio.uio_fmode = KSOCKET_FMODE(ks);
	len = 0;
	for (i = 0; i < msg->msg_iovlen; i++) {
		ssize_t iovlen;
		iovlen = (msg->msg_iov)[i].iov_len;
		len += iovlen;
		if (len < 0 || iovlen < 0)
			return (EINVAL);
	}
	auio.uio_resid = len;

	msg->msg_flags = flags | MSG_EOR;

	error = socket_sendmsg(KSTOSO(ks), msg, &auio, cr);
	if (error != 0) {
		if (sent != NULL)
			*sent = 0;
		return (error);
	}

	if (sent != NULL)
		*sent = len - auio.uio_resid;
	return (0);
}
Example #2
0
int
ksocket_sendto(ksocket_t ks, void *msg, size_t msglen, int flags,
    struct sockaddr *name, socklen_t namelen, size_t *sent, struct cred *cr)
{
	int error;
	struct nmsghdr msghdr;
	struct uio auio;
	struct iovec iov;

	/* All Solaris components should pass a cred for this operation. */
	ASSERT(cr != NULL);

	if (!KSOCKET_VALID(ks)) {
		if (sent != NULL)
			*sent = 0;
		return (ENOTSOCK);
	}

	iov.iov_base = msg;
	iov.iov_len = msglen;

	bzero(&auio, sizeof (struct uio));
	auio.uio_loffset = 0;
	auio.uio_iov = &iov;
	auio.uio_iovcnt = 1;
	auio.uio_resid = msglen;
	if (flags & MSG_USERSPACE)
		auio.uio_segflg = UIO_USERSPACE;
	else
		auio.uio_segflg = UIO_SYSSPACE;
	auio.uio_extflg = UIO_COPY_DEFAULT;
	auio.uio_limit = 0;
	auio.uio_fmode = KSOCKET_FMODE(ks);

	msghdr.msg_iov = &iov;
	msghdr.msg_iovlen = 1;
	msghdr.msg_name = (char *)name;
	msghdr.msg_namelen = namelen;
	msghdr.msg_control = NULL;
	msghdr.msg_controllen = 0;
	msghdr.msg_flags = flags | MSG_EOR;

	error = socket_sendmsg(KSTOSO(ks), &msghdr, &auio, cr);
	if (error != 0) {
		if (sent != NULL)
			*sent = 0;
		return (error);
	}
	if (sent != NULL)
		*sent = msglen - auio.uio_resid;
	return (0);
}
Example #3
0
DEFINE_SYSCALL(sendmsg, int, sockfd, const struct msghdr *, msg, int, flags)
{
	log_info("sendmsg(%d, %p, %x)", sockfd, msg, flags);
	if (!mm_check_read_msghdr(msg))
		return -L_EFAULT;
	struct file *f = vfs_get(sockfd);
	if (!f)
		return -L_EBADF;
	int r;
	if (!f->op_vtable->sendmsg)
	{
		log_error("sendmsg() not implemented.");
		r = -L_ENOTSOCK;
	}
	else
		r = socket_sendmsg(f, msg, flags);
	vfs_release(f);
	return r;
}
Example #4
0
/*ARGSUSED2*/
static int
socket_vop_write(struct vnode *vp, struct uio *uiop, int ioflag,
    struct cred *cr, caller_context_t *ct)
{
	struct sonode *so = VTOSO(vp);
	struct nmsghdr lmsg;

	ASSERT(vp->v_type == VSOCK);
	bzero((void *)&lmsg, sizeof (lmsg));

	if (!(so->so_mode & SM_BYTESTREAM)) {
		/*
		 * If the socket is not byte stream set MSG_EOR
		 */
		lmsg.msg_flags = MSG_EOR;
	}

	return (socket_sendmsg(so, &lmsg, uiop, cr));
}