int svr4_sys_fcntl(struct lwp *l, const struct svr4_sys_fcntl_args *uap, register_t *retval) { struct sys_fcntl_args fa; register_t flags; struct svr4_flock64 ifl64; struct svr4_flock ifl; struct flock fl; int error; int cmd; SCARG(&fa, fd) = SCARG(uap, fd); SCARG(&fa, arg) = SCARG(uap, arg); switch (SCARG(uap, cmd)) { case SVR4_F_DUPFD: cmd = F_DUPFD; break; case SVR4_F_GETFD: cmd = F_GETFD; break; case SVR4_F_SETFD: cmd = F_SETFD; break; case SVR4_F_GETFL: cmd = F_GETFL; break; case SVR4_F_SETFL: /* * we must save the O_ASYNC flag, as that is * handled by ioctl(_, I_SETSIG, _) emulation. */ SCARG(&fa, cmd) = F_GETFL; if ((error = sys_fcntl(l, &fa, &flags)) != 0) return error; flags &= O_ASYNC; flags |= svr4_to_bsd_flags((u_long) SCARG(uap, arg)); cmd = F_SETFL; SCARG(&fa, arg) = (void *) flags; break; case SVR4_F_GETLK: cmd = F_GETLK; goto lock32; case SVR4_F_SETLK: cmd = F_SETLK; goto lock32; case SVR4_F_SETLKW: cmd = F_SETLKW; lock32: error = copyin(SCARG(uap, arg), &ifl, sizeof ifl); if (error) return error; svr4_to_bsd_flock(&ifl, &fl); error = do_fcntl_lock(SCARG(uap, fd), cmd, &fl); if (cmd != F_GETLK || error != 0) return error; bsd_to_svr4_flock(&fl, &ifl); return copyout(&ifl, SCARG(uap, arg), sizeof ifl); case SVR4_F_DUP2FD: { struct sys_dup2_args du; SCARG(&du, from) = SCARG(uap, fd); SCARG(&du, to) = (int)(u_long)SCARG(uap, arg); error = sys_dup2(l, &du, retval); if (error) return error; *retval = SCARG(&du, to); return 0; } case SVR4_F_FREESP: error = copyin(SCARG(uap, arg), &ifl, sizeof ifl); if (error) return error; svr4_to_bsd_flock(&ifl, &fl); return fd_truncate(l, SCARG(uap, fd), &fl, retval); case SVR4_F_GETLK64: cmd = F_GETLK; goto lock64; case SVR4_F_SETLK64: cmd = F_SETLK; goto lock64; case SVR4_F_SETLKW64: cmd = F_SETLKW; lock64: error = copyin(SCARG(uap, arg), &ifl64, sizeof ifl64); if (error) return error; svr4_to_bsd_flock64(&ifl64, &fl); error = do_fcntl_lock(SCARG(uap, fd), cmd, &fl); if (cmd != F_GETLK || error != 0) return error; bsd_to_svr4_flock64(&fl, &ifl64); return copyout(&ifl64, SCARG(uap, arg), sizeof ifl64); case SVR4_F_FREESP64: error = copyin(SCARG(uap, arg), &ifl64, sizeof ifl64); if (error) return error; svr4_to_bsd_flock64(&ifl64, &fl); return fd_truncate(l, SCARG(uap, fd), &fl, retval); case SVR4_F_REVOKE: return fd_revoke(l, SCARG(uap, fd), retval); default: return ENOSYS; } SCARG(&fa, cmd) = cmd; error = sys_fcntl(l, &fa, retval); if (error != 0) return error; switch (SCARG(uap, cmd)) { case SVR4_F_GETFL: *retval = bsd_to_svr4_flags(*retval); break; } return 0; }
int svr4_32_sock_ioctl(file_t *fp, struct lwp *l, register_t *retval, int fd, u_long cmd, void *data) { int error; int (*ctl)(file_t *, u_long, void *) = fp->f_ops->fo_ioctl; *retval = 0; switch (cmd) { case SVR4_SIOCGIFNUM: { struct ifnet *ifp; int ifnum = 0; int s; /* * This does not return the number of physical * interfaces (if_index), but the number of interfaces * + addresses like ifconf() does, because this number * is used by code that will call SVR4_SIOCGIFCONF to * find the space needed for SVR4_SIOCGIFCONF. So we * count the number of ifreq entries that the next * SVR4_SIOCGIFCONF will return. Maybe a more correct * fix is to make SVR4_SIOCGIFCONF return only one * entry per physical interface? */ s = pserialize_read_enter(); IFNET_READER_FOREACH(ifp) ifnum += svr4_count_ifnum(ifp); pserialize_read_exit(s); DPRINTF(("SIOCGIFNUM %d\n", ifnum)); return copyout(&ifnum, data, sizeof(ifnum)); } case SVR4_32_SIOCGIFFLAGS: { struct oifreq br; struct svr4_32_ifreq sr; if ((error = copyin(data, &sr, sizeof(sr))) != 0) return error; (void) strncpy(br.ifr_name, sr.svr4_ifr_name, sizeof(br.ifr_name)); if ((error = (*ctl)(fp, SIOCGIFFLAGS, &br)) != 0) { DPRINTF(("SIOCGIFFLAGS %s: error %d\n", sr.svr4_ifr_name, error)); return error; } sr.svr4_ifr_flags = bsd_to_svr4_flags(br.ifr_flags); DPRINTF(("SIOCGIFFLAGS %s = %x\n", sr.svr4_ifr_name, sr.svr4_ifr_flags)); return copyout(&sr, data, sizeof(sr)); } case SVR4_32_SIOCGIFCONF: { struct svr4_32_ifconf sc; struct oifconf ifc; if ((error = copyin(data, &sc, sizeof(sc))) != 0) return error; DPRINTF(("ifreq %ld svr4_32_ifreq %ld ifc_len %d\n", (unsigned long)sizeof(struct oifreq), (unsigned long)sizeof(struct svr4_32_ifreq), sc.svr4_32_ifc_len)); ifc.ifc_len = sc.svr4_32_ifc_len; ifc.ifc_buf = NETBSD32PTR64(sc.ifc_ifcu.ifcu_buf); if ((error = (*ctl)(fp, OOSIOCGIFCONF, &ifc)) != 0) return error; DPRINTF(("SIOCGIFCONF\n")); return 0; } default: DPRINTF(("Unknown svr4_32 sockio %lx\n", cmd)); return 0; /* ENOSYS really */ } }