1/*- 2 * Copyright (c) 1998 Mark Newton 3 * Copyright (c) 1994 Christos Zoulas 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29#include <sys/cdefs.h> 30__FBSDID("$FreeBSD$"); 31 32#include <sys/param.h> 33#include <sys/proc.h> 34#include <sys/systm.h> 35#include <sys/capability.h> 36#include <sys/file.h> 37#include <sys/filio.h> 38#include <sys/lock.h> 39#include <sys/signal.h> 40#include <sys/filedesc.h> 41#include <sys/poll.h> 42#include <sys/malloc.h> 43#include <sys/mutex.h> 44 45#include <sys/sysproto.h> 46 47#include <compat/svr4/svr4.h> 48#include <compat/svr4/svr4_types.h> 49#include <compat/svr4/svr4_util.h> 50#include <compat/svr4/svr4_signal.h> 51#include <compat/svr4/svr4_proto.h> 52#include <compat/svr4/svr4_ioctl.h> 53#include <compat/svr4/svr4_filio.h> 54 55/*#define GROTTY_READ_HACK*/ 56 57int 58svr4_sys_poll(td, uap) 59 struct thread *td; 60 struct svr4_sys_poll_args *uap; 61{ 62 int error; 63 struct poll_args pa; 64 struct pollfd *pfd; 65 int idx = 0, cerr; 66 u_long siz; 67 68 if (uap->nfds > maxfilesperproc && uap->nfds > FD_SETSIZE) 69 return (EINVAL); 70 71 pa.fds = uap->fds; 72 pa.nfds = uap->nfds; 73 pa.timeout = uap->timeout; 74 75 siz = uap->nfds * sizeof(struct pollfd); 76 pfd = (struct pollfd *)malloc(siz, M_TEMP, M_WAITOK); 77 78 error = sys_poll(td, (struct poll_args *)uap); 79 80 if ((cerr = copyin(uap->fds, pfd, siz)) != 0) { 81 error = cerr; 82 goto done; 83 } 84 85 for (idx = 0; idx < uap->nfds; idx++) { 86 /* POLLWRNORM already equals POLLOUT, so we don't worry about that */ 87 if (pfd[idx].revents & (POLLOUT | POLLWRNORM | POLLWRBAND)) 88 pfd[idx].revents |= (POLLOUT | POLLWRNORM | POLLWRBAND); 89 } 90 if ((cerr = copyout(pfd, uap->fds, siz)) != 0) { 91 error = cerr; 92 goto done; /* yeah, I know it's the next line, but this way I won't 93 forget to update it if I add more code */ 94 } 95done: 96 free(pfd, M_TEMP); 97 return error; 98} 99 100#if defined(READ_TEST) 101int 102svr4_sys_read(td, uap) 103 struct thread *td; 104 struct svr4_sys_read_args *uap; 105{ 106 struct read_args ra; 107 cap_rights_t rights; 108 struct file *fp; 109 struct socket *so = NULL; 110 int so_state; 111 sigset_t sigmask; 112 int rv; 113 114 ra.fd = uap->fd; 115 ra.buf = uap->buf; 116 ra.nbyte = uap->nbyte; 117 118 if (fget(td, uap->fd, cap_rights_init(&rights, CAP_READ), &fp) != 0) { 119 DPRINTF(("Something fishy with the user-supplied file descriptor...\n")); 120 return EBADF; 121 } 122 123 if (fp->f_type == DTYPE_SOCKET) { 124 so = fp->f_data; 125 DPRINTF(("fd %d is a socket\n", uap->fd)); 126 if (so->so_state & SS_ASYNC) { 127 DPRINTF(("fd %d is an ASYNC socket!\n", uap->fd)); 128 } 129 DPRINTF(("Here are its flags: 0x%x\n", so->so_state)); 130#if defined(GROTTY_READ_HACK) 131 so_state = so->so_state; 132 so->so_state &= ~SS_NBIO; 133#endif 134 } 135 136 rv = read(td, &ra); 137 138 DPRINTF(("svr4_read(%d, 0x%0x, %d) = %d\n", 139 uap->fd, uap->buf, uap->nbyte, rv)); 140 if (rv == EAGAIN) { 141#ifdef DEBUG_SVR4 142 struct sigacts *ps; 143 144 PROC_LOCK(td->td_proc); 145 ps = td->td_proc->p_sigacts; 146 mtx_lock(&ps->ps_mtx); 147#endif 148 DPRINTF(("sigmask = 0x%x\n", td->td_sigmask)); 149 DPRINTF(("sigignore = 0x%x\n", ps->ps_sigignore)); 150 DPRINTF(("sigcaught = 0x%x\n", ps->ps_sigcatch)); 151 DPRINTF(("siglist = 0x%x\n", td->td_siglist)); 152#ifdef DEBUG_SVR4 153 mtx_unlock(&ps->ps_mtx); 154 PROC_UNLOCK(td->td_proc); 155#endif 156 } 157 158#if defined(GROTTY_READ_HACK) 159 if (so) { /* We've already checked to see if this is a socket */ 160 so->so_state = so_state; 161 } 162#endif 163 fdrop(fp, td); 164 165 return(rv); 166} 167#endif /* READ_TEST */ 168 169#if defined(BOGUS) 170int 171svr4_sys_write(td, uap) 172 struct thread *td; 173 struct svr4_sys_write_args *uap; 174{ 175 struct write_args wa; 176 struct file *fp; 177 int rv; 178 179 wa.fd = uap->fd; 180 wa.buf = uap->buf; 181 wa.nbyte = uap->nbyte; 182 183 rv = write(td, &wa); 184 185 DPRINTF(("svr4_write(%d, 0x%0x, %d) = %d\n", 186 uap->fd, uap->buf, uap->nbyte, rv)); 187 188 return(rv); 189} 190#endif /* BOGUS */ 191 192int 193svr4_fil_ioctl(fp, td, retval, fd, cmd, data) 194 struct file *fp; 195 struct thread *td; 196 register_t *retval; 197 int fd; 198 u_long cmd; 199 caddr_t data; 200{ 201 struct filedesc *fdp = td->td_proc->p_fd; 202 struct filedescent *fde; 203 int error, num; 204 205 *retval = 0; 206 207 switch (cmd) { 208 case SVR4_FIOCLEX: 209 FILEDESC_XLOCK(fdp); 210 fde = &fdp->fd_ofiles[fd]; 211 fde->fde_flags |= UF_EXCLOSE; 212 FILEDESC_XUNLOCK(fdp); 213 return 0; 214 215 case SVR4_FIONCLEX: 216 FILEDESC_XLOCK(fdp); 217 fde = &fdp->fd_ofiles[fd]; 218 fde->fde_flags &= ~UF_EXCLOSE; 219 FILEDESC_XUNLOCK(fdp); 220 return 0; 221 222 case SVR4_FIOGETOWN: 223 case SVR4_FIOSETOWN: 224 case SVR4_FIOASYNC: 225 case SVR4_FIONBIO: 226 case SVR4_FIONREAD: 227 if ((error = copyin(data, &num, sizeof(num))) != 0) 228 return error; 229 230 switch (cmd) { 231 case SVR4_FIOGETOWN: cmd = FIOGETOWN; break; 232 case SVR4_FIOSETOWN: cmd = FIOSETOWN; break; 233 case SVR4_FIOASYNC: cmd = FIOASYNC; break; 234 case SVR4_FIONBIO: cmd = FIONBIO; break; 235 case SVR4_FIONREAD: cmd = FIONREAD; break; 236 } 237 238#ifdef SVR4_DEBUG 239 if (cmd == FIOASYNC) DPRINTF(("FIOASYNC\n")); 240#endif 241 error = fo_ioctl(fp, cmd, (caddr_t) &num, td->td_ucred, td); 242 243 if (error) 244 return error; 245 246 return copyout(&num, data, sizeof(num)); 247 248 default: 249 DPRINTF(("Unknown svr4 filio %lx\n", cmd)); 250 return 0; /* ENOSYS really */ 251 } 252} 253