svr4_filio.c revision 224778
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: head/sys/compat/svr4/svr4_filio.c 224778 2011-08-11 12:30:23Z rwatson $"); 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 = 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 struct file *fp; 108 struct socket *so = NULL; 109 int so_state; 110 sigset_t sigmask; 111 int rv; 112 113 ra.fd = uap->fd; 114 ra.buf = uap->buf; 115 ra.nbyte = uap->nbyte; 116 117 if (fget(td, uap->fd, CAP_READ, &fp) != 0) { 118 DPRINTF(("Something fishy with the user-supplied file descriptor...\n")); 119 return EBADF; 120 } 121 122 if (fp->f_type == DTYPE_SOCKET) { 123 so = fp->f_data; 124 DPRINTF(("fd %d is a socket\n", uap->fd)); 125 if (so->so_state & SS_ASYNC) { 126 DPRINTF(("fd %d is an ASYNC socket!\n", uap->fd)); 127 } 128 DPRINTF(("Here are its flags: 0x%x\n", so->so_state)); 129#if defined(GROTTY_READ_HACK) 130 so_state = so->so_state; 131 so->so_state &= ~SS_NBIO; 132#endif 133 } 134 135 rv = read(td, &ra); 136 137 DPRINTF(("svr4_read(%d, 0x%0x, %d) = %d\n", 138 uap->fd, uap->buf, uap->nbyte, rv)); 139 if (rv == EAGAIN) { 140#ifdef DEBUG_SVR4 141 struct sigacts *ps; 142 143 PROC_LOCK(td->td_proc); 144 ps = td->td_proc->p_sigacts; 145 mtx_lock(&ps->ps_mtx); 146#endif 147 DPRINTF(("sigmask = 0x%x\n", td->td_sigmask)); 148 DPRINTF(("sigignore = 0x%x\n", ps->ps_sigignore)); 149 DPRINTF(("sigcaught = 0x%x\n", ps->ps_sigcatch)); 150 DPRINTF(("siglist = 0x%x\n", td->td_siglist)); 151#ifdef DEBUG_SVR4 152 mtx_unlock(&ps->ps_mtx); 153 PROC_UNLOCK(td->td_proc); 154#endif 155 } 156 157#if defined(GROTTY_READ_HACK) 158 if (so) { /* We've already checked to see if this is a socket */ 159 so->so_state = so_state; 160 } 161#endif 162 fdrop(fp, td); 163 164 return(rv); 165} 166#endif /* READ_TEST */ 167 168#if defined(BOGUS) 169int 170svr4_sys_write(td, uap) 171 struct thread *td; 172 struct svr4_sys_write_args *uap; 173{ 174 struct write_args wa; 175 struct file *fp; 176 int rv; 177 178 wa.fd = uap->fd; 179 wa.buf = uap->buf; 180 wa.nbyte = uap->nbyte; 181 182 rv = write(td, &wa); 183 184 DPRINTF(("svr4_write(%d, 0x%0x, %d) = %d\n", 185 uap->fd, uap->buf, uap->nbyte, rv)); 186 187 return(rv); 188} 189#endif /* BOGUS */ 190 191int 192svr4_fil_ioctl(fp, td, retval, fd, cmd, data) 193 struct file *fp; 194 struct thread *td; 195 register_t *retval; 196 int fd; 197 u_long cmd; 198 caddr_t data; 199{ 200 int error; 201 int num; 202 struct filedesc *fdp = td->td_proc->p_fd; 203 204 *retval = 0; 205 206 switch (cmd) { 207 case SVR4_FIOCLEX: 208 FILEDESC_XLOCK(fdp); 209 fdp->fd_ofileflags[fd] |= UF_EXCLOSE; 210 FILEDESC_XUNLOCK(fdp); 211 return 0; 212 213 case SVR4_FIONCLEX: 214 FILEDESC_XLOCK(fdp); 215 fdp->fd_ofileflags[fd] &= ~UF_EXCLOSE; 216 FILEDESC_XUNLOCK(fdp); 217 return 0; 218 219 case SVR4_FIOGETOWN: 220 case SVR4_FIOSETOWN: 221 case SVR4_FIOASYNC: 222 case SVR4_FIONBIO: 223 case SVR4_FIONREAD: 224 if ((error = copyin(data, &num, sizeof(num))) != 0) 225 return error; 226 227 switch (cmd) { 228 case SVR4_FIOGETOWN: cmd = FIOGETOWN; break; 229 case SVR4_FIOSETOWN: cmd = FIOSETOWN; break; 230 case SVR4_FIOASYNC: cmd = FIOASYNC; break; 231 case SVR4_FIONBIO: cmd = FIONBIO; break; 232 case SVR4_FIONREAD: cmd = FIONREAD; break; 233 } 234 235#ifdef SVR4_DEBUG 236 if (cmd == FIOASYNC) DPRINTF(("FIOASYNC\n")); 237#endif 238 error = fo_ioctl(fp, cmd, (caddr_t) &num, td->td_ucred, td); 239 240 if (error) 241 return error; 242 243 return copyout(&num, data, sizeof(num)); 244 245 default: 246 DPRINTF(("Unknown svr4 filio %lx\n", cmd)); 247 return 0; /* ENOSYS really */ 248 } 249} 250