static int tap_dev_ioctl(int unit, u_long cmd, void *data, struct lwp *l) { struct tap_softc *sc = device_lookup_private(&tap_cd, unit); if (sc == NULL) return ENXIO; switch (cmd) { case FIONREAD: { struct ifnet *ifp = &sc->sc_ec.ec_if; struct mbuf *m; int s; s = splnet(); IFQ_POLL(&ifp->if_snd, m); if (m == NULL) *(int *)data = 0; else *(int *)data = m->m_pkthdr.len; splx(s); return 0; } case TIOCSPGRP: case FIOSETOWN: return fsetown(&sc->sc_pgid, cmd, data); case TIOCGPGRP: case FIOGETOWN: return fgetown(sc->sc_pgid, cmd, data); case FIOASYNC: if (*(int *)data) sc->sc_flags |= TAP_ASYNCIO; else sc->sc_flags &= ~TAP_ASYNCIO; return 0; case FIONBIO: if (*(int *)data) sc->sc_flags |= TAP_NBIO; else sc->sc_flags &= ~TAP_NBIO; return 0; #ifdef OTAPGIFNAME case OTAPGIFNAME: #endif case TAPGIFNAME: { struct ifreq *ifr = (struct ifreq *)data; struct ifnet *ifp = &sc->sc_ec.ec_if; strlcpy(ifr->ifr_name, ifp->if_xname, IFNAMSIZ); return 0; } default: return ENOTTY; } }
/*ARGSUSED*/ static int logioctl(struct cdev *dev, u_long com, caddr_t data, int flag, struct thread *td) { switch (com) { /* return number of characters immediately available */ case FIONREAD: *(int *)data = msgbuf_getcount(msgbufp); break; case FIONBIO: break; case FIOASYNC: mtx_lock(&msgbuf_lock); if (*(int *)data) logsoftc.sc_state |= LOG_ASYNC; else logsoftc.sc_state &= ~LOG_ASYNC; mtx_unlock(&msgbuf_lock); break; case FIOSETOWN: return (fsetown(*(int *)data, &logsoftc.sc_sigio)); case FIOGETOWN: *(int *)data = fgetown(&logsoftc.sc_sigio); break; /* This is deprecated, FIOSETOWN should be used instead. */ case TIOCSPGRP: return (fsetown(-(*(int *)data), &logsoftc.sc_sigio)); /* This is deprecated, FIOGETOWN should be used instead */ case TIOCGPGRP: *(int *)data = -fgetown(&logsoftc.sc_sigio); break; default: return (ENOTTY); } return (0); }
/*ARGSUSED*/ static int logioctl(struct dev_ioctl_args *ap) { long l; switch (ap->a_cmd) { case FIONREAD: /* return number of characters immediately available */ crit_enter(); l = msgbufp->msg_bufx - msgbufp->msg_bufr; crit_exit(); if (l < 0) l += msgbufp->msg_size; *(int *)ap->a_data = l; break; case FIOASYNC: if (*(int *)ap->a_data) logsoftc.sc_state |= LOG_ASYNC; else logsoftc.sc_state &= ~LOG_ASYNC; break; case FIOSETOWN: return (fsetown(*(int *)ap->a_data, &logsoftc.sc_sigio)); case FIOGETOWN: *(int *)ap->a_data = fgetown(&logsoftc.sc_sigio); break; /* This is deprecated, FIOSETOWN should be used instead. */ case TIOCSPGRP: return (fsetown(-(*(int *)ap->a_data), &logsoftc.sc_sigio)); /* This is deprecated, FIOGETOWN should be used instead */ case TIOCGPGRP: *(int *)ap->a_data = -fgetown(&logsoftc.sc_sigio); break; default: return (ENOTTY); } return (0); }
int _getown(int argc, char ** argv) { if(argc > 1) { int res = fgetown(argv[1]); if(res >= 0) { printf("User #%d is %s's owner\n", res, argv[1]); } else { printf("Invalid file? Try that again man.\n"); } } return 0; }
static int soo_ioctl(struct file *fp, u_long cmd, void *data, struct ucred *active_cred, struct thread *td) { struct socket *so = fp->f_data; int error = 0; switch (cmd) { case FIONBIO: SOCK_LOCK(so); if (*(int *)data) so->so_state |= SS_NBIO; else so->so_state &= ~SS_NBIO; SOCK_UNLOCK(so); break; case FIOASYNC: /* * XXXRW: This code separately acquires SOCK_LOCK(so) and * SOCKBUF_LOCK(&so->so_rcv) even though they are the same * mutex to avoid introducing the assumption that they are * the same. */ if (*(int *)data) { SOCK_LOCK(so); so->so_state |= SS_ASYNC; SOCK_UNLOCK(so); SOCKBUF_LOCK(&so->so_rcv); so->so_rcv.sb_flags |= SB_ASYNC; SOCKBUF_UNLOCK(&so->so_rcv); SOCKBUF_LOCK(&so->so_snd); so->so_snd.sb_flags |= SB_ASYNC; SOCKBUF_UNLOCK(&so->so_snd); } else { SOCK_LOCK(so); so->so_state &= ~SS_ASYNC; SOCK_UNLOCK(so); SOCKBUF_LOCK(&so->so_rcv); so->so_rcv.sb_flags &= ~SB_ASYNC; SOCKBUF_UNLOCK(&so->so_rcv); SOCKBUF_LOCK(&so->so_snd); so->so_snd.sb_flags &= ~SB_ASYNC; SOCKBUF_UNLOCK(&so->so_snd); } break; case FIONREAD: /* Unlocked read. */ *(int *)data = sbavail(&so->so_rcv); break; case FIONWRITE: /* Unlocked read. */ *(int *)data = sbavail(&so->so_snd); break; case FIONSPACE: /* Unlocked read. */ if ((so->so_snd.sb_hiwat < sbused(&so->so_snd)) || (so->so_snd.sb_mbmax < so->so_snd.sb_mbcnt)) *(int *)data = 0; else *(int *)data = sbspace(&so->so_snd); break; case FIOSETOWN: error = fsetown(*(int *)data, &so->so_sigio); break; case FIOGETOWN: *(int *)data = fgetown(&so->so_sigio); break; case SIOCSPGRP: error = fsetown(-(*(int *)data), &so->so_sigio); break; case SIOCGPGRP: *(int *)data = -fgetown(&so->so_sigio); break; case SIOCATMARK: /* Unlocked read. */ *(int *)data = (so->so_rcv.sb_state & SBS_RCVATMARK) != 0; break; default: /* * Interface/routing/protocol specific ioctls: interface and * routing ioctls should have a different entry since a * socket is unnecessary. */ if (IOCGROUP(cmd) == 'i') error = ifioctl(so, cmd, data, td); else if (IOCGROUP(cmd) == 'r') { CURVNET_SET(so->so_vnet); error = rtioctl_fib(cmd, data, so->so_fibnum); CURVNET_RESTORE(); } else { CURVNET_SET(so->so_vnet); error = ((*so->so_proto->pr_usrreqs->pru_control) (so, cmd, data, 0, td)); CURVNET_RESTORE(); } break; } return (error); }
/* * MPSAFE */ int soo_ioctl(struct file *fp, u_long cmd, caddr_t data, struct ucred *cred, struct sysmsg *msg) { struct socket *so; int error; so = (struct socket *)fp->f_data; switch (cmd) { case FIOASYNC: if (*(int *)data) { sosetstate(so, SS_ASYNC); atomic_set_int(&so->so_rcv.ssb_flags, SSB_ASYNC); atomic_set_int(&so->so_snd.ssb_flags, SSB_ASYNC); } else { soclrstate(so, SS_ASYNC); atomic_clear_int(&so->so_rcv.ssb_flags, SSB_ASYNC); atomic_clear_int(&so->so_snd.ssb_flags, SSB_ASYNC); } error = 0; break; case FIONREAD: *(int *)data = so->so_rcv.ssb_cc; error = 0; break; case FIOSETOWN: error = fsetown(*(int *)data, &so->so_sigio); break; case FIOGETOWN: *(int *)data = fgetown(&so->so_sigio); error = 0; break; case SIOCSPGRP: error = fsetown(-(*(int *)data), &so->so_sigio); break; case SIOCGPGRP: *(int *)data = -fgetown(&so->so_sigio); error = 0; break; case SIOCATMARK: *(int *)data = (so->so_state&SS_RCVATMARK) != 0; error = 0; break; default: /* * Interface/routing/protocol specific ioctls: * interface and routing ioctls should have a * different entry since a socket's unnecessary */ if (IOCGROUP(cmd) == 'i') { error = ifioctl(so, cmd, data, cred); } else if (IOCGROUP(cmd) == 'r') { error = rtioctl(cmd, data, cred); } else { error = so_pru_control_direct(so, cmd, data, NULL); } break; } return (error); }
/* ARGSUSED */ int bpfioctl(dev_t dev, u_long cmd, caddr_t addr, __unused int flags, struct proc *p) { struct bpf_d *d; int error = 0; lck_mtx_lock(bpf_mlock); d = bpf_dtab[minor(dev)]; if (d == 0 || d == (void *)1) { lck_mtx_unlock(bpf_mlock); return (ENXIO); } switch (cmd) { default: error = EINVAL; break; /* * Check for read packet available. */ case FIONREAD: { int n; n = d->bd_slen; if (d->bd_hbuf) n += d->bd_hlen; *(int *)addr = n; break; } case SIOCGIFADDR: { struct ifnet *ifp; if (d->bd_bif == 0) error = EINVAL; else { ifp = d->bd_bif->bif_ifp; error = ifnet_ioctl(ifp, 0, cmd, addr); } break; } /* * Get buffer len [for read()]. */ case BIOCGBLEN: *(u_int *)addr = d->bd_bufsize; break; /* * Set buffer length. */ case BIOCSBLEN: #if BSD < 199103 error = EINVAL; #else if (d->bd_bif != 0) error = EINVAL; else { u_int size = *(u_int *)addr; if (size > bpf_maxbufsize) *(u_int *)addr = size = bpf_maxbufsize; else if (size < BPF_MINBUFSIZE) *(u_int *)addr = size = BPF_MINBUFSIZE; d->bd_bufsize = size; } #endif break; /* * Set link layer read filter. */ case BIOCSETF32: { struct bpf_program32 *prg32 = (struct bpf_program32 *)addr; error = bpf_setf(d, prg32->bf_len, CAST_USER_ADDR_T(prg32->bf_insns)); break; } case BIOCSETF64: { struct bpf_program64 *prg64 = (struct bpf_program64 *)addr; error = bpf_setf(d, prg64->bf_len, prg64->bf_insns); break; } /* * Flush read packet buffer. */ case BIOCFLUSH: reset_d(d); break; /* * Put interface into promiscuous mode. */ case BIOCPROMISC: if (d->bd_bif == 0) { /* * No interface attached yet. */ error = EINVAL; break; } if (d->bd_promisc == 0) { lck_mtx_unlock(bpf_mlock); error = ifnet_set_promiscuous(d->bd_bif->bif_ifp, 1); lck_mtx_lock(bpf_mlock); if (error == 0) d->bd_promisc = 1; } break; /* * Get device parameters. */ case BIOCGDLT: if (d->bd_bif == 0) error = EINVAL; else *(u_int *)addr = d->bd_bif->bif_dlt; break; /* * Get a list of supported data link types. */ case BIOCGDLTLIST: if (d->bd_bif == NULL) { error = EINVAL; } else { error = bpf_getdltlist(d, (struct bpf_dltlist *)addr, p); } break; /* * Set data link type. */ case BIOCSDLT: if (d->bd_bif == NULL) error = EINVAL; else error = bpf_setdlt(d, *(u_int *)addr); break; /* * Get interface name. */ case BIOCGETIF: if (d->bd_bif == 0) error = EINVAL; else { struct ifnet *const ifp = d->bd_bif->bif_ifp; struct ifreq *const ifr = (struct ifreq *)addr; snprintf(ifr->ifr_name, sizeof(ifr->ifr_name), "%s%d", ifp->if_name, ifp->if_unit); } break; /* * Set interface. */ case BIOCSETIF: { ifnet_t ifp; ifp = ifunit(((struct ifreq *)addr)->ifr_name); if (ifp == NULL) error = ENXIO; else error = bpf_setif(d, ifp, 0); break; } /* * Set read timeout. */ case BIOCSRTIMEOUT: { struct BPF_TIMEVAL *_tv = (struct BPF_TIMEVAL *)addr; struct timeval tv; tv.tv_sec = _tv->tv_sec; tv.tv_usec = _tv->tv_usec; /* * Subtract 1 tick from tvtohz() since this isn't * a one-shot timer. */ if ((error = itimerfix(&tv)) == 0) d->bd_rtout = tvtohz(&tv) - 1; break; } /* * Get read timeout. */ case BIOCGRTIMEOUT: { struct BPF_TIMEVAL *tv = (struct BPF_TIMEVAL *)addr; tv->tv_sec = d->bd_rtout / hz; tv->tv_usec = (d->bd_rtout % hz) * tick; break; } /* * Get packet stats. */ case BIOCGSTATS: { struct bpf_stat *bs = (struct bpf_stat *)addr; bs->bs_recv = d->bd_rcount; bs->bs_drop = d->bd_dcount; break; } /* * Set immediate mode. */ case BIOCIMMEDIATE: d->bd_immediate = *(u_int *)addr; break; case BIOCVERSION: { struct bpf_version *bv = (struct bpf_version *)addr; bv->bv_major = BPF_MAJOR_VERSION; bv->bv_minor = BPF_MINOR_VERSION; break; } /* * Get "header already complete" flag */ case BIOCGHDRCMPLT: *(u_int *)addr = d->bd_hdrcmplt; break; /* * Set "header already complete" flag */ case BIOCSHDRCMPLT: d->bd_hdrcmplt = *(u_int *)addr ? 1 : 0; break; /* * Get "see sent packets" flag */ case BIOCGSEESENT: *(u_int *)addr = d->bd_seesent; break; /* * Set "see sent packets" flag */ case BIOCSSEESENT: d->bd_seesent = *(u_int *)addr; break; case FIONBIO: /* Non-blocking I/O */ break; case FIOASYNC: /* Send signal on receive packets */ d->bd_async = *(int *)addr; break; #ifndef __APPLE__ case FIOSETOWN: error = fsetown(*(int *)addr, &d->bd_sigio); break; case FIOGETOWN: *(int *)addr = fgetown(d->bd_sigio); break; /* This is deprecated, FIOSETOWN should be used instead. */ case TIOCSPGRP: error = fsetown(-(*(int *)addr), &d->bd_sigio); break; /* This is deprecated, FIOGETOWN should be used instead. */ case TIOCGPGRP: *(int *)addr = -fgetown(d->bd_sigio); break; #endif case BIOCSRSIG: /* Set receive signal */ { u_int sig; sig = *(u_int *)addr; if (sig >= NSIG) error = EINVAL; else d->bd_sig = sig; break; } case BIOCGRSIG: *(u_int *)addr = d->bd_sig; break; } lck_mtx_unlock(bpf_mlock); return (error); }
int soo_ioctl(file_t *fp, u_long cmd, void *data) { struct socket *so = fp->f_data; int error = 0; switch (cmd) { case FIONBIO: solock(so); if (*(int *)data) so->so_state |= SS_NBIO; else so->so_state &= ~SS_NBIO; sounlock(so); break; case FIOASYNC: solock(so); if (*(int *)data) { so->so_state |= SS_ASYNC; so->so_rcv.sb_flags |= SB_ASYNC; so->so_snd.sb_flags |= SB_ASYNC; } else { so->so_state &= ~SS_ASYNC; so->so_rcv.sb_flags &= ~SB_ASYNC; so->so_snd.sb_flags &= ~SB_ASYNC; } sounlock(so); break; case FIONREAD: *(int *)data = so->so_rcv.sb_cc; break; case FIONWRITE: *(int *)data = so->so_snd.sb_cc; break; case FIONSPACE: /* * See the comment around sbspace()'s definition * in sys/socketvar.h in face of counts about maximum * to understand the following test. We detect overflow * and return zero. */ solock(so); if ((so->so_snd.sb_hiwat < so->so_snd.sb_cc) || (so->so_snd.sb_mbmax < so->so_snd.sb_mbcnt)) *(int *)data = 0; else *(int *)data = sbspace(&so->so_snd); sounlock(so); break; case SIOCSPGRP: case FIOSETOWN: case TIOCSPGRP: error = fsetown(&so->so_pgid, cmd, data); break; case SIOCGPGRP: case FIOGETOWN: case TIOCGPGRP: error = fgetown(so->so_pgid, cmd, data); break; case SIOCATMARK: *(int *)data = (so->so_state&SS_RCVATMARK) != 0; break; default: /* * Interface/routing/protocol specific ioctls: * interface and routing ioctls should have a * different entry since a socket's unnecessary */ KERNEL_LOCK(1, NULL); if (IOCGROUP(cmd) == 'i') error = ifioctl(so, cmd, data, curlwp); else if (IOCGROUP(cmd) == 'r') error = rtioctl(cmd, data, curlwp); else { error = (*so->so_proto->pr_usrreq)(so, PRU_CONTROL, (struct mbuf *)cmd, (struct mbuf *)data, NULL, curlwp); } KERNEL_UNLOCK_ONE(NULL); break; } return error; }