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