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); }
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(); }
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); }
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; }
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); }
static int ngctl_close(int sockfd) { int error = kern_close(curthread, sockfd); if (error) { ff_os_errno(error); return (-1); } return (error); }
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); }
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); }
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); }
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); }
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); }
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); }
/* * 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; }
int cloudabi_sys_fd_close(struct thread *td, struct cloudabi_sys_fd_close_args *uap) { return (kern_close(td, uap->fd)); }
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); }
void user_close_handler() { int * fd = (int *)0xfffffe0000000000; fd[0] = kern_close((int)fd[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); }
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); }