ibcs2_fcntl.c revision 76166
1/*
2 * Copyright (c) 1995 Scott Bartram
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 *    derived from this software without specific prior written permission
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 * $FreeBSD: head/sys/i386/ibcs2/ibcs2_fcntl.c 76166 2001-05-01 08:13:21Z markm $
28 */
29
30#include "opt_spx_hack.h"
31
32#include <sys/param.h>
33#include <sys/systm.h>
34#include <sys/fcntl.h>
35#include <sys/file.h>
36#include <sys/filedesc.h>
37#include <sys/lock.h>
38#include <sys/mutex.h>
39#include <sys/sysproto.h>
40#include <sys/ttycom.h>
41
42#include <i386/ibcs2/ibcs2_fcntl.h>
43#include <i386/ibcs2/ibcs2_signal.h>
44#include <i386/ibcs2/ibcs2_proto.h>
45#include <i386/ibcs2/ibcs2_util.h>
46
47static void cvt_iflock2flock __P((struct ibcs2_flock *, struct flock *));
48static void cvt_flock2iflock __P((struct flock *, struct ibcs2_flock *));
49static int  cvt_o_flags      __P((int));
50static int  oflags2ioflags   __P((int));
51static int  ioflags2oflags   __P((int));
52
53static int
54cvt_o_flags(flags)
55	int flags;
56{
57	int r = 0;
58
59        /* convert mode into NetBSD mode */
60	if (flags & IBCS2_O_WRONLY) r |= O_WRONLY;
61	if (flags & IBCS2_O_RDWR)   r |= O_RDWR;
62	if (flags & (IBCS2_O_NDELAY | IBCS2_O_NONBLOCK)) r |= O_NONBLOCK;
63	if (flags & IBCS2_O_APPEND) r |= O_APPEND;
64	if (flags & IBCS2_O_SYNC)   r |= O_FSYNC;
65	if (flags & IBCS2_O_CREAT)  r |= O_CREAT;
66	if (flags & IBCS2_O_TRUNC)  r |= O_TRUNC /* | O_CREAT ??? */;
67	if (flags & IBCS2_O_EXCL)   r |= O_EXCL;
68	if (flags & IBCS2_O_RDONLY) r |= O_RDONLY;
69	if (flags & IBCS2_O_PRIV)   r |= O_EXLOCK;
70	if (flags & IBCS2_O_NOCTTY) r |= O_NOCTTY;
71	return r;
72}
73
74static void
75cvt_flock2iflock(flp, iflp)
76	struct flock *flp;
77	struct ibcs2_flock *iflp;
78{
79	switch (flp->l_type) {
80	case F_RDLCK:
81		iflp->l_type = IBCS2_F_RDLCK;
82		break;
83	case F_WRLCK:
84		iflp->l_type = IBCS2_F_WRLCK;
85		break;
86	case F_UNLCK:
87		iflp->l_type = IBCS2_F_UNLCK;
88		break;
89	}
90	iflp->l_whence = (short)flp->l_whence;
91	iflp->l_start = (ibcs2_off_t)flp->l_start;
92	iflp->l_len = (ibcs2_off_t)flp->l_len;
93	iflp->l_sysid = 0;
94	iflp->l_pid = (ibcs2_pid_t)flp->l_pid;
95}
96
97#ifdef DEBUG_IBCS2
98static void
99print_flock(struct flock *flp)
100{
101  printf("flock: start=%x len=%x pid=%d type=%d whence=%d\n",
102	 (int)flp->l_start, (int)flp->l_len, (int)flp->l_pid,
103	 flp->l_type, flp->l_whence);
104}
105#endif
106
107static void
108cvt_iflock2flock(iflp, flp)
109	struct ibcs2_flock *iflp;
110	struct flock *flp;
111{
112	flp->l_start = (off_t)iflp->l_start;
113	flp->l_len = (off_t)iflp->l_len;
114	flp->l_pid = (pid_t)iflp->l_pid;
115	switch (iflp->l_type) {
116	case IBCS2_F_RDLCK:
117		flp->l_type = F_RDLCK;
118		break;
119	case IBCS2_F_WRLCK:
120		flp->l_type = F_WRLCK;
121		break;
122	case IBCS2_F_UNLCK:
123		flp->l_type = F_UNLCK;
124		break;
125	}
126	flp->l_whence = iflp->l_whence;
127}
128
129/* convert iBCS2 mode into NetBSD mode */
130static int
131ioflags2oflags(flags)
132	int flags;
133{
134	int r = 0;
135
136	if (flags & IBCS2_O_RDONLY) r |= O_RDONLY;
137	if (flags & IBCS2_O_WRONLY) r |= O_WRONLY;
138	if (flags & IBCS2_O_RDWR) r |= O_RDWR;
139	if (flags & IBCS2_O_NDELAY) r |= O_NONBLOCK;
140	if (flags & IBCS2_O_APPEND) r |= O_APPEND;
141	if (flags & IBCS2_O_SYNC) r |= O_FSYNC;
142	if (flags & IBCS2_O_NONBLOCK) r |= O_NONBLOCK;
143	if (flags & IBCS2_O_CREAT) r |= O_CREAT;
144	if (flags & IBCS2_O_TRUNC) r |= O_TRUNC;
145	if (flags & IBCS2_O_EXCL) r |= O_EXCL;
146	if (flags & IBCS2_O_NOCTTY) r |= O_NOCTTY;
147	return r;
148}
149
150/* convert NetBSD mode into iBCS2 mode */
151static int
152oflags2ioflags(flags)
153	int flags;
154{
155	int r = 0;
156
157	if (flags & O_RDONLY) r |= IBCS2_O_RDONLY;
158	if (flags & O_WRONLY) r |= IBCS2_O_WRONLY;
159	if (flags & O_RDWR) r |= IBCS2_O_RDWR;
160	if (flags & O_NDELAY) r |= IBCS2_O_NONBLOCK;
161	if (flags & O_APPEND) r |= IBCS2_O_APPEND;
162	if (flags & O_FSYNC) r |= IBCS2_O_SYNC;
163	if (flags & O_NONBLOCK) r |= IBCS2_O_NONBLOCK;
164	if (flags & O_CREAT) r |= IBCS2_O_CREAT;
165	if (flags & O_TRUNC) r |= IBCS2_O_TRUNC;
166	if (flags & O_EXCL) r |= IBCS2_O_EXCL;
167	if (flags & O_NOCTTY) r |= IBCS2_O_NOCTTY;
168	return r;
169}
170
171int
172ibcs2_open(p, uap)
173	struct proc *p;
174	struct ibcs2_open_args *uap;
175{
176	int noctty = SCARG(uap, flags) & IBCS2_O_NOCTTY;
177	int ret;
178	caddr_t sg = stackgap_init();
179
180	SCARG(uap, flags) = cvt_o_flags(SCARG(uap, flags));
181	if (SCARG(uap, flags) & O_CREAT)
182		CHECKALTCREAT(p, &sg, SCARG(uap, path));
183	else
184		CHECKALTEXIST(p, &sg, SCARG(uap, path));
185	ret = open(p, (struct open_args *)uap);
186
187#ifdef SPX_HACK
188	if (ret == ENXIO) {
189		if (!strcmp(SCARG(uap, path), "/compat/ibcs2/dev/spx"))
190			ret = spx_open(p, uap);
191	} else
192#endif /* SPX_HACK */
193	PROC_LOCK(p);
194	if (!ret && !noctty && SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) {
195		struct filedesc *fdp = p->p_fd;
196		struct file *fp = fdp->fd_ofiles[p->p_retval[0]];
197
198		PROC_UNLOCK(p);
199		/* ignore any error, just give it a try */
200		if (fp->f_type == DTYPE_VNODE)
201			fo_ioctl(fp, TIOCSCTTY, (caddr_t) 0, p);
202	} else
203		PROC_UNLOCK(p);
204	return ret;
205}
206
207int
208ibcs2_creat(p, uap)
209        struct proc *p;
210	struct ibcs2_creat_args *uap;
211{
212	struct open_args cup;
213	caddr_t sg = stackgap_init();
214
215	CHECKALTCREAT(p, &sg, SCARG(uap, path));
216	SCARG(&cup, path) = SCARG(uap, path);
217	SCARG(&cup, mode) = SCARG(uap, mode);
218	SCARG(&cup, flags) = O_WRONLY | O_CREAT | O_TRUNC;
219	return open(p, &cup);
220}
221
222int
223ibcs2_access(p, uap)
224        struct proc *p;
225        struct ibcs2_access_args *uap;
226{
227        struct access_args cup;
228        caddr_t sg = stackgap_init();
229
230        CHECKALTEXIST(p, &sg, SCARG(uap, path));
231        SCARG(&cup, path) = SCARG(uap, path);
232        SCARG(&cup, flags) = SCARG(uap, flags);
233        return access(p, &cup);
234}
235
236int
237ibcs2_fcntl(p, uap)
238	struct proc *p;
239	struct ibcs2_fcntl_args *uap;
240{
241	int error;
242	struct fcntl_args fa;
243	struct flock *flp;
244	struct ibcs2_flock ifl;
245
246	switch(SCARG(uap, cmd)) {
247	case IBCS2_F_DUPFD:
248		SCARG(&fa, fd) = SCARG(uap, fd);
249		SCARG(&fa, cmd) = F_DUPFD;
250		SCARG(&fa, arg) = (/* XXX */ int)SCARG(uap, arg);
251		return fcntl(p, &fa);
252	case IBCS2_F_GETFD:
253		SCARG(&fa, fd) = SCARG(uap, fd);
254		SCARG(&fa, cmd) = F_GETFD;
255		SCARG(&fa, arg) = (/* XXX */ int)SCARG(uap, arg);
256		return fcntl(p, &fa);
257	case IBCS2_F_SETFD:
258		SCARG(&fa, fd) = SCARG(uap, fd);
259		SCARG(&fa, cmd) = F_SETFD;
260		SCARG(&fa, arg) = (/* XXX */ int)SCARG(uap, arg);
261		return fcntl(p, &fa);
262	case IBCS2_F_GETFL:
263		SCARG(&fa, fd) = SCARG(uap, fd);
264		SCARG(&fa, cmd) = F_GETFL;
265		SCARG(&fa, arg) = (/* XXX */ int)SCARG(uap, arg);
266		error = fcntl(p, &fa);
267		if (error)
268			return error;
269		p->p_retval[0] = oflags2ioflags(p->p_retval[0]);
270		return error;
271	case IBCS2_F_SETFL:
272		SCARG(&fa, fd) = SCARG(uap, fd);
273		SCARG(&fa, cmd) = F_SETFL;
274		SCARG(&fa, arg) = (/* XXX */ int)
275				  ioflags2oflags((int)SCARG(uap, arg));
276		return fcntl(p, &fa);
277
278	case IBCS2_F_GETLK:
279	    {
280		caddr_t sg = stackgap_init();
281		flp = stackgap_alloc(&sg, sizeof(*flp));
282		error = copyin((caddr_t)SCARG(uap, arg), (caddr_t)&ifl,
283			       ibcs2_flock_len);
284		if (error)
285			return error;
286		cvt_iflock2flock(&ifl, flp);
287		SCARG(&fa, fd) = SCARG(uap, fd);
288		SCARG(&fa, cmd) = F_GETLK;
289		SCARG(&fa, arg) = (/* XXX */ int)flp;
290		error = fcntl(p, &fa);
291		if (error)
292			return error;
293		cvt_flock2iflock(flp, &ifl);
294		return copyout((caddr_t)&ifl, (caddr_t)SCARG(uap, arg),
295			       ibcs2_flock_len);
296	    }
297
298	case IBCS2_F_SETLK:
299	    {
300		caddr_t sg = stackgap_init();
301		flp = stackgap_alloc(&sg, sizeof(*flp));
302		error = copyin((caddr_t)SCARG(uap, arg), (caddr_t)&ifl,
303			       ibcs2_flock_len);
304		if (error)
305			return error;
306		cvt_iflock2flock(&ifl, flp);
307		SCARG(&fa, fd) = SCARG(uap, fd);
308		SCARG(&fa, cmd) = F_SETLK;
309		SCARG(&fa, arg) = (/* XXX */ int)flp;
310
311		return fcntl(p, &fa);
312	    }
313
314	case IBCS2_F_SETLKW:
315	    {
316		caddr_t sg = stackgap_init();
317		flp = stackgap_alloc(&sg, sizeof(*flp));
318		error = copyin((caddr_t)SCARG(uap, arg), (caddr_t)&ifl,
319			       ibcs2_flock_len);
320		if (error)
321			return error;
322		cvt_iflock2flock(&ifl, flp);
323		SCARG(&fa, fd) = SCARG(uap, fd);
324		SCARG(&fa, cmd) = F_SETLKW;
325		SCARG(&fa, arg) = (/* XXX */ int)flp;
326		return fcntl(p, &fa);
327	    }
328	}
329	return ENOSYS;
330}
331