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