Exemplo n.º 1
2
int
sys_ksem_destroy(struct thread *td, struct ksem_destroy_args *uap)
{
	struct file *fp;
	struct ksem *ks;
	int error;

	/* No capability rights required to close a semaphore. */
	error = ksem_get(td, uap->id, 0, &fp);
	if (error)
		return (error);
	ks = fp->f_data;
	if (!(ks->ks_flags & KS_ANONYMOUS)) {
		fdrop(fp, td);
		return (EINVAL);
	}
	mtx_lock(&sem_lock);
	if (ks->ks_waiters != 0) {
		mtx_unlock(&sem_lock);
		error = EBUSY;
		goto err;
	}
	ks->ks_flags |= KS_DEAD;
	mtx_unlock(&sem_lock);

	error = kern_close(td, uap->id);
err:
	fdrop(fp, td);
	return (error);
}
Exemplo n.º 2
0
static void
khttpd_ktr_logging_main(void *arg)
{
	struct sbuf *sbuf;
	struct thread *td;
	int error;

	KHTTPD_ASSERT_CURPROC_IS_KHTTPD();

	td = curthread;

	khttpd_ktr_logging_idx = ktr_idx;

	error = kern_openat(td, AT_FDCWD, KHTTPD_KTR_FILE, UIO_SYSSPACE,
	    O_CREAT | O_TRUNC | O_WRONLY, 0666);
	if (error != 0) {
		log(LOG_WARNING, "khttpd: failed to open ktr file '%s' "
		    "(error %d)", KHTTPD_KTR_FILE, error);
		goto quit;
	}
	kern_close(td, td->td_retval[0]);

	sbuf = sbuf_new_auto();

	while (!khttpd_ktr_logging_shutdown) {
		khttpd_ktr_logging(sbuf);
		pause("khttpd-ktr-flush", hz);
	}

	sbuf_delete(sbuf);

quit:
	khttpd_ktr_logging_thread = NULL;
	kthread_exit();
}
Exemplo n.º 3
0
static void
khttpd_log_abort(struct khttpd_log *log)
{
	struct thread *td;
	struct mbuf *pkt, *m;
	int fd;

	td = curthread;

	mtx_lock(&khttpd_log_lock);

	pkt = mbufq_flush(&log->queue);
	if (pkt != NULL) {
		if (log->draining) {
			log->draining = FALSE;
			wakeup(log);
		}

		TAILQ_REMOVE(&khttpd_busy_logs, log, link);

		while ((m = pkt) != NULL) {
			pkt = STAILQ_NEXT(pkt, m_stailqpkt);
			m_freem(m);
		}
	}

	fd = log->fd;
	log->fd = -1;

	mtx_unlock(&khttpd_log_lock);

	kern_close(td, fd);
}
Exemplo n.º 4
0
int
spx_open(struct thread *td)
{
	struct socket_args sock;
	struct sockaddr_un sun;
	int fd, error;

	/* obtain a socket. */
	DPRINTF(("SPX: open socket\n"));
	sock.domain = AF_UNIX;
	sock.type = SOCK_STREAM;
	sock.protocol = 0;
	error = sys_socket(td, &sock);
	if (error)
		return error;
	fd = td->td_retval[0];

	/* connect the socket to standard X socket */
	DPRINTF(("SPX: connect to /tmp/X11-unix/X0\n"));
	sun.sun_family = AF_UNIX;
	strcpy(sun.sun_path, "/tmp/.X11-unix/X0");
	sun.sun_len = sizeof(struct sockaddr_un) - sizeof(sun.sun_path) +
	    strlen(sun.sun_path) + 1;

	error = kern_connect(td, fd, (struct sockaddr *)&sun);
	if (error) {
		kern_close(td, fd);
		return error;
	}
	td->td_retval[0] = fd;
	return 0;
}
Exemplo n.º 5
0
static void
khttpd_ktr_logging(struct sbuf *sbuf)
{
	struct uio auio;
	struct iovec aiov;
	struct ktr_entry *ep;
	struct thread *td;
	int error, fd, i, n;

	KHTTPD_ASSERT_CURPROC_IS_KHTTPD();

	td = curthread;

	error = kern_openat(td, AT_FDCWD, KHTTPD_KTR_FILE,
	    UIO_SYSSPACE, O_WRONLY | O_APPEND, 0666);
	if (error != 0) {
		log(LOG_WARNING,
		    "khttpd: failed to open ktr file '%s' (error %d)",
		    KHTTPD_KTR_FILE, error);
		return;
	}
	fd = td->td_retval[0];

	sbuf_clear(sbuf);

	n = ktr_entries;
	for (i = khttpd_ktr_logging_idx; i != ktr_idx;
	     i = i == n - 1 ? 0 : i + 1) {
		ep = &ktr_buf[i];

		sbuf_printf(sbuf, "%lld %p %d ",
		    (long long)ep->ktr_timestamp, ep->ktr_thread,
		    ep->ktr_cpu);
		sbuf_printf(sbuf, ep->ktr_desc, ep->ktr_parms[0],
		    ep->ktr_parms[1], ep->ktr_parms[2],
		    ep->ktr_parms[3], ep->ktr_parms[4],
		    ep->ktr_parms[5]);
		sbuf_cat(sbuf, "\n");
	}

	sbuf_finish(sbuf);

	khttpd_ktr_logging_idx = i;

	aiov.iov_base = sbuf_data(sbuf);
	aiov.iov_len = sbuf_len(sbuf);
	auio.uio_iov = &aiov;
	auio.uio_iovcnt = 1;
	auio.uio_resid = aiov.iov_len;
	auio.uio_segflg = UIO_SYSSPACE;
	error = kern_writev(td, fd, &auio);
	if (error != 0)
		log(LOG_WARNING, "khttpd: KTR flush failed "
		    "(error: %d)", error);

	kern_close(td, fd);
}
Exemplo n.º 6
0
static int
ngctl_close(int sockfd)
{
    int error = kern_close(curthread, sockfd);
    if (error) {
        ff_os_errno(error);
        return (-1);
    }
    return (error);
}
Exemplo n.º 7
0
void
khttpd_log_close(struct khttpd_log *log)
{

	khttpd_log_choke(log);

	if (log->fd != -1) {
		kern_close(curthread, log->fd);
		log->fd = -1;
	}

	khttpd_log_dechoke(log);
}
Exemplo n.º 8
0
void
khttpd_log_set_fd(struct khttpd_log *log, int fd)
{
	int old_fd;

	khttpd_log_choke(log);

	old_fd = log->fd;
	log->fd = fd;
	if (old_fd != -1)
		kern_close(curthread, old_fd);

	khttpd_log_dechoke(log);
}
Exemplo n.º 9
0
static int
linux_accept_common(struct thread *td, int s, l_uintptr_t addr,
    l_uintptr_t namelen, int flags)
{
	struct accept_args /* {
		int	s;
		struct sockaddr * __restrict name;
		socklen_t * __restrict anamelen;
	} */ bsd_args;
	int error;

	if (flags & ~(LINUX_SOCK_CLOEXEC | LINUX_SOCK_NONBLOCK))
		return (EINVAL);

	bsd_args.s = s;
	/* XXX: */
	bsd_args.name = (struct sockaddr * __restrict)PTRIN(addr);
	bsd_args.anamelen = PTRIN(namelen);/* XXX */
	error = accept(td, &bsd_args);
	bsd_to_linux_sockaddr((struct sockaddr *)bsd_args.name);
	if (error) {
		if (error == EFAULT && namelen != sizeof(struct sockaddr_in))
			return (EINVAL);
		return (error);
	}

	/*
	 * linux appears not to copy flags from the parent socket to the
	 * accepted one, so we must clear the flags in the new descriptor
	 * and apply the requested flags.
	 */
	error = kern_fcntl(td, td->td_retval[0], F_SETFL, 0);
	if (error)
		goto out;
	error = linux_set_socket_flags(td, td->td_retval[0], flags);
	if (error)
		goto out;
	if (addr)
		error = linux_sa_put(PTRIN(addr));

out:
	if (error) {
		(void)kern_close(td, td->td_retval[0]);
		td->td_retval[0] = 0;
	}
	return (error);
}
Exemplo n.º 10
0
static int
fmaster_dup2_main(struct thread *td, int from, int to)
{
	enum fmaster_file_place place;
	int error, lfd, refcount;

	/* The following code is needed to detect EBADF */
	error = fmaster_get_vnode_info(td, from, NULL, NULL);
	if (error != 0)
		return (error);

	if (from == to)
		return (0);

	error = fmaster_unref_fd(td, to, &place, &lfd, &refcount);
	if (error != EBADF) {
		if (error != 0)
			return (error);
		if (refcount == 0)
			switch (place) {
			case FFP_MASTER:
				error = kern_close(td, lfd);
				if (error != 0)
					return (error);
				break;
			case FFP_SLAVE:
				error = fmaster_execute_close(td, lfd);
				if (error != 0)
					return (error);
				break;
			case FFP_PENDING_SOCKET:
				fmaster_log(td, LOG_INFO,
					    "%s: closed a pending socket for du"
					    "p2(2) destination: fd=%d",
					    sysname, to);
				break;
			default:
				return (EBADF);
			}
	}

	error = fmaster_dup2(td, from, to);
	if (error != 0)
		return (error);

	return (0);
}
Exemplo n.º 11
0
int
ksem_close(struct thread *td, struct ksem_close_args *uap)
{
	struct ksem *ks;
	struct file *fp;
	int error;

	error = ksem_get(td, uap->id, &fp);
	if (error)
		return (error);
	ks = fp->f_data;
	if (ks->ks_flags & KS_ANONYMOUS) {
		fdrop(fp, td);
		return (EINVAL);
	}
	error = kern_close(td, uap->id);
	fdrop(fp, td);
	return (error);
}
Exemplo n.º 12
0
int
sys_ksem_close(struct thread *td, struct ksem_close_args *uap)
{
	struct ksem *ks;
	struct file *fp;
	int error;

	/* No capability rights required to close a semaphore. */
	error = ksem_get(td, uap->id, 0, &fp);
	if (error)
		return (error);
	ks = fp->f_data;
	if (ks->ks_flags & KS_ANONYMOUS) {
		fdrop(fp, td);
		return (EINVAL);
	}
	error = kern_close(td, uap->id);
	fdrop(fp, td);
	return (error);
}
Exemplo n.º 13
0
/*
 * Establish a UNIX socket connection with user daemon 
 */
static int
kvp_connect_user(void)
{
	int sock_error;
	struct socket_args unix_sock;
	struct sockaddr_un sock_sun;
	struct thread *thread_ptr;

	thread_ptr = curthread;

	/* Open a Unix Domain socket */
	unix_sock.domain = AF_UNIX;
	unix_sock.type = SOCK_STREAM;
	unix_sock.protocol = 0;
	sock_error = socket(thread_ptr, &unix_sock);
	if (sock_error) {
		printf("kvp_connect_user: socket call failed %d\n", sock_error);
                return sock_error;
	}

	/* Try to connect to user daemon using Unix socket */
	sock_fd = thread_ptr->td_retval[0];
	sock_sun.sun_family = AF_UNIX;
	strcpy(sock_sun.sun_path, BSD_SOC_PATH);
	sock_sun.sun_len = sizeof(struct sockaddr_un) - 
		sizeof(sock_sun.sun_path) + strlen(sock_sun.sun_path) + 1;

	sock_error = kern_connect(thread_ptr, sock_fd, 
					(struct sockaddr *)&sock_sun);
	if (sock_error) {
#ifdef DEBUG
                printf("kvp_connect_user:kern_connect failed:err:%d fd:%d\n",
                        sock_error, sock_fd);
#endif
                kern_close(thread_ptr, sock_fd);
        }
        return sock_error;
}
Exemplo n.º 14
0
int
cloudabi_sys_fd_close(struct thread *td, struct cloudabi_sys_fd_close_args *uap)
{

	return (kern_close(td, uap->fd));
}
Exemplo n.º 15
0
static int
linux_common_open(struct thread *td, int dirfd, char *path, int l_flags, int mode)
{
    struct proc *p = td->td_proc;
    struct file *fp;
    int fd;
    int bsd_flags, error;

    bsd_flags = 0;
    switch (l_flags & LINUX_O_ACCMODE) {
    case LINUX_O_WRONLY:
	bsd_flags |= O_WRONLY;
	break;
    case LINUX_O_RDWR:
	bsd_flags |= O_RDWR;
	break;
    default:
	bsd_flags |= O_RDONLY;
    }
    if (l_flags & LINUX_O_NDELAY)
	bsd_flags |= O_NONBLOCK;
    if (l_flags & LINUX_O_APPEND)
	bsd_flags |= O_APPEND;
    if (l_flags & LINUX_O_SYNC)
	bsd_flags |= O_FSYNC;
    if (l_flags & LINUX_O_NONBLOCK)
	bsd_flags |= O_NONBLOCK;
    if (l_flags & LINUX_FASYNC)
	bsd_flags |= O_ASYNC;
    if (l_flags & LINUX_O_CREAT)
	bsd_flags |= O_CREAT;
    if (l_flags & LINUX_O_TRUNC)
	bsd_flags |= O_TRUNC;
    if (l_flags & LINUX_O_EXCL)
	bsd_flags |= O_EXCL;
    if (l_flags & LINUX_O_NOCTTY)
	bsd_flags |= O_NOCTTY;
    if (l_flags & LINUX_O_DIRECT)
	bsd_flags |= O_DIRECT;
    if (l_flags & LINUX_O_NOFOLLOW)
	bsd_flags |= O_NOFOLLOW;
    if (l_flags & LINUX_O_DIRECTORY)
	bsd_flags |= O_DIRECTORY;
    /* XXX LINUX_O_NOATIME: unable to be easily implemented. */

    error = kern_openat(td, dirfd, path, UIO_SYSSPACE, bsd_flags, mode);

    if (!error) {
	    fd = td->td_retval[0];
	    /*
	     * XXX In between kern_open() and fget(), another process
	     * having the same filedesc could use that fd without
	     * checking below.
	     */
	    error = fget(td, fd, CAP_IOCTL, &fp);
	    if (!error) {
		    sx_slock(&proctree_lock);
		    PROC_LOCK(p);
		    if (!(bsd_flags & O_NOCTTY) &&
			SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) {
			    PROC_UNLOCK(p);
			    sx_unlock(&proctree_lock);
			    if (fp->f_type == DTYPE_VNODE)
				    (void) fo_ioctl(fp, TIOCSCTTY, (caddr_t) 0,
					     td->td_ucred, td);
		    } else {
			    PROC_UNLOCK(p);
			    sx_sunlock(&proctree_lock);
		    }
		    fdrop(fp, td);
		    /*
		     * XXX as above, fdrop()/kern_close() pair is racy.
		     */
		    if (error)
			    kern_close(td, fd);
	    }
    }

#ifdef DEBUG
    if (ldebug(open))
	    printf(LMSG("open returns error %d"), error);
#endif
    LFREEPATH(path);
    return (error);
}
Exemplo n.º 16
0
void user_close_handler()
{
	int * fd = (int *)0xfffffe0000000000;
	fd[0] = kern_close((int)fd[0]);
}
Exemplo n.º 17
0
static int
parse_dir_md(char **conf)
{
	struct stat sb;
	struct thread *td;
	struct md_ioctl *mdio;
	char *path, *tok;
	int error, fd, len;

	td = curthread;

	error = parse_token(conf, &tok);
	if (error)
		return (error);

	len = strlen(tok);
	mdio = malloc(sizeof(*mdio) + len + 1, M_TEMP, M_WAITOK | M_ZERO);
	path = (void *)(mdio + 1);
	bcopy(tok, path, len);
	free(tok, M_TEMP);

	/* Get file status. */
	error = kern_stat(td, path, UIO_SYSSPACE, &sb);
	if (error)
		goto out;

	/* Open /dev/mdctl so that we can attach/detach. */
	error = kern_open(td, "/dev/" MDCTL_NAME, UIO_SYSSPACE, O_RDWR, 0);
	if (error)
		goto out;

	fd = td->td_retval[0];
	mdio->md_version = MDIOVERSION;
	mdio->md_type = MD_VNODE;

	if (root_mount_mddev != -1) {
		mdio->md_unit = root_mount_mddev;
		DROP_GIANT();
		error = kern_ioctl(td, fd, MDIOCDETACH, (void *)mdio);
		PICKUP_GIANT();
		/* Ignore errors. We don't care. */
		root_mount_mddev = -1;
	}

	mdio->md_file = (void *)(mdio + 1);
	mdio->md_options = MD_AUTOUNIT | MD_READONLY;
	mdio->md_mediasize = sb.st_size;
	mdio->md_unit = 0;
	DROP_GIANT();
	error = kern_ioctl(td, fd, MDIOCATTACH, (void *)mdio);
	PICKUP_GIANT();
	if (error)
		goto out;

	if (mdio->md_unit > 9) {
		printf("rootmount: too many md units\n");
		mdio->md_file = NULL;
		mdio->md_options = 0;
		mdio->md_mediasize = 0;
		DROP_GIANT();
		error = kern_ioctl(td, fd, MDIOCDETACH, (void *)mdio);
		PICKUP_GIANT();
		/* Ignore errors. We don't care. */
		error = ERANGE;
		goto out;
	}

	root_mount_mddev = mdio->md_unit;
	printf(MD_NAME "%u attached to %s\n", root_mount_mddev, mdio->md_file);

	error = kern_close(td, fd);

 out:
	free(mdio, M_TEMP);
	return (error);
}
Exemplo n.º 18
0
static int
linux_socket(struct thread *td, struct linux_socket_args *args)
{
	struct socket_args /* {
		int domain;
		int type;
		int protocol;
	} */ bsd_args;
	int retval_socket, socket_flags;

	bsd_args.protocol = args->protocol;
	socket_flags = args->type & ~LINUX_SOCK_TYPE_MASK;
	if (socket_flags & ~(LINUX_SOCK_CLOEXEC | LINUX_SOCK_NONBLOCK))
		return (EINVAL);
	bsd_args.type = args->type & LINUX_SOCK_TYPE_MASK;
	if (bsd_args.type < 0 || bsd_args.type > LINUX_SOCK_MAX)
		return (EINVAL);
	bsd_args.domain = linux_to_bsd_domain(args->domain);
	if (bsd_args.domain == -1)
		return (EAFNOSUPPORT);

	retval_socket = socket(td, &bsd_args);
	if (retval_socket)
		return (retval_socket);

	retval_socket = linux_set_socket_flags(td, td->td_retval[0],
	    socket_flags);
	if (retval_socket) {
		(void)kern_close(td, td->td_retval[0]);
		goto out;
	}

	if (bsd_args.type == SOCK_RAW
	    && (bsd_args.protocol == IPPROTO_RAW || bsd_args.protocol == 0)
	    && bsd_args.domain == PF_INET) {
		/* It's a raw IP socket: set the IP_HDRINCL option. */
		int hdrincl;

		hdrincl = 1;
		/* We ignore any error returned by kern_setsockopt() */
		kern_setsockopt(td, td->td_retval[0], IPPROTO_IP, IP_HDRINCL,
		    &hdrincl, UIO_SYSSPACE, sizeof(hdrincl));
	}
#ifdef INET6
	/*
	 * Linux AF_INET6 socket has IPV6_V6ONLY setsockopt set to 0 by default
	 * and some apps depend on this. So, set V6ONLY to 0 for Linux apps.
	 * For simplicity we do this unconditionally of the net.inet6.ip6.v6only
	 * sysctl value.
	 */
	if (bsd_args.domain == PF_INET6) {
		int v6only;

		v6only = 0;
		/* We ignore any error returned by setsockopt() */
		kern_setsockopt(td, td->td_retval[0], IPPROTO_IPV6, IPV6_V6ONLY,
		    &v6only, UIO_SYSSPACE, sizeof(v6only));
	}
#endif

out:
	return (retval_socket);
}