proc->thread stage 2: MAJOR revamping of system calls, ucred, jail API,
[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.3 2003/06/23 17:55:38 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(struct ibcs2_open_args *uap)
172 {
173         struct proc *p = curproc;
174         int noctty = SCARG(uap, flags) & IBCS2_O_NOCTTY;
175         int ret;
176         caddr_t sg = stackgap_init();
177
178         SCARG(uap, flags) = cvt_o_flags(SCARG(uap, flags));
179         if (SCARG(uap, flags) & O_CREAT)
180                 CHECKALTCREAT(&sg, SCARG(uap, path));
181         else
182                 CHECKALTEXIST(&sg, SCARG(uap, path));
183         ret = open((struct open_args *)uap);
184
185 #ifdef SPX_HACK
186         if (ret == ENXIO) {
187                 if (!strcmp(SCARG(uap, path), "/compat/ibcs2/dev/spx"))
188                         ret = spx_open(uap);
189         } else
190 #endif /* SPX_HACK */
191         if (!ret && !noctty && SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) {
192                 struct filedesc *fdp = p->p_fd;
193                 struct file *fp = fdp->fd_ofiles[p->p_retval[0]];
194
195                 /* ignore any error, just give it a try */
196                 if (fp->f_type == DTYPE_VNODE)
197                         fo_ioctl(fp, TIOCSCTTY, (caddr_t) 0, p);
198         }
199         return ret;
200 }
201
202 int
203 ibcs2_creat(struct ibcs2_creat_args *uap)
204 {       
205         struct open_args cup;   
206         caddr_t sg = stackgap_init();
207
208         CHECKALTCREAT(&sg, SCARG(uap, path));
209         SCARG(&cup, path) = SCARG(uap, path);
210         SCARG(&cup, mode) = SCARG(uap, mode);
211         SCARG(&cup, flags) = O_WRONLY | O_CREAT | O_TRUNC;
212         return open(&cup);
213 }       
214
215 int
216 ibcs2_access(struct ibcs2_access_args *uap)
217 {
218         struct access_args cup;
219         caddr_t sg = stackgap_init();
220
221         CHECKALTEXIST(&sg, SCARG(uap, path));
222         SCARG(&cup, path) = SCARG(uap, path);
223         SCARG(&cup, flags) = SCARG(uap, flags);
224         return access(&cup);
225 }
226
227 int
228 ibcs2_fcntl(struct ibcs2_fcntl_args *uap)
229 {
230         struct proc *p = curproc;
231         int error;
232         struct fcntl_args fa;
233         struct flock *flp;
234         struct ibcs2_flock ifl;
235         
236         switch(SCARG(uap, cmd)) {
237         case IBCS2_F_DUPFD:
238                 SCARG(&fa, fd) = SCARG(uap, fd);
239                 SCARG(&fa, cmd) = F_DUPFD;
240                 SCARG(&fa, arg) = (/* XXX */ int)SCARG(uap, arg);
241                 return fcntl(&fa);
242         case IBCS2_F_GETFD:
243                 SCARG(&fa, fd) = SCARG(uap, fd);
244                 SCARG(&fa, cmd) = F_GETFD;
245                 SCARG(&fa, arg) = (/* XXX */ int)SCARG(uap, arg);
246                 return fcntl(&fa);
247         case IBCS2_F_SETFD:
248                 SCARG(&fa, fd) = SCARG(uap, fd);
249                 SCARG(&fa, cmd) = F_SETFD;
250                 SCARG(&fa, arg) = (/* XXX */ int)SCARG(uap, arg);
251                 return fcntl(&fa);
252         case IBCS2_F_GETFL:
253                 SCARG(&fa, fd) = SCARG(uap, fd);
254                 SCARG(&fa, cmd) = F_GETFL;
255                 SCARG(&fa, arg) = (/* XXX */ int)SCARG(uap, arg);
256                 error = fcntl(&fa);
257                 if (error)
258                         return error;
259                 p->p_retval[0] = oflags2ioflags(p->p_retval[0]);
260                 return error;
261         case IBCS2_F_SETFL:
262                 SCARG(&fa, fd) = SCARG(uap, fd);
263                 SCARG(&fa, cmd) = F_SETFL;
264                 SCARG(&fa, arg) = (/* XXX */ int)
265                                   ioflags2oflags((int)SCARG(uap, arg));
266                 return fcntl(&fa);
267
268         case IBCS2_F_GETLK:
269             {
270                 caddr_t sg = stackgap_init();
271                 flp = stackgap_alloc(&sg, sizeof(*flp));
272                 error = copyin((caddr_t)SCARG(uap, arg), (caddr_t)&ifl,
273                                ibcs2_flock_len);
274                 if (error)
275                         return error;
276                 cvt_iflock2flock(&ifl, flp);
277                 SCARG(&fa, fd) = SCARG(uap, fd);
278                 SCARG(&fa, cmd) = F_GETLK;
279                 SCARG(&fa, arg) = (/* XXX */ int)flp;
280                 error = fcntl(&fa);
281                 if (error)
282                         return error;
283                 cvt_flock2iflock(flp, &ifl);
284                 return copyout((caddr_t)&ifl, (caddr_t)SCARG(uap, arg),
285                                ibcs2_flock_len);
286             }
287
288         case IBCS2_F_SETLK:
289             {
290                 caddr_t sg = stackgap_init();
291                 flp = stackgap_alloc(&sg, sizeof(*flp));
292                 error = copyin((caddr_t)SCARG(uap, arg), (caddr_t)&ifl,
293                                ibcs2_flock_len);
294                 if (error)
295                         return error;
296                 cvt_iflock2flock(&ifl, flp);
297                 SCARG(&fa, fd) = SCARG(uap, fd);
298                 SCARG(&fa, cmd) = F_SETLK;
299                 SCARG(&fa, arg) = (/* XXX */ int)flp;
300
301                 return fcntl(&fa);
302             }
303
304         case IBCS2_F_SETLKW:
305             {
306                 caddr_t sg = stackgap_init();
307                 flp = stackgap_alloc(&sg, sizeof(*flp));
308                 error = copyin((caddr_t)SCARG(uap, arg), (caddr_t)&ifl,
309                                ibcs2_flock_len);
310                 if (error)
311                         return error;
312                 cvt_iflock2flock(&ifl, flp);
313                 SCARG(&fa, fd) = SCARG(uap, fd);
314                 SCARG(&fa, cmd) = F_SETLKW;
315                 SCARG(&fa, arg) = (/* XXX */ int)flp;
316                 return fcntl(&fa);
317             }
318         }
319         return ENOSYS;
320 }