svr4_filio.c revision 125454
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 125454 2004-02-04 21:52:57Z jhb $");
31
32#include <sys/param.h>
33#include <sys/proc.h>
34#include <sys/systm.h>
35#include <sys/file.h>
36#include <sys/filio.h>
37#include <sys/lock.h>
38#include <sys/signal.h>
39#include <sys/filedesc.h>
40#include <sys/poll.h>
41#include <sys/malloc.h>
42#include <sys/mutex.h>
43#include <sys/resource.h>
44#include <sys/resourcevar.h>
45
46#include <sys/sysproto.h>
47
48#include <compat/svr4/svr4.h>
49#include <compat/svr4/svr4_types.h>
50#include <compat/svr4/svr4_util.h>
51#include <compat/svr4/svr4_signal.h>
52#include <compat/svr4/svr4_proto.h>
53#include <compat/svr4/svr4_ioctl.h>
54#include <compat/svr4/svr4_filio.h>
55
56/*#define GROTTY_READ_HACK*/
57
58int
59svr4_sys_poll(td, uap)
60     struct thread *td;
61     struct svr4_sys_poll_args *uap;
62{
63     int error;
64     struct poll_args pa;
65     struct pollfd *pfd;
66     int idx = 0, cerr;
67     u_long siz;
68
69     PROC_LOCK(td->td_proc);
70     if (uap->nfds > lim_cur(td->td_proc, RLIMIT_NOFILE) &&
71       uap->nfds > FD_SETSIZE) {
72       PROC_UNLOCK(td->td_proc);
73       return (EINVAL);
74     }
75     PROC_UNLOCK(td->td_proc);
76
77     pa.fds = uap->fds;
78     pa.nfds = uap->nfds;
79     pa.timeout = uap->timeout;
80
81     siz = uap->nfds * sizeof(struct pollfd);
82     pfd = (struct pollfd *)malloc(siz, M_TEMP, M_WAITOK);
83
84     error = poll(td, (struct poll_args *)uap);
85
86     if ((cerr = copyin(uap->fds, pfd, siz)) != 0) {
87       error = cerr;
88       goto done;
89     }
90
91     for (idx = 0; idx < uap->nfds; idx++) {
92       /* 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	FILEDESC_LOCK(fdp);
213	switch (cmd) {
214	case SVR4_FIOCLEX:
215		fdp->fd_ofileflags[fd] |= UF_EXCLOSE;
216		FILEDESC_UNLOCK(fdp);
217		return 0;
218
219	case SVR4_FIONCLEX:
220		fdp->fd_ofileflags[fd] &= ~UF_EXCLOSE;
221		FILEDESC_UNLOCK(fdp);
222		return 0;
223
224	case SVR4_FIOGETOWN:
225	case SVR4_FIOSETOWN:
226	case SVR4_FIOASYNC:
227	case SVR4_FIONBIO:
228	case SVR4_FIONREAD:
229		FILEDESC_UNLOCK(fdp);
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		FILEDESC_UNLOCK(fdp);
253		DPRINTF(("Unknown svr4 filio %lx\n", cmd));
254		return 0;	/* ENOSYS really */
255	}
256}
257