svr4_filio.c revision 139743
156160Sru/*-
2146515Sru * Copyright (c) 1998 Mark Newton
321495Sjmacd * Copyright (c) 1994 Christos Zoulas
4146515Sru * All rights reserved.
521495Sjmacd *
621495Sjmacd * Redistribution and use in source and binary forms, with or without
721495Sjmacd * modification, are permitted provided that the following conditions
821495Sjmacd * are met:
921495Sjmacd * 1. Redistributions of source code must retain the above copyright
1021495Sjmacd *    notice, this list of conditions and the following disclaimer.
1121495Sjmacd * 2. Redistributions in binary form must reproduce the above copyright
1221495Sjmacd *    notice, this list of conditions and the following disclaimer in the
1321495Sjmacd *    documentation and/or other materials provided with the distribution.
1421495Sjmacd * 3. The name of the author may not be used to endorse or promote products
1521495Sjmacd *    derived from this software without specific prior written permission
1621495Sjmacd *
1721495Sjmacd * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1821495Sjmacd * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1921495Sjmacd * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2021495Sjmacd * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2121495Sjmacd * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2242660Smarkm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2342660Smarkm * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2421495Sjmacd * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2521495Sjmacd * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2621495Sjmacd * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2721495Sjmacd */
2821495Sjmacd
2921495Sjmacd#include <sys/cdefs.h>
3021495Sjmacd__FBSDID("$FreeBSD: head/sys/compat/svr4/svr4_filio.c 139743 2005-01-05 22:34:37Z imp $");
31146515Sru
3221495Sjmacd#include <sys/param.h>
3321495Sjmacd#include <sys/proc.h>
3421495Sjmacd#include <sys/systm.h>
35146515Sru#include <sys/file.h>
3621495Sjmacd#include <sys/filio.h>
3721495Sjmacd#include <sys/lock.h>
3821495Sjmacd#include <sys/signal.h>
3921495Sjmacd#include <sys/filedesc.h>
4021495Sjmacd#include <sys/poll.h>
4121495Sjmacd#include <sys/malloc.h>
4221495Sjmacd#include <sys/mutex.h>
4321495Sjmacd#include <sys/resource.h>
44146515Sru#include <sys/resourcevar.h>
4521495Sjmacd
4656160Sru#include <sys/sysproto.h>
4756160Sru
4856160Sru#include <compat/svr4/svr4.h>
49146515Sru#include <compat/svr4/svr4_types.h>
5056160Sru#include <compat/svr4/svr4_util.h>
5121495Sjmacd#include <compat/svr4/svr4_signal.h>
5221495Sjmacd#include <compat/svr4/svr4_proto.h>
5321495Sjmacd#include <compat/svr4/svr4_ioctl.h>
5421495Sjmacd#include <compat/svr4/svr4_filio.h>
55146515Sru
56146515Sru/*#define GROTTY_READ_HACK*/
5721495Sjmacd
58146515Sruint
59146515Srusvr4_sys_poll(td, uap)
6021495Sjmacd     struct thread *td;
61146515Sru     struct svr4_sys_poll_args *uap;
62146515Sru{
6321495Sjmacd     int error;
6421495Sjmacd     struct poll_args pa;
6521495Sjmacd     struct pollfd *pfd;
66146515Sru     int idx = 0, cerr;
6721495Sjmacd     u_long siz;
6821495Sjmacd
6921495Sjmacd     PROC_LOCK(td->td_proc);
7021495Sjmacd     if (uap->nfds > lim_cur(td->td_proc, RLIMIT_NOFILE) &&
7121495Sjmacd       uap->nfds > FD_SETSIZE) {
7221495Sjmacd       PROC_UNLOCK(td->td_proc);
7321495Sjmacd       return (EINVAL);
74146515Sru     }
7521495Sjmacd     PROC_UNLOCK(td->td_proc);
7656160Sru
77146515Sru     pa.fds = uap->fds;
7856160Sru     pa.nfds = uap->nfds;
7921495Sjmacd     pa.timeout = uap->timeout;
8021495Sjmacd
8142660Smarkm     siz = uap->nfds * sizeof(struct pollfd);
8221495Sjmacd     pfd = (struct pollfd *)malloc(siz, M_TEMP, M_WAITOK);
8321495Sjmacd
8421495Sjmacd     error = poll(td, (struct poll_args *)uap);
8521495Sjmacd
8621495Sjmacd     if ((cerr = copyin(uap->fds, pfd, siz)) != 0) {
8721495Sjmacd       error = cerr;
8821495Sjmacd       goto done;
8921495Sjmacd     }
9021495Sjmacd
9121495Sjmacd     for (idx = 0; idx < uap->nfds; idx++) {
9242660Smarkm       /* POLLWRNORM already equals POLLOUT, so we don't worry about that */
93       if (pfd[idx].revents & (POLLOUT | POLLWRNORM | POLLWRBAND))
94	    pfd[idx].revents |= (POLLOUT | POLLWRNORM | POLLWRBAND);
95     }
96     if ((cerr = copyout(pfd, uap->fds, siz)) != 0) {
97       error = cerr;
98       goto done;   /* yeah, I know it's the next line, but this way I won't
99		       forget to update it if I add more code */
100     }
101done:
102     free(pfd, M_TEMP);
103     return error;
104}
105
106#if defined(READ_TEST)
107int
108svr4_sys_read(td, uap)
109     struct thread *td;
110     struct svr4_sys_read_args *uap;
111{
112     struct read_args ra;
113     struct file *fp;
114     struct socket *so = NULL;
115     int so_state;
116     sigset_t sigmask;
117     int rv;
118
119     ra.fd = uap->fd;
120     ra.buf = uap->buf;
121     ra.nbyte = uap->nbyte;
122
123     if (fget(td, uap->fd, &fp) != 0) {
124       DPRINTF(("Something fishy with the user-supplied file descriptor...\n"));
125       return EBADF;
126     }
127
128     if (fp->f_type == DTYPE_SOCKET) {
129       so = fp->f_data;
130       DPRINTF(("fd %d is a socket\n", uap->fd));
131       if (so->so_state & SS_ASYNC) {
132	 DPRINTF(("fd %d is an ASYNC socket!\n", uap->fd));
133       }
134       DPRINTF(("Here are its flags: 0x%x\n", so->so_state));
135#if defined(GROTTY_READ_HACK)
136       so_state = so->so_state;
137       so->so_state &= ~SS_NBIO;
138#endif
139     }
140
141     rv = read(td, &ra);
142
143     DPRINTF(("svr4_read(%d, 0x%0x, %d) = %d\n",
144	     uap->fd, uap->buf, uap->nbyte, rv));
145     if (rv == EAGAIN) {
146#ifdef DEBUG_SVR4
147       struct sigacts *ps;
148
149       PROC_LOCK(td->td_proc);
150       ps = td->td_proc->p_sigacts;
151       mtx_lock(&ps->ps_mtx);
152#endif
153       DPRINTF(("sigmask = 0x%x\n", td->td_sigmask));
154       DPRINTF(("sigignore = 0x%x\n", ps->ps_sigignore));
155       DPRINTF(("sigcaught = 0x%x\n", ps->ps_sigcatch));
156       DPRINTF(("siglist = 0x%x\n", td->td_siglist));
157#ifdef DEBUG_SVR4
158       mtx_unlock(&ps->ps_mtx);
159       PROC_UNLOCK(td->td_proc);
160#endif
161     }
162
163#if defined(GROTTY_READ_HACK)
164     if (so) {  /* We've already checked to see if this is a socket */
165       so->so_state = so_state;
166     }
167#endif
168     fdrop(fp, td);
169
170     return(rv);
171}
172#endif /* READ_TEST */
173
174#if defined(BOGUS)
175int
176svr4_sys_write(td, uap)
177     struct thread *td;
178     struct svr4_sys_write_args *uap;
179{
180     struct write_args wa;
181     struct file *fp;
182     int rv;
183
184     wa.fd = uap->fd;
185     wa.buf = uap->buf;
186     wa.nbyte = uap->nbyte;
187
188     rv = write(td, &wa);
189
190     DPRINTF(("svr4_write(%d, 0x%0x, %d) = %d\n",
191	     uap->fd, uap->buf, uap->nbyte, rv));
192
193     return(rv);
194}
195#endif /* BOGUS */
196
197int
198svr4_fil_ioctl(fp, td, retval, fd, cmd, data)
199	struct file *fp;
200	struct thread *td;
201	register_t *retval;
202	int fd;
203	u_long cmd;
204	caddr_t data;
205{
206	int error;
207	int num;
208	struct filedesc *fdp = td->td_proc->p_fd;
209
210	*retval = 0;
211
212	switch (cmd) {
213	case SVR4_FIOCLEX:
214		FILEDESC_LOCK_FAST(fdp);
215		fdp->fd_ofileflags[fd] |= UF_EXCLOSE;
216		FILEDESC_UNLOCK_FAST(fdp);
217		return 0;
218
219	case SVR4_FIONCLEX:
220		FILEDESC_LOCK_FAST(fdp);
221		fdp->fd_ofileflags[fd] &= ~UF_EXCLOSE;
222		FILEDESC_UNLOCK_FAST(fdp);
223		return 0;
224
225	case SVR4_FIOGETOWN:
226	case SVR4_FIOSETOWN:
227	case SVR4_FIOASYNC:
228	case SVR4_FIONBIO:
229	case SVR4_FIONREAD:
230		if ((error = copyin(data, &num, sizeof(num))) != 0)
231			return error;
232
233		switch (cmd) {
234		case SVR4_FIOGETOWN:	cmd = FIOGETOWN; break;
235		case SVR4_FIOSETOWN:	cmd = FIOSETOWN; break;
236		case SVR4_FIOASYNC:	cmd = FIOASYNC;  break;
237		case SVR4_FIONBIO:	cmd = FIONBIO;   break;
238		case SVR4_FIONREAD:	cmd = FIONREAD;  break;
239		}
240
241#ifdef SVR4_DEBUG
242		if (cmd == FIOASYNC) DPRINTF(("FIOASYNC\n"));
243#endif
244		error = fo_ioctl(fp, cmd, (caddr_t) &num, td->td_ucred, td);
245
246		if (error)
247			return error;
248
249		return copyout(&num, data, sizeof(num));
250
251	default:
252		DPRINTF(("Unknown svr4 filio %lx\n", cmd));
253		return 0;	/* ENOSYS really */
254	}
255}
256