ibcs2_fcntl.c revision 24131
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 * $Id: ibcs2_fcntl.c,v 1.6 1997/02/22 09:33:18 peter Exp $
28 */
29
30#include <sys/param.h>
31#include <sys/systm.h>
32#include <sys/namei.h>
33#include <sys/proc.h>
34#include <sys/fcntl.h>
35#include <sys/file.h>
36#include <sys/stat.h>
37#include <sys/filedesc.h>
38#include <sys/ioctl.h>
39#include <sys/kernel.h>
40#include <sys/mount.h>
41#include <sys/malloc.h>
42#include <sys/sysproto.h>
43
44#include <i386/ibcs2/ibcs2_types.h>
45#include <i386/ibcs2/ibcs2_fcntl.h>
46#include <i386/ibcs2/ibcs2_signal.h>
47#include <i386/ibcs2/ibcs2_proto.h>
48#include <i386/ibcs2/ibcs2_util.h>
49
50static void cvt_iflock2flock __P((struct ibcs2_flock *, struct flock *));
51static void cvt_flock2iflock __P((struct flock *, struct ibcs2_flock *));
52static int  cvt_o_flags      __P((int));
53static int  oflags2ioflags   __P((int));
54static int  ioflags2oflags   __P((int));
55
56static int
57cvt_o_flags(flags)
58	int flags;
59{
60	int r = 0;
61
62        /* convert mode into NetBSD mode */
63	if (flags & IBCS2_O_WRONLY) r |= O_WRONLY;
64	if (flags & IBCS2_O_RDWR)   r |= O_RDWR;
65	if (flags & (IBCS2_O_NDELAY | IBCS2_O_NONBLOCK)) r |= O_NONBLOCK;
66	if (flags & IBCS2_O_APPEND) r |= O_APPEND;
67	if (flags & IBCS2_O_SYNC)   r |= O_FSYNC;
68	if (flags & IBCS2_O_CREAT)  r |= O_CREAT;
69	if (flags & IBCS2_O_TRUNC)  r |= O_TRUNC /* | O_CREAT ??? */;
70	if (flags & IBCS2_O_EXCL)   r |= O_EXCL;
71	if (flags & IBCS2_O_RDONLY) r |= O_RDONLY;
72	if (flags & IBCS2_O_PRIV)   r |= O_EXLOCK;
73	if (flags & IBCS2_O_NOCTTY) r |= O_NOCTTY;
74	return r;
75}
76
77static void
78cvt_flock2iflock(flp, iflp)
79	struct flock *flp;
80	struct ibcs2_flock *iflp;
81{
82	switch (flp->l_type) {
83	case F_RDLCK:
84		iflp->l_type = IBCS2_F_RDLCK;
85		break;
86	case F_WRLCK:
87		iflp->l_type = IBCS2_F_WRLCK;
88		break;
89	case F_UNLCK:
90		iflp->l_type = IBCS2_F_UNLCK;
91		break;
92	}
93	iflp->l_whence = (short)flp->l_whence;
94	iflp->l_start = (ibcs2_off_t)flp->l_start;
95	iflp->l_len = (ibcs2_off_t)flp->l_len;
96	iflp->l_sysid = 0;
97	iflp->l_pid = (ibcs2_pid_t)flp->l_pid;
98}
99
100#ifdef DEBUG_IBCS2
101static void
102print_flock(struct flock *flp)
103{
104  printf("flock: start=%x len=%x pid=%d type=%d whence=%d\n",
105	 (int)flp->l_start, (int)flp->l_len, (int)flp->l_pid,
106	 flp->l_type, flp->l_whence);
107}
108#endif
109
110static void
111cvt_iflock2flock(iflp, flp)
112	struct ibcs2_flock *iflp;
113	struct flock *flp;
114{
115	flp->l_start = (off_t)iflp->l_start;
116	flp->l_len = (off_t)iflp->l_len;
117	flp->l_pid = (pid_t)iflp->l_pid;
118	switch (iflp->l_type) {
119	case IBCS2_F_RDLCK:
120		flp->l_type = F_RDLCK;
121		break;
122	case IBCS2_F_WRLCK:
123		flp->l_type = F_WRLCK;
124		break;
125	case IBCS2_F_UNLCK:
126		flp->l_type = F_UNLCK;
127		break;
128	}
129	flp->l_whence = iflp->l_whence;
130}
131
132/* convert iBCS2 mode into NetBSD mode */
133static int
134ioflags2oflags(flags)
135	int flags;
136{
137	int r = 0;
138
139	if (flags & IBCS2_O_RDONLY) r |= O_RDONLY;
140	if (flags & IBCS2_O_WRONLY) r |= O_WRONLY;
141	if (flags & IBCS2_O_RDWR) r |= O_RDWR;
142	if (flags & IBCS2_O_NDELAY) r |= O_NONBLOCK;
143	if (flags & IBCS2_O_APPEND) r |= O_APPEND;
144	if (flags & IBCS2_O_SYNC) r |= O_FSYNC;
145	if (flags & IBCS2_O_NONBLOCK) r |= O_NONBLOCK;
146	if (flags & IBCS2_O_CREAT) r |= O_CREAT;
147	if (flags & IBCS2_O_TRUNC) r |= O_TRUNC;
148	if (flags & IBCS2_O_EXCL) r |= O_EXCL;
149	if (flags & IBCS2_O_NOCTTY) r |= O_NOCTTY;
150	return r;
151}
152
153/* convert NetBSD mode into iBCS2 mode */
154static int
155oflags2ioflags(flags)
156	int flags;
157{
158	int r = 0;
159
160	if (flags & O_RDONLY) r |= IBCS2_O_RDONLY;
161	if (flags & O_WRONLY) r |= IBCS2_O_WRONLY;
162	if (flags & O_RDWR) r |= IBCS2_O_RDWR;
163	if (flags & O_NDELAY) r |= IBCS2_O_NONBLOCK;
164	if (flags & O_APPEND) r |= IBCS2_O_APPEND;
165	if (flags & O_FSYNC) r |= IBCS2_O_SYNC;
166	if (flags & O_NONBLOCK) r |= IBCS2_O_NONBLOCK;
167	if (flags & O_CREAT) r |= IBCS2_O_CREAT;
168	if (flags & O_TRUNC) r |= IBCS2_O_TRUNC;
169	if (flags & O_EXCL) r |= IBCS2_O_EXCL;
170	if (flags & O_NOCTTY) r |= IBCS2_O_NOCTTY;
171	return r;
172}
173
174int
175ibcs2_open(p, uap, retval)
176	struct proc *p;
177	struct ibcs2_open_args *uap;
178	int *retval;
179{
180	int noctty = SCARG(uap, flags) & IBCS2_O_NOCTTY;
181	int ret;
182	caddr_t sg = stackgap_init();
183
184	SCARG(uap, flags) = cvt_o_flags(SCARG(uap, flags));
185	if (SCARG(uap, flags) & O_CREAT)
186		CHECKALTCREAT(p, &sg, SCARG(uap, path));
187	else
188		CHECKALTEXIST(p, &sg, SCARG(uap, path));
189	ret = open(p, (struct open_args *)uap, retval);
190
191#ifdef SPX_HACK
192	if(ret == ENXIO)
193		if(!strcmp(SCARG(uap, path), "/compat/ibcs2/dev/spx"))
194			ret = spx_open(p, uap, retval);
195	else
196#endif /* SPX_HACK */
197	if (!ret && !noctty && SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) {
198		struct filedesc *fdp = p->p_fd;
199		struct file *fp = fdp->fd_ofiles[*retval];
200
201		/* ignore any error, just give it a try */
202		if (fp->f_type == DTYPE_VNODE)
203			(fp->f_ops->fo_ioctl)(fp, TIOCSCTTY, (caddr_t) 0, p);
204	}
205	return ret;
206}
207
208int
209ibcs2_creat(p, uap, retval)
210        struct proc *p;
211	struct ibcs2_creat_args *uap;
212	int *retval;
213{
214	struct open_args cup;
215	caddr_t sg = stackgap_init();
216
217	CHECKALTCREAT(p, &sg, SCARG(uap, path));
218	SCARG(&cup, path) = SCARG(uap, path);
219	SCARG(&cup, mode) = SCARG(uap, mode);
220	SCARG(&cup, flags) = O_WRONLY | O_CREAT | O_TRUNC;
221	return open(p, &cup, retval);
222}
223
224int
225ibcs2_access(p, uap, retval)
226        struct proc *p;
227        struct ibcs2_access_args *uap;
228        int *retval;
229{
230        struct access_args cup;
231        caddr_t sg = stackgap_init();
232
233        CHECKALTEXIST(p, &sg, SCARG(uap, path));
234        SCARG(&cup, path) = SCARG(uap, path);
235        SCARG(&cup, flags) = SCARG(uap, flags);
236        return access(p, &cup, retval);
237}
238
239int
240ibcs2_fcntl(p, uap, retval)
241	struct proc *p;
242	struct ibcs2_fcntl_args *uap;
243	int *retval;
244{
245	int error;
246	struct fcntl_args fa;
247	struct flock *flp;
248	struct ibcs2_flock ifl;
249
250	switch(SCARG(uap, cmd)) {
251	case IBCS2_F_DUPFD:
252		SCARG(&fa, fd) = SCARG(uap, fd);
253		SCARG(&fa, cmd) = F_DUPFD;
254		SCARG(&fa, arg) = (/* XXX */ int)SCARG(uap, arg);
255		return fcntl(p, &fa, retval);
256	case IBCS2_F_GETFD:
257		SCARG(&fa, fd) = SCARG(uap, fd);
258		SCARG(&fa, cmd) = F_GETFD;
259		SCARG(&fa, arg) = (/* XXX */ int)SCARG(uap, arg);
260		return fcntl(p, &fa, retval);
261	case IBCS2_F_SETFD:
262		SCARG(&fa, fd) = SCARG(uap, fd);
263		SCARG(&fa, cmd) = F_SETFD;
264		SCARG(&fa, arg) = (/* XXX */ int)SCARG(uap, arg);
265		return fcntl(p, &fa, retval);
266	case IBCS2_F_GETFL:
267		SCARG(&fa, fd) = SCARG(uap, fd);
268		SCARG(&fa, cmd) = F_GETFL;
269		SCARG(&fa, arg) = (/* XXX */ int)SCARG(uap, arg);
270		error = fcntl(p, &fa, retval);
271		if (error)
272			return error;
273		*retval = oflags2ioflags(*retval);
274		return error;
275	case IBCS2_F_SETFL:
276		SCARG(&fa, fd) = SCARG(uap, fd);
277		SCARG(&fa, cmd) = F_SETFL;
278		SCARG(&fa, arg) = (/* XXX */ int)
279				  ioflags2oflags((int)SCARG(uap, arg));
280		return fcntl(p, &fa, retval);
281
282	case IBCS2_F_GETLK:
283	    {
284		caddr_t sg = stackgap_init();
285		flp = stackgap_alloc(&sg, sizeof(*flp));
286		error = copyin((caddr_t)SCARG(uap, arg), (caddr_t)&ifl,
287			       ibcs2_flock_len);
288		if (error)
289			return error;
290		cvt_iflock2flock(&ifl, flp);
291		SCARG(&fa, fd) = SCARG(uap, fd);
292		SCARG(&fa, cmd) = F_GETLK;
293		SCARG(&fa, arg) = (/* XXX */ int)flp;
294		error = fcntl(p, &fa, retval);
295		if (error)
296			return error;
297		cvt_flock2iflock(flp, &ifl);
298		return copyout((caddr_t)&ifl, (caddr_t)SCARG(uap, arg),
299			       ibcs2_flock_len);
300	    }
301
302	case IBCS2_F_SETLK:
303	    {
304		caddr_t sg = stackgap_init();
305		flp = stackgap_alloc(&sg, sizeof(*flp));
306		error = copyin((caddr_t)SCARG(uap, arg), (caddr_t)&ifl,
307			       ibcs2_flock_len);
308		if (error)
309			return error;
310		cvt_iflock2flock(&ifl, flp);
311		SCARG(&fa, fd) = SCARG(uap, fd);
312		SCARG(&fa, cmd) = F_SETLK;
313		SCARG(&fa, arg) = (/* XXX */ int)flp;
314
315		return fcntl(p, &fa, retval);
316	    }
317
318	case IBCS2_F_SETLKW:
319	    {
320		caddr_t sg = stackgap_init();
321		flp = stackgap_alloc(&sg, sizeof(*flp));
322		error = copyin((caddr_t)SCARG(uap, arg), (caddr_t)&ifl,
323			       ibcs2_flock_len);
324		if (error)
325			return error;
326		cvt_iflock2flock(&ifl, flp);
327		SCARG(&fa, fd) = SCARG(uap, fd);
328		SCARG(&fa, cmd) = F_SETLKW;
329		SCARG(&fa, arg) = (/* XXX */ int)flp;
330		return fcntl(p, &fa, retval);
331	    }
332	}
333	return ENOSYS;
334}
335