Ejemplo n.º 1
0
static int
fd_revoke(struct lwp *l, int fd, register_t *retval)
{
	file_t *fp;
	vnode_t *vp;
	int error;

	if ((fp = fd_getfile(fd)) == NULL)
		return EBADF;

	if (fp->f_type != DTYPE_VNODE) {
		fd_putfile(fd);
		return EINVAL;
	}

	vp = (vnode_t *) fp->f_data;
	if (vp->v_type != VCHR && vp->v_type != VBLK) {
		error = EINVAL;
		goto out;
	}

	error = dorevoke(vp, l->l_cred);
out:
	vrele(vp);
	fd_putfile(fd);
	return error;
}
Ejemplo n.º 2
0
static int
fd_truncate(struct lwp *l, int fd, struct flock *flp, register_t *retval)
{
	file_t *fp;
	off_t start, length;
	vnode_t *vp;
	struct vattr vattr;
	int error;
	struct sys_ftruncate_args ft;

	/*
	 * We only support truncating the file.
	 */
	if ((fp = fd_getfile(fd)) == NULL)
		return EBADF;

	vp = fp->f_data;
	if (fp->f_type != DTYPE_VNODE || vp->v_type == VFIFO) {
		fd_putfile(fd);
		return ESPIPE;
	}
	if ((error = VOP_GETATTR(vp, &vattr, l->l_cred)) != 0) {
		fd_putfile(fd);
		return error;
	}

	length = vattr.va_size;

	switch (flp->l_whence) {
	case SEEK_CUR:
		start = fp->f_offset + flp->l_start;
		break;

	case SEEK_END:
		start = flp->l_start + length;
		break;

	case SEEK_SET:
		start = flp->l_start;
		break;

	default:
		fd_putfile(fd);
		return EINVAL;
	}

	if (start + flp->l_len < length) {
		/* We don't support free'ing in the middle of the file */
		fd_putfile(fd);
		return EINVAL;
	}

	SCARG(&ft, fd) = fd;
	SCARG(&ft, length) = start;

	error = sys_ftruncate(l, &ft, retval);
	fd_putfile(fd);
	return error;
}
Ejemplo n.º 3
0
/* ARGSUSED */
int
sys_flock(struct lwp *l, const struct sys_flock_args *uap, register_t *retval)
{
	/* {
		syscallarg(int)	fd;
		syscallarg(int)	how;
	} */
	int fd, how, error;
	file_t *fp;
	vnode_t	*vp;
	struct flock lf;

	fd = SCARG(uap, fd);
	how = SCARG(uap, how);
	error = 0;

	if ((fp = fd_getfile(fd)) == NULL) {
		return EBADF;
	}
	if (fp->f_type != DTYPE_VNODE) {
		fd_putfile(fd);
		return EOPNOTSUPP;
	}

	vp = fp->f_vnode;
	lf.l_whence = SEEK_SET;
	lf.l_start = 0;
	lf.l_len = 0;

	switch (how & ~LOCK_NB) {
	case LOCK_UN:
		lf.l_type = F_UNLCK;
		atomic_and_uint(&fp->f_flag, ~FHASLOCK);
		error = VOP_ADVLOCK(vp, fp, F_UNLCK, &lf, F_FLOCK);
		fd_putfile(fd);
		return error;
	case LOCK_EX:
		lf.l_type = F_WRLCK;
		break;
	case LOCK_SH:
		lf.l_type = F_RDLCK;
		break;
	default:
		fd_putfile(fd);
		return EINVAL;
	}

	atomic_or_uint(&fp->f_flag, FHASLOCK);
	if (how & LOCK_NB) {
		error = VOP_ADVLOCK(vp, fp, F_SETLK, &lf, F_FLOCK);
	} else {
		error = VOP_ADVLOCK(vp, fp, F_SETLK, &lf, F_FLOCK|F_WAIT);
	}
	fd_putfile(fd);
	return error;
}
Ejemplo n.º 4
0
/*
 * Duplicate a file descriptor to a particular value.
 */
int
dodup(struct lwp *l, int from, int to, int flags, register_t *retval)
{
	int error;
	file_t *fp;

	if ((fp = fd_getfile(from)) == NULL)
		return EBADF;
	mutex_enter(&fp->f_lock);
	fp->f_count++;
	mutex_exit(&fp->f_lock);
	fd_putfile(from);

	if ((u_int)to >= curproc->p_rlimit[RLIMIT_NOFILE].rlim_cur ||
	    (u_int)to >= maxfiles)
		error = EBADF;
	else if (from == to)
		error = 0;
	else
		error = fd_dup2(fp, to, flags);
	closef(fp);
	*retval = to;

	return error;
}
Ejemplo n.º 5
0
/*
 * Read a block of directory entries in a file system independent format.
 */
int
compat_12_sys_getdirentries(struct lwp *l, const struct compat_12_sys_getdirentries_args *uap, register_t *retval)
{
	/* {
		syscallarg(int) fd;
		syscallarg(char *) buf;
		syscallarg(u_int) count;
		syscallarg(long *) basep;
	} */
	struct file *fp;
	int error, done;
	long loff;

	/* fd_getvnode() will use the descriptor for us */
	if ((error = fd_getvnode(SCARG(uap, fd), &fp)) != 0)
		return error;
	if ((fp->f_flag & FREAD) == 0) {
		error = EBADF;
		goto out;
	}

	loff = fp->f_offset;

	error = vn_readdir(fp, SCARG(uap, buf), UIO_USERSPACE,
			SCARG(uap, count), &done, l, 0, 0);

	error = copyout(&loff, SCARG(uap, basep), sizeof(long));
	*retval = done;
 out:
	fd_putfile(SCARG(uap, fd));
	return error;
}
int
compat_50_netbsd32_futimes(struct lwp *l,
    const struct compat_50_netbsd32_futimes_args *uap, register_t *retval)
{
	/* {
		syscallarg(int) fd;
		syscallarg(const netbsd32_timeval50p_t) tptr;
	} */
	int error;
	file_t *fp;
	struct timeval tv[2], *tvp;

	error = get_utimes32(SCARG_P32(uap, tptr), tv, &tvp);
	if (error != 0)
		return error;

	/* fd_getvnode() will use the descriptor for us */
	if ((error = fd_getvnode(SCARG(uap, fd), &fp)) != 0)
		return error;

	error = do_sys_utimes(l, fp->f_data, NULL, 0, tvp, UIO_SYSSPACE);

	fd_putfile(SCARG(uap, fd));
	return error;
}
Ejemplo n.º 7
0
/*
 * Get peer socket name.
 */
int
do_sys_getpeername(int fd, struct mbuf **nam)
{
	struct socket	*so;
	struct mbuf	*m;
	int		error;

	if ((error = fd_getsock(fd, &so)) != 0)
		return error;

	m = m_getclr(M_WAIT, MT_SONAME);
	MCLAIM(m, so->so_mowner);

	solock(so);
	if ((so->so_state & SS_ISCONNECTED) == 0)
		error = ENOTCONN;
	else {
		*nam = m;
		error = (*so->so_proto->pr_usrreqs->pr_peeraddr)(so, m);
	}
	sounlock(so);
	if (error != 0)
		m_free(m);
	fd_putfile(fd);
	return error;
}
Ejemplo n.º 8
0
int
svr4_sys_open(struct lwp *l, const struct svr4_sys_open_args *uap, register_t *retval)
{
	int			error;
	struct sys_open_args	cup;

	SCARG(&cup, flags) = svr4_to_bsd_flags(SCARG(uap, flags));

	SCARG(&cup, path) = SCARG(uap, path);
	SCARG(&cup, mode) = SCARG(uap, mode);
	error = sys_open(l, &cup, retval);

	if (error)
		return error;

	/* XXXAD locking */

	if (!(SCARG(&cup, flags) & O_NOCTTY) && SESS_LEADER(l->l_proc) &&
	    !(l->l_proc->p_lflag & PL_CONTROLT)) {
		file_t *fp;
		fp = fd_getfile(*retval);

		/* ignore any error, just give it a try */
		if (fp != NULL) {
			if (fp->f_type == DTYPE_VNODE)
				(fp->f_ops->fo_ioctl)(fp, TIOCSCTTY, NULL);
			fd_putfile(*retval);
		}
	}
	return 0;
}
int
compat_30_netbsd32_getdents(struct lwp *l, const struct compat_30_netbsd32_getdents_args *uap, register_t *retval)
{
	/* {
		syscallarg(int) fd;
		syscallarg(netbsd32_charp) buf;
		syscallarg(netbsd32_size_t) count;
	} */
	file_t *fp;
	int error, done;
	char  *buf;
	netbsd32_size_t count;

	/* Limit the size on any kernel buffers used by VOP_READDIR */
	count = min(MAXBSIZE, SCARG(uap, count));

	/* fd_getvnode() will use the descriptor for us */
	if ((error = fd_getvnode(SCARG(uap, fd), &fp)) != 0)
		return (error);
	if ((fp->f_flag & FREAD) == 0) {
		error = EBADF;
		goto out;
	}
	buf = kmem_alloc(count, KM_SLEEP);
	error = vn_readdir(fp, buf, UIO_SYSSPACE, count, &done, l, 0, 0);
	if (error == 0) {
		*retval = netbsd32_to_dirent12(buf, done);
		error = copyout(buf, SCARG_P32(uap, buf), *retval);
	}
	kmem_free(buf, count);
 out:
 	fd_putfile(SCARG(uap, fd));
	return (error);
}
Ejemplo n.º 10
0
int
ibcs2_sys_open(struct lwp *l, const struct ibcs2_sys_open_args *uap, register_t *retval)
{
	/* {
		syscallarg(char *) path;
		syscallarg(int) flags;
		syscallarg(int) mode;
	} */
	struct proc *p = l->l_proc;
	struct sys_open_args bsd_ua;
	int noctty = SCARG(uap, flags) & IBCS2_O_NOCTTY;
	int ret;

	SCARG(&bsd_ua, path) = SCARG(uap, path);
	SCARG(&bsd_ua, flags) = cvt_o_flags(SCARG(uap, flags));
	SCARG(&bsd_ua, mode) = SCARG(uap, mode);
	ret = sys_open(l, &bsd_ua, retval);

	if (!ret && !noctty && SESS_LEADER(p) && !(p->p_lflag & PL_CONTROLT)) {
		file_t *fp;

		if ((fp = fd_getfile(*retval)) != NULL) {
			/* ignore any error, just give it a try */
			if (fp->f_type == DTYPE_VNODE)
				(fp->f_ops->fo_ioctl)(fp, TIOCSCTTY, NULL);
			fd_putfile(*retval);
		}
	}
	return ret;
}
Ejemplo n.º 11
0
int
compat_20_netbsd32_fstatfs(struct lwp *l, const struct compat_20_netbsd32_fstatfs_args *uap, register_t *retval)
{
	/* {
		syscallarg(int) fd;
		syscallarg(netbsd32_statfsp_t) buf;
	} */
	file_t *fp;
	struct mount *mp;
	struct statvfs *sp;
	struct netbsd32_statfs s32;
	int error;

	/* fd_getvnode() will use the descriptor for us */
	if ((error = fd_getvnode(SCARG(uap, fd), &fp)) != 0)
		return (error);
	mp = ((struct vnode *)fp->f_data)->v_mount;
	sp = &mp->mnt_stat;
	if ((error = VFS_STATVFS(mp, sp)) != 0)
		goto out;
	sp->f_flag = mp->mnt_flag & MNT_VISFLAGMASK;
	compat_20_netbsd32_from_statvfs(sp, &s32);
	error = copyout(&s32, SCARG_P32(uap, buf), sizeof(s32));
 out:
	fd_putfile(SCARG(uap, fd));
	return (error);
}
Ejemplo n.º 12
0
static void
linux_open_ctty(struct lwp *l, int flags, int fd)
{
	struct proc *p = l->l_proc;

	/*
	 * this bit from sunos_misc.c (and svr4_fcntl.c).
	 * If we are a session leader, and we don't have a controlling
	 * terminal yet, and the O_NOCTTY flag is not set, try to make
	 * this the controlling terminal.
	 */
        if (!(flags & O_NOCTTY) && SESS_LEADER(p) && !(p->p_lflag & PL_CONTROLT)) {
                file_t *fp;

		fp = fd_getfile(fd);

                /* ignore any error, just give it a try */
                if (fp != NULL) {
			if (fp->f_type == DTYPE_VNODE) {
				(fp->f_ops->fo_ioctl) (fp, TIOCSCTTY, NULL);
			}
			fd_putfile(fd);
		}
        }
}
Ejemplo n.º 13
0
static int
kttcp_recv(struct lwp *l, struct kttcp_io_args *kio)
{
	struct socket *so;
	int error;
	struct timeval t0, t1;
	unsigned long long len, done;

	done = 0;	/* XXX gcc */

	if (kio->kio_totalsize > KTTCP_MAX_XMIT)
		return EINVAL;

	if ((error = fd_getsock(kio->kio_socket, &so)) != 0)
		return error;
	len = kio->kio_totalsize;
	microtime(&t0);
	do {
		error = kttcp_soreceive(so, len, &done, l, NULL);
		len -= done;
	} while (error == 0 && len > 0 && done > 0);

	fd_putfile(kio->kio_socket);

	microtime(&t1);
	if (error == EPIPE)
		error = 0;
	if (error != 0)
		return error;
	timersub(&t1, &t0, &kio->kio_elapsed);

	kio->kio_bytesdone = kio->kio_totalsize - len;

	return 0;
}
Ejemplo n.º 14
0
int
ibcs2_sys_fstatvfs(struct lwp *l, const struct ibcs2_sys_fstatvfs_args *uap, register_t *retval)
{
	/* {
		syscallarg(int) fd;
		syscallarg(struct ibcs2_statvfs *) buf;
	} */
	file_t *fp;
	struct mount *mp;
	struct statvfs *sp;
	int error;

	/* fd_getvnode() will use the descriptor for us */
	if ((error = fd_getvnode(SCARG(uap, fd), &fp)) != 0)
		return (error);
	mp = ((struct vnode *)fp->f_data)->v_mount;
	sp = &mp->mnt_stat;
	if ((error = VFS_STATVFS(mp, sp)) != 0)
		goto out;
	sp->f_flag = mp->mnt_flag & MNT_VISFLAGMASK;
	error = cvt_statvfs(sp, SCARG(uap, buf), sizeof(struct ibcs2_statvfs));
 out:
 	fd_putfile(SCARG(uap, fd));
	return (error);
}
Ejemplo n.º 15
0
int
do_sys_connect(struct lwp *l, int fd, struct mbuf *nam)
{
	struct socket	*so;
	int		error;
	int		interrupted = 0;

	if ((error = fd_getsock(fd, &so)) != 0) {
		m_freem(nam);
		return (error);
	}
	solock(so);
	MCLAIM(nam, so->so_mowner);
	if ((so->so_state & SS_ISCONNECTING) != 0) {
		error = EALREADY;
		goto out;
	}

	error = soconnect(so, nam, l);
	if (error)
		goto bad;
	if ((so->so_state & (SS_NBIO|SS_ISCONNECTING)) ==
	    (SS_NBIO|SS_ISCONNECTING)) {
		error = EINPROGRESS;
		goto out;
	}
	while ((so->so_state & SS_ISCONNECTING) != 0 && so->so_error == 0) {
		error = sowait(so, true, 0);
		if (__predict_false((so->so_state & SS_ISABORTING) != 0)) {
			error = EPIPE;
			interrupted = 1;
			break;
		}
		if (error) {
			if (error == EINTR || error == ERESTART)
				interrupted = 1;
			break;
		}
	}
	if (error == 0) {
		error = so->so_error;
		so->so_error = 0;
	}
 bad:
	if (!interrupted)
		so->so_state &= ~SS_ISCONNECTING;
	if (error == ERESTART)
		error = EINTR;
 out:
	sounlock(so);
	fd_putfile(fd);
	m_freem(nam);
	return error;
}
Ejemplo n.º 16
0
int
sys_getsockopt(struct lwp *l, const struct sys_getsockopt_args *uap,
    register_t *retval)
{
	/* {
		syscallarg(int)			s;
		syscallarg(int)			level;
		syscallarg(int)			name;
		syscallarg(void *)		val;
		syscallarg(unsigned int *)	avalsize;
	} */
	struct sockopt	sopt;
	struct socket	*so;
	file_t		*fp;
	unsigned int	valsize, len;
	int		error;

	if (SCARG(uap, val) != NULL) {
		error = copyin(SCARG(uap, avalsize), &valsize, sizeof(valsize));
		if (error)
			return error;
	} else
		valsize = 0;

	if ((error = fd_getsock1(SCARG(uap, s), &so, &fp)) != 0)
		return (error);

	sockopt_init(&sopt, SCARG(uap, level), SCARG(uap, name), 0);

	if (fp->f_flag & FNOSIGPIPE)
		so->so_options |= SO_NOSIGPIPE;
	else
		so->so_options &= ~SO_NOSIGPIPE;
	error = sogetopt(so, &sopt);
	if (error)
		goto out;

	if (valsize > 0) {
		len = min(valsize, sopt.sopt_size);
		error = copyout(sopt.sopt_data, SCARG(uap, val), len);
		if (error)
			goto out;

		error = copyout(&len, SCARG(uap, avalsize), sizeof(len));
		if (error)
			goto out;
	}

 out:
	sockopt_destroy(&sopt);
	fd_putfile(SCARG(uap, s));
	return error;
}
Ejemplo n.º 17
0
int
do_sys_recvmsg(struct lwp *l, int s, struct msghdr *mp, struct mbuf **from,
    struct mbuf **control, register_t *retsize)
{
	int error;
	struct socket *so;

	if ((error = fd_getsock(s, &so)) != 0)
		return error;
	error = do_sys_recvmsg_so(l, s, so, mp, from, control, retsize);
	fd_putfile(s);
	return error;
}
Ejemplo n.º 18
0
int
do_sys_sendmsg(struct lwp *l, int s, struct msghdr *mp, int flags,
    register_t *retsize)
{
	int		error;
	struct socket	*so;
	file_t		*fp;

	if ((error = fd_getsock1(s, &so, &fp)) != 0)
		return error;
	error = do_sys_sendmsg_so(l, s, so, fp, mp, flags, retsize);
	fd_putfile(s);
	return error;
}
Ejemplo n.º 19
0
int
netbsd32_mq_setattr(struct lwp *l, const struct netbsd32_mq_setattr_args *uap,
    register_t *retval)
{
	/* {
		syscallarg(mqd_t) mqdes;
		syscallarg(const netbsd32_mq_attrp_t) mqstat;
		syscallarg(netbsd32_mq_attrp_t) omqstat;
	} */
	struct mqueue *mq;
	struct netbsd32_mq_attr attr32;
	struct mq_attr attr;
	int error, nonblock;

	error = copyin(SCARG_P32(uap, mqstat), &attr32, sizeof(attr32));
	if (error)
		return error;
	netbsd32_to_mq_attr(&attr32, &attr);
	nonblock = (attr.mq_flags & O_NONBLOCK);

	error = mqueue_get(SCARG(uap, mqdes), 0, &mq);
	if (error)
		return error;

	/* Copy the old attributes, if needed */
	if (SCARG_P32(uap, omqstat))
		memcpy(&attr, &mq->mq_attrib, sizeof(struct mq_attr));

	/* Ignore everything, except O_NONBLOCK */
	if (nonblock)
		mq->mq_attrib.mq_flags |= O_NONBLOCK;
	else
		mq->mq_attrib.mq_flags &= ~O_NONBLOCK;

	mutex_exit(&mq->mq_mtx);
	fd_putfile((int)SCARG(uap, mqdes));

	/*
	 * Copy the data to the user-space.
	 * Note: According to POSIX, the new attributes should not be set in
	 * case of fail - this would be violated.
	 */
	if (SCARG_P32(uap, omqstat)) {
		netbsd32_from_mq_attr(&attr, &attr32);
		error = copyout(&attr32, SCARG_P32(uap, omqstat),
		    sizeof(attr32));
	}

	return error;
}
Ejemplo n.º 20
0
/*
 * Return status information about a file descriptor.
 * Common function for compat code.
 */
int
do_sys_fstat(int fd, struct stat *sb)
{
	file_t *fp;
	int error;

	if ((fp = fd_getfile(fd)) == NULL) {
		return EBADF;
	}
	error = (*fp->f_ops->fo_stat)(fp, sb);
	fd_putfile(fd);

	return error;
}
Ejemplo n.º 21
0
int
do_sys_bind(struct lwp *l, int fd, struct mbuf *nam)
{
	struct socket	*so;
	int		error;

	if ((error = fd_getsock(fd, &so)) != 0) {
		m_freem(nam);
		return (error);
	}
	MCLAIM(nam, so->so_mowner);
	error = sobind(so, nam, l);
	m_freem(nam);
	fd_putfile(fd);
	return error;
}
Ejemplo n.º 22
0
int
sys_listen(struct lwp *l, const struct sys_listen_args *uap, register_t *retval)
{
	/* {
		syscallarg(int)	s;
		syscallarg(int)	backlog;
	} */
	struct socket	*so;
	int		error;

	if ((error = fd_getsock(SCARG(uap, s), &so)) != 0)
		return (error);
	error = solisten(so, SCARG(uap, backlog), l);
	fd_putfile(SCARG(uap, s));
	return error;
}
Ejemplo n.º 23
0
int
sys_setsockopt(struct lwp *l, const struct sys_setsockopt_args *uap,
    register_t *retval)
{
	/* {
		syscallarg(int)			s;
		syscallarg(int)			level;
		syscallarg(int)			name;
		syscallarg(const void *)	val;
		syscallarg(unsigned int)	valsize;
	} */
	struct sockopt	sopt;
	struct socket	*so;
	file_t		*fp;
	int		error;
	unsigned int	len;

	len = SCARG(uap, valsize);
	if (len > 0 && SCARG(uap, val) == NULL)
		return EINVAL;

	if (len > MCLBYTES)
		return EINVAL;

	if ((error = fd_getsock1(SCARG(uap, s), &so, &fp)) != 0)
		return (error);

	sockopt_init(&sopt, SCARG(uap, level), SCARG(uap, name), len);

	if (len > 0) {
		error = copyin(SCARG(uap, val), sopt.sopt_data, len);
		if (error)
			goto out;
	}

	error = sosetopt(so, &sopt);
	if (so->so_options & SO_NOSIGPIPE)
		atomic_or_uint(&fp->f_flag, FNOSIGPIPE);
	else
		atomic_and_uint(&fp->f_flag, ~FNOSIGPIPE);

 out:
	sockopt_destroy(&sopt);
	fd_putfile(SCARG(uap, s));
	return error;
}
Ejemplo n.º 24
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;
}
Ejemplo n.º 25
0
int
darwin_sys_ioctl(struct lwp *l, const struct darwin_sys_ioctl_args *uap, register_t *retval)
{
	/* {
		syscallarg(int) fd;
		syscallarg(u_long) com;
		syscallarg(void *) data;
	} */
	struct sys_ioctl_args cup;
	int error;

	switch (SCARG(uap, com)) {
	case DARWIN_FIODTYPE: { /* Get file d_type */
		file_t *fp;
		struct vnode *vp;
		int *data = SCARG(uap, data);
		int type;

		/* fd_getvnode() will use the descriptor for us */
		if ((error = fd_getvnode(SCARG(uap, fd), &fp)))
			return (error);

		vp = fp->f_data;
		type = vtype_to_dtype(vp->v_type);
		fd_putfile(SCARG(uap, fd));

		error = copyout(&type, data, sizeof(*data));

		return error;
		break;
	}

	default:
		/* Try native ioctl */
		break;
	}

	SCARG(&cup, fd) = SCARG(uap, fd);
	SCARG(&cup, com) = SCARG(uap, com);
	SCARG(&cup, data) = SCARG(uap, data);

	error = sys_ioctl(l, &cup, retval);

	return error;
}
Ejemplo n.º 26
0
/*
 * Duplicate a file descriptor.
 */
int
sys_dup(struct lwp *l, const struct sys_dup_args *uap, register_t *retval)
{
	/* {
		syscallarg(int)	fd;
	} */
	int error, newfd, oldfd;
	file_t *fp;

	oldfd = SCARG(uap, fd);

	if ((fp = fd_getfile(oldfd)) == NULL) {
		return EBADF;
	}
	error = fd_dup(fp, 0, &newfd, false);
	fd_putfile(oldfd);
	*retval = newfd;
	return error;
}
Ejemplo n.º 27
0
int
sys_shutdown(struct lwp *l, const struct sys_shutdown_args *uap,
    register_t *retval)
{
	/* {
		syscallarg(int)	s;
		syscallarg(int)	how;
	} */
	struct socket	*so;
	int		error;

	if ((error = fd_getsock(SCARG(uap, s), &so)) != 0)
		return error;
	solock(so);
	error = soshutdown(so, SCARG(uap, how));
	sounlock(so);
	fd_putfile(SCARG(uap, s));
	return error;
}
Ejemplo n.º 28
0
/*
 * Return pathconf information about a file descriptor.
 */
int
sys_fpathconf(struct lwp *l, const struct sys_fpathconf_args *uap,
	      register_t *retval)
{
	/* {
		syscallarg(int)	fd;
		syscallarg(int)	name;
	} */
	int fd, error;
	file_t *fp;

	fd = SCARG(uap, fd);
	error = 0;

	if ((fp = fd_getfile(fd)) == NULL) {
		return (EBADF);
	}
	switch (fp->f_type) {
	case DTYPE_SOCKET:
	case DTYPE_PIPE:
		if (SCARG(uap, name) != _PC_PIPE_BUF)
			error = EINVAL;
		else
			*retval = PIPE_BUF;
		break;

	case DTYPE_VNODE:
		error = VOP_PATHCONF(fp->f_vnode, SCARG(uap, name), retval);
		break;

	case DTYPE_KQUEUE:
		error = EINVAL;
		break;

	default:
		error = EOPNOTSUPP;
		break;
	}

	fd_putfile(fd);
	return (error);
}
Ejemplo n.º 29
0
int
ultrix_sys_open(struct lwp *l, const struct ultrix_sys_open_args *uap, register_t *retval)
{
	struct proc *p = l->l_proc;
	int q, r;
	int noctty;
	int ret;
	struct sys_open_args ap;

	/* convert open flags into NetBSD flags */

	q = SCARG(uap, flags);
	noctty = q & 0x8000;
	r =	(q & (0x0001 | 0x0002 | 0x0008 | 0x0040 | 0x0200 | 0x0400 | 0x0800));
	r |=	((q & (0x0004 | 0x1000 | 0x4000)) ? O_NONBLOCK : 0);
	r |=	((q & 0x0080) ? O_SHLOCK : 0);
	r |=	((q & 0x0100) ? O_EXLOCK : 0);
	r |=	((q & 0x2000) ? O_FSYNC : 0);

	SCARG(&ap, path) = SCARG(uap, path);
	SCARG(&ap, flags) = r;
	SCARG(&ap, mode) = SCARG(uap, mode);
	ret = sys_open(l, &ap, retval);

	/* XXXSMP */
	if (!ret && !noctty && SESS_LEADER(p) && !(p->p_lflag & PL_CONTROLT)) {
		file_t *fp;
		int fd;

		fd = (int)*retval;
		fp = fd_getfile(fd);

		/* ignore any error, just give it a try */
		if (fp != NULL) {
			if (fp->f_type == DTYPE_VNODE)
				(fp->f_ops->fo_ioctl)(fp, TIOCSCTTY, NULL);
			fd_putfile(fd);
		}
	}
	return ret;
}
Ejemplo n.º 30
0
/*
 * sys_fstatfs() takes an fd, not a path, and so needs no emul
 * pathname processing;  but it's similar enough to sys_statvfs() that
 * it goes here anyway.
 */
int
ultrix_sys_fstatfs(struct lwp *l, const struct ultrix_sys_fstatfs_args *uap, register_t *retval)
{
	file_t *fp;
	struct mount *mp;
	struct statvfs *sp;
	int error;

	/* fd_getvnode() will use the descriptor for us */
	if ((error = fd_getvnode(SCARG(uap, fd), &fp)) != 0)
		return error;
	mp = ((struct vnode *)fp->f_data)->v_mount;
	sp = &mp->mnt_stat;
	if ((error = VFS_STATVFS(mp, sp)) != 0)
		goto out;
	sp->f_flag = mp->mnt_flag & MNT_VISFLAGMASK;
	error = ultrixstatfs(sp, (void *)SCARG(uap, buf));
 out:
 	fd_putfile(SCARG(uap, fd));
	return error;
}