1 /*-
2 * Copyright (c) 1994-1995 Søren Schmidt
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 * in this position and unchanged.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software withough specific prior written permission
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * $FreeBSD: src/sys/i386/linux/linux_file.c,v 1.7.4.4 1999/09/05 08:14:13 peter Exp $
29 */
30
31 #include <sys/param.h>
32 #include <sys/systm.h>
33 #include <sys/sysproto.h>
34 #include <sys/fcntl.h>
35 #include <sys/file.h>
36 #include <sys/filedesc.h>
37 #include <sys/proc.h>
38 #include <sys/ioctl.h>
39 #include <sys/vnode.h>
40 #include <sys/malloc.h>
41 #include <sys/dirent.h>
42 #include <sys/conf.h>
43 #include <sys/tty.h>
44
45 #include <i386/linux/linux.h>
46 #include <i386/linux/linux_proto.h>
47 #include <i386/linux/linux_util.h>
48
49 int
50 linux_creat(struct proc *p, struct linux_creat_args *args, int *retval)
51 {
52 struct open_args /* {
53 char *path;
54 int flags;
55 int mode;
56 } */ bsd_open_args;
57 caddr_t sg;
58
59 sg = stackgap_init();
60 CHECKALTCREAT(p, &sg, args->path);
61
62 #ifdef DEBUG
63 printf("Linux-emul(%d): creat(%s, %d)\n",
64 p->p_pid, args->path, args->mode);
65 #endif
66 bsd_open_args.path = args->path;
67 bsd_open_args.mode = args->mode;
68 bsd_open_args.flags = O_WRONLY | O_CREAT | O_TRUNC;
69 return open(p, &bsd_open_args, retval);
70 }
71
72 int
73 linux_open(struct proc *p, struct linux_open_args *args, int *retval)
74 {
75 struct open_args /* {
76 char *path;
77 int flags;
78 int mode;
79 } */ bsd_open_args;
80 int error;
81 caddr_t sg;
82
83 sg = stackgap_init();
84
85 if (args->flags & LINUX_O_CREAT)
86 CHECKALTCREAT(p, &sg, args->path);
87 else
88 CHECKALTEXIST(p, &sg, args->path);
89
90 #ifdef DEBUG
91 printf("Linux-emul(%d): open(%s, 0x%x, 0x%x)\n",
92 p->p_pid, args->path, args->flags, args->mode);
93 #endif
94 bsd_open_args.flags = 0;
95 if (args->flags & LINUX_O_RDONLY)
96 bsd_open_args.flags |= O_RDONLY;
97 if (args->flags & LINUX_O_WRONLY)
98 bsd_open_args.flags |= O_WRONLY;
99 if (args->flags & LINUX_O_RDWR)
100 bsd_open_args.flags |= O_RDWR;
101 if (args->flags & LINUX_O_NDELAY)
102 bsd_open_args.flags |= O_NONBLOCK;
103 if (args->flags & LINUX_O_APPEND)
104 bsd_open_args.flags |= O_APPEND;
105 if (args->flags & LINUX_O_SYNC)
106 bsd_open_args.flags |= O_FSYNC;
107 if (args->flags & LINUX_O_NONBLOCK)
108 bsd_open_args.flags |= O_NONBLOCK;
109 if (args->flags & LINUX_FASYNC)
110 bsd_open_args.flags |= O_ASYNC;
111 if (args->flags & LINUX_O_CREAT)
112 bsd_open_args.flags |= O_CREAT;
113 if (args->flags & LINUX_O_TRUNC)
114 bsd_open_args.flags |= O_TRUNC;
115 if (args->flags & LINUX_O_EXCL)
116 bsd_open_args.flags |= O_EXCL;
117 if (args->flags & LINUX_O_NOCTTY)
118 bsd_open_args.flags |= O_NOCTTY;
119 bsd_open_args.path = args->path;
120 bsd_open_args.mode = args->mode;
121
122 error = open(p, &bsd_open_args, retval);
123 if (!error && !(bsd_open_args.flags & O_NOCTTY) &&
124 SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) {
125 struct filedesc *fdp = p->p_fd;
126 struct file *fp = fdp->fd_ofiles[*retval];
127
128 if (fp->f_type == DTYPE_VNODE)
129 (fp->f_ops->fo_ioctl)(fp, TIOCSCTTY, (caddr_t) 0, p);
130 }
131 #ifdef DEBUG
132 printf("Linux-emul(%d): open returns error %d\n",
133 p->p_pid, error);
134 #endif
135 return error;
136 }
137
138 struct linux_flock {
139 short l_type;
140 short l_whence;
141 linux_off_t l_start;
142 linux_off_t l_len;
143 linux_pid_t l_pid;
144 };
145
146 static void
147 linux_to_bsd_flock(struct linux_flock *linux_flock, struct flock *bsd_flock)
148 {
149 switch (linux_flock->l_type) {
150 case LINUX_F_RDLCK:
151 bsd_flock->l_type = F_RDLCK;
152 break;
153 case LINUX_F_WRLCK:
154 bsd_flock->l_type = F_WRLCK;
155 break;
156 case LINUX_F_UNLCK:
157 bsd_flock->l_type = F_UNLCK;
158 break;
159 }
160 bsd_flock->l_whence = linux_flock->l_whence;
161 bsd_flock->l_start = (off_t)linux_flock->l_start;
162 bsd_flock->l_len = (off_t)linux_flock->l_len;
163 bsd_flock->l_pid = (pid_t)linux_flock->l_pid;
164 }
165
166 static void
167 bsd_to_linux_flock(struct flock *bsd_flock, struct linux_flock *linux_flock)
168 {
169 switch (bsd_flock->l_type) {
170 case F_RDLCK:
171 linux_flock->l_type = LINUX_F_RDLCK;
172 break;
173 case F_WRLCK:
174 linux_flock->l_type = LINUX_F_WRLCK;
175 break;
176 case F_UNLCK:
177 linux_flock->l_type = LINUX_F_UNLCK;
178 break;
179 }
180 linux_flock->l_whence = bsd_flock->l_whence;
181 linux_flock->l_start = (linux_off_t)bsd_flock->l_start;
182 linux_flock->l_len = (linux_off_t)bsd_flock->l_len;
183 linux_flock->l_pid = (linux_pid_t)bsd_flock->l_pid;
184 }
185
186 int
187 linux_fcntl(struct proc *p, struct linux_fcntl_args *args, int *retval)
188 {
189 int error, result;
190 struct fcntl_args /* {
191 int fd;
192 int cmd;
193 int arg;
194 } */ fcntl_args;
195 struct linux_flock linux_flock;
196 struct flock *bsd_flock;
197 struct filedesc *fdp;
198 struct file *fp;
199 struct vnode *vp;
200 struct vattr va;
201 long pgid;
202 struct pgrp *pgrp;
203 struct tty *tp, *(*d_tty) __P((dev_t));
204 caddr_t sg;
205
206 sg = stackgap_init();
207 bsd_flock = (struct flock *)stackgap_alloc(&sg, sizeof(struct flock));
208 d_tty = NULL;
209
210 #ifdef DEBUG
211 printf("Linux-emul(%d): fcntl(%d, %08x, *)\n",
212 p->p_pid, args->fd, args->cmd);
213 #endif
214 fcntl_args.fd = args->fd;
215 fcntl_args.arg = 0;
216
217 switch (args->cmd) {
218 case LINUX_F_DUPFD:
219 fcntl_args.cmd = F_DUPFD;
220 return fcntl(p, &fcntl_args, retval);
221
222 case LINUX_F_GETFD:
223 fcntl_args.cmd = F_GETFD;
224 return fcntl(p, &fcntl_args, retval);
225
226 case LINUX_F_SETFD:
227 fcntl_args.cmd = F_SETFD;
228 return fcntl(p, &fcntl_args, retval);
229
230 case LINUX_F_GETFL:
231 fcntl_args.cmd = F_GETFL;
232 error = fcntl(p, &fcntl_args, &result);
233 *retval = 0;
234 if (result & O_RDONLY) *retval |= LINUX_O_RDONLY;
235 if (result & O_WRONLY) *retval |= LINUX_O_WRONLY;
236 if (result & O_RDWR) *retval |= LINUX_O_RDWR;
237 if (result & O_NDELAY) *retval |= LINUX_O_NONBLOCK;
238 if (result & O_APPEND) *retval |= LINUX_O_APPEND;
239 if (result & O_FSYNC) *retval |= LINUX_O_SYNC;
240 return error;
241
242 case LINUX_F_SETFL:
243 if (args->arg & LINUX_O_NDELAY) fcntl_args.arg |= O_NONBLOCK;
244 if (args->arg & LINUX_O_APPEND) fcntl_args.arg |= O_APPEND;
245 if (args->arg & LINUX_O_SYNC) fcntl_args.arg |= O_FSYNC;
246 fcntl_args.cmd = F_SETFL;
247 return fcntl(p, &fcntl_args, retval);
248
249 case LINUX_F_GETLK:
250 if ((error = copyin((caddr_t)args->arg, (caddr_t)&linux_flock,
251 sizeof(struct linux_flock))))
252 return error;
253 linux_to_bsd_flock(&linux_flock, bsd_flock);
254 fcntl_args.cmd = F_GETLK;
255 fcntl_args.arg = (int)bsd_flock;
256 if (error = fcntl(p, &fcntl_args, retval))
257 return error;
258 bsd_to_linux_flock(bsd_flock, &linux_flock);
259 return copyout((caddr_t)&linux_flock, (caddr_t)args->arg,
260 sizeof(struct linux_flock));
261
262 case LINUX_F_SETLK:
263 if ((error = copyin((caddr_t)args->arg, (caddr_t)&linux_flock,
264 sizeof(struct linux_flock))))
265 return error;
266 linux_to_bsd_flock(&linux_flock, bsd_flock);
267 fcntl_args.cmd = F_SETLK;
268 fcntl_args.arg = (int)bsd_flock;
269 return fcntl(p, &fcntl_args, retval);
270
271 case LINUX_F_SETLKW:
272 if ((error = copyin((caddr_t)args->arg, (caddr_t)&linux_flock,
273 sizeof(struct linux_flock))))
274 return error;
275 linux_to_bsd_flock(&linux_flock, bsd_flock);
276 fcntl_args.cmd = F_SETLKW;
277 fcntl_args.arg = (int)bsd_flock;
278 return fcntl(p, &fcntl_args, retval);
279
280 case LINUX_F_SETOWN:
281 case LINUX_F_GETOWN:
282 /*
283 * We need to route around the normal fcntl() for these calls,
284 * since it uses TIOC{G,S}PGRP, which is too restrictive for
285 * Linux F_{G,S}ETOWN semantics. For sockets, this problem
286 * does not exist.
287 */
288 fdp = p->p_fd;
289 if ((u_int)args->fd >= fdp->fd_nfiles ||
290 (fp = fdp->fd_ofiles[args->fd]) == NULL)
291 return EBADF;
292 if (fp->f_type == DTYPE_SOCKET) {
293 fcntl_args.cmd = args->cmd == LINUX_F_SETOWN ? F_SETOWN : F_GETOWN;
294 return fcntl(p, &fcntl_args, retval);
295 }
296 vp = (struct vnode *)fp->f_data;
297 if (vp->v_type != VCHR)
298 return EINVAL;
299 if ((error = VOP_GETATTR(vp, &va, p->p_ucred, p)))
300 return error;
301
302 d_tty = cdevsw[major(va.va_rdev)]->d_devtotty;
303 if (!d_tty || (!(tp = (*d_tty)(va.va_rdev))))
304 return EINVAL;
305 if (args->cmd == LINUX_F_GETOWN) {
306 retval[0] = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID;
307 return 0;
308 }
309 if ((long)args->arg <= 0) {
310 pgid = -(long)args->arg;
311 } else {
312 struct proc *p1 = pfind((long)args->arg);
313 if (p1 == 0)
314 return (ESRCH);
315 pgid = (long)p1->p_pgrp->pg_id;
316 }
317 pgrp = pgfind(pgid);
318 if (pgrp == NULL || pgrp->pg_session != p->p_session)
319 return EPERM;
320 tp->t_pgrp = pgrp;
321 return 0;
322 }
323 return EINVAL;
324 }
325
326 int
327 linux_lseek(struct proc *p, struct linux_lseek_args *args, int *retval)
328 {
329
330 struct lseek_args /* {
331 int fd;
332 int pad;
333 off_t offset;
334 int whence;
335 } */ tmp_args;
336 int error;
337
338 #ifdef DEBUG
339 printf("Linux-emul(%d): lseek(%d, %d, %d)\n",
340 p->p_pid, args->fdes, args->off, args->whence);
341 #endif
342 tmp_args.fd = args->fdes;
343 tmp_args.offset = (off_t)args->off;
344 tmp_args.whence = args->whence;
345 error = lseek(p, &tmp_args, retval);
346 return error;
347 }
348
349 int
350 linux_llseek(struct proc *p, struct linux_llseek_args *args, int *retval)
351 {
352 struct lseek_args bsd_args;
353 int error;
354 off_t off;
355
356 #ifdef DEBUG
357 printf("Linux-emul(%d): llseek(%d, %d:%d, %d)\n",
358 p->p_pid, args->fd, args->ohigh, args->olow, args->whence);
359 #endif
360 off = (args->olow) | (((off_t) args->ohigh) << 32);
361
362 bsd_args.fd = args->fd;
363 bsd_args.offset = off;
364 bsd_args.whence = args->whence;
365
366 if ((error = lseek(p, &bsd_args, retval)))
367 return error;
368
369 if ((error = copyout(retval, (caddr_t)args->res, sizeof (off_t))))
370 return error;
371
372 retval[0] = 0;
373 return 0;
374 }
375
376
377 struct linux_dirent {
378 long dino;
379 linux_off_t doff;
380 unsigned short dreclen;
381 char dname[LINUX_NAME_MAX + 1];
382 };
383
384 #define LINUX_RECLEN(de,namlen) \
385 ALIGN((((char *)&(de)->dname - (char *)de) + (namlen) + 1))
386
387 int
388 linux_readdir(struct proc *p, struct linux_readdir_args *args, int *retval)
389 {
390 struct linux_getdents_args lda;
391
392 lda.fd = args->fd;
393 lda.dent = args->dent;
394 lda.count = 1;
395 return linux_getdents(p, &lda, retval);
396 }
397
398 int
399 linux_getdents(struct proc *p, struct linux_getdents_args *args, int *retval)
400 {
401 register struct dirent *bdp;
402 struct vnode *vp;
403 caddr_t inp, buf; /* BSD-format */
404 int len, reclen; /* BSD-format */
405 caddr_t outp; /* Linux-format */
406 int resid, linuxreclen=0; /* Linux-format */
407 struct file *fp;
408 struct uio auio;
409 struct iovec aiov;
410 struct vattr va;
411 off_t off;
412 struct linux_dirent linux_dirent;
413 int buflen, error, eofflag, nbytes, justone;
414 u_int *cookies = NULL, *cookiep;
415 int ncookies;
416
417 #ifdef DEBUG
418 printf("Linux-emul(%d): getdents(%d, *, %d)\n",
419 p->p_pid, args->fd, args->count);
420 #endif
421 if ((error = getvnode(p->p_fd, args->fd, &fp)) != 0) {
422 return (error);
423 }
424
425 if ((fp->f_flag & FREAD) == 0)
426 return (EBADF);
427
428 vp = (struct vnode *) fp->f_data;
429
430 if (vp->v_type != VDIR)
431 return (EINVAL);
432
433 if ((error = VOP_GETATTR(vp, &va, p->p_ucred, p))) {
434 return error;
435 }
436
437 nbytes = args->count;
438 if (nbytes == 1) {
439 nbytes = sizeof (struct linux_dirent);
440 justone = 1;
441 }
442 else
443 justone = 0;
444
445 off = fp->f_offset;
446 #define DIRBLKSIZ 512 /* XXX we used to use ufs's DIRBLKSIZ */
447 buflen = max(DIRBLKSIZ, nbytes);
448 buflen = min(buflen, MAXBSIZE);
449 buf = malloc(buflen, M_TEMP, M_WAITOK);
450 VOP_LOCK(vp);
451 again:
452 aiov.iov_base = buf;
453 aiov.iov_len = buflen;
454 auio.uio_iov = &aiov;
455 auio.uio_iovcnt = 1;
456 auio.uio_rw = UIO_READ;
457 auio.uio_segflg = UIO_SYSSPACE;
458 auio.uio_procp = p;
459 auio.uio_resid = buflen;
460 auio.uio_offset = off;
461
462 if (cookies) {
463 free(cookies, M_TEMP);
464 cookies = NULL;
465 }
466
467 error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, &ncookies, &cookies);
468 if (error) {
469 goto out;
470 }
471
472 inp = buf;
473 outp = (caddr_t) args->dent;
474 resid = nbytes;
475 if ((len = buflen - auio.uio_resid) <= 0) {
476 goto eof;
477 }
478
479 cookiep = cookies;
480
481 if (cookies) {
482 /*
483 * When using cookies, the vfs has the option of reading from
484 * a different offset than that supplied (UFS truncates the
485 * offset to a block boundary to make sure that it never reads
486 * partway through a directory entry, even if the directory
487 * has been compacted).
488 */
489 while (len > 0 && ncookies > 0 && *cookiep <= off) {
490 bdp = (struct dirent *) inp;
491 len -= bdp->d_reclen;
492 inp += bdp->d_reclen;
493 cookiep++;
494 ncookies--;
495 }
496 }
497
498 while (len > 0) {
499 if (cookiep && ncookies == 0)
500 break;
501 bdp = (struct dirent *) inp;
502 reclen = bdp->d_reclen;
503 if (reclen & 3) {
504 printf("linux_readdir: reclen=%d\n", reclen);
505 error = EFAULT;
506 goto out;
507 }
508
509 if (bdp->d_fileno == 0) {
510 inp += reclen;
511 if (cookiep) {
512 off = *cookiep++;
513 ncookies--;
514 } else
515 off += reclen;
516 len -= reclen;
517 continue;
518 }
519 linuxreclen = LINUX_RECLEN(&linux_dirent, bdp->d_namlen);
520 if (reclen > len || resid < linuxreclen) {
521 outp++;
522 break;
523 }
524 linux_dirent.dino = (long) bdp->d_fileno;
525 if (justone) {
526 /*
527 * old linux-style readdir usage.
528 */
529 linux_dirent.doff = (linux_off_t) linuxreclen;
530 linux_dirent.dreclen = (u_short) bdp->d_namlen;
531 } else {
532 linux_dirent.doff = (linux_off_t) off;
533 linux_dirent.dreclen = (u_short) linuxreclen;
534 }
535 strcpy(linux_dirent.dname, bdp->d_name);
536 if ((error = copyout((caddr_t)&linux_dirent, outp, linuxreclen))) {
537 goto out;
538 }
539 inp += reclen;
540 if (cookiep) {
541 off = *cookiep++;
542 ncookies--;
543 } else
544 off += reclen;
545 outp += linuxreclen;
546 resid -= linuxreclen;
547 len -= reclen;
548 if (justone)
549 break;
550 }
551
552 if (outp == (caddr_t) args->dent)
553 goto again;
554 fp->f_offset = off;
555
556 if (justone)
557 nbytes = resid + linuxreclen;
558
559 eof:
560 *retval = nbytes - resid;
561 if (cookies)
562 free(cookies, M_TEMP);
563 out:
564 VOP_UNLOCK(vp);
565 free(buf, M_TEMP);
566 return error;
567 }
568
569 /*
570 * These exist mainly for hooks for doing /compat/linux translation.
571 */
572
573 int
574 linux_access(struct proc *p, struct linux_access_args *args, int *retval)
575 {
576 struct access_args bsd;
577 caddr_t sg;
578
579 sg = stackgap_init();
580 CHECKALTEXIST(p, &sg, args->path);
581
582 #ifdef DEBUG
583 printf("Linux-emul(%d): access(%s, %d)\n",
584 p->p_pid, args->path, args->flags);
585 #endif
586 bsd.path = args->path;
587 bsd.flags = args->flags;
588
589 return access(p, &bsd, retval);
590 }
591
592 int
593 linux_unlink(struct proc *p, struct linux_unlink_args *args, int *retval)
594 {
595 struct unlink_args bsd;
596 caddr_t sg;
597
598 sg = stackgap_init();
599 CHECKALTEXIST(p, &sg, args->path);
600
601 #ifdef DEBUG
602 printf("Linux-emul(%d): unlink(%s)\n",
603 p->p_pid, args->path);
604 #endif
605 bsd.path = args->path;
606
607 return unlink(p, &bsd, retval);
608 }
609
610 int
611 linux_chdir(struct proc *p, struct linux_chdir_args *args, int *retval)
612 {
613 struct chdir_args bsd;
614 caddr_t sg;
615
616 sg = stackgap_init();
617 CHECKALTEXIST(p, &sg, args->path);
618
619 #ifdef DEBUG
620 printf("Linux-emul(%d): chdir(%s)\n",
621 p->p_pid, args->path);
622 #endif
623 bsd.path = args->path;
624
625 return chdir(p, &bsd, retval);
626 }
627
628 int
629 linux_chmod(struct proc *p, struct linux_chmod_args *args, int *retval)
630 {
631 struct chmod_args bsd;
632 caddr_t sg;
633
634 sg = stackgap_init();
635 CHECKALTEXIST(p, &sg, args->path);
636
637 #ifdef DEBUG
638 printf("Linux-emul(%d): chmod(%s, %d)\n",
639 p->p_pid, args->path, args->mode);
640 #endif
641 bsd.path = args->path;
642 bsd.mode = args->mode;
643
644 return chmod(p, &bsd, retval);
645 }
646
647 int
648 linux_chown(struct proc *p, struct linux_chown_args *args, int *retval)
649 {
650 struct chown_args bsd;
651 caddr_t sg;
652
653 sg = stackgap_init();
654 CHECKALTEXIST(p, &sg, args->path);
655
656 #ifdef DEBUG
657 printf("Linux-emul(%d): chown(%s, %d, %d)\n",
658 p->p_pid, args->path, args->uid, args->gid);
659 #endif
660 bsd.path = args->path;
661 /* XXX size casts here */
662 bsd.uid = args->uid;
663 bsd.gid = args->gid;
664
665 return chown(p, &bsd, retval);
666 }
667
668 int
669 linux_mkdir(struct proc *p, struct linux_mkdir_args *args, int *retval)
670 {
671 struct mkdir_args bsd;
672 caddr_t sg;
673
674 sg = stackgap_init();
675 CHECKALTCREAT(p, &sg, args->path);
676
677 #ifdef DEBUG
678 printf("Linux-emul(%d): mkdir(%s, %d)\n",
679 p->p_pid, args->path, args->mode);
680 #endif
681 bsd.path = args->path;
682 bsd.mode = args->mode;
683
684 return mkdir(p, &bsd, retval);
685 }
686
687 int
688 linux_rmdir(struct proc *p, struct linux_rmdir_args *args, int *retval)
689 {
690 struct rmdir_args bsd;
691 caddr_t sg;
692
693 sg = stackgap_init();
694 CHECKALTEXIST(p, &sg, args->path);
695
696 #ifdef DEBUG
697 printf("Linux-emul(%d): rmdir(%s)\n",
698 p->p_pid, args->path);
699 #endif
700 bsd.path = args->path;
701
702 return rmdir(p, &bsd, retval);
703 }
704
705 int
706 linux_rename(struct proc *p, struct linux_rename_args *args, int *retval)
707 {
708 struct rename_args bsd;
709 caddr_t sg;
710
711 sg = stackgap_init();
712 CHECKALTEXIST(p, &sg, args->from);
713 CHECKALTCREAT(p, &sg, args->to);
714
715 #ifdef DEBUG
716 printf("Linux-emul(%d): rename(%s, %s)\n",
717 p->p_pid, args->from, args->to);
718 #endif
719 bsd.from = args->from;
720 bsd.to = args->to;
721
722 return rename(p, &bsd, retval);
723 }
724
725 int
726 linux_symlink(struct proc *p, struct linux_symlink_args *args, int *retval)
727 {
728 struct symlink_args bsd;
729 caddr_t sg;
730
731 sg = stackgap_init();
732 CHECKALTEXIST(p, &sg, args->path);
733 CHECKALTCREAT(p, &sg, args->to);
734
735 #ifdef DEBUG
736 printf("Linux-emul(%d): symlink(%s, %s)\n",
737 p->p_pid, args->path, args->to);
738 #endif
739 bsd.path = args->path;
740 bsd.link = args->to;
741
742 return symlink(p, &bsd, retval);
743 }
744
745 int
746 linux_execve(struct proc *p, struct linux_execve_args *args, int *retval)
747 {
748 struct execve_args bsd;
749 caddr_t sg;
750
751 sg = stackgap_init();
752 CHECKALTEXIST(p, &sg, args->path);
753
754 #ifdef DEBUG
755 printf("Linux-emul(%d): execve(%s)\n",
756 p->p_pid, args->path);
757 #endif
758 bsd.fname = args->path;
759 bsd.argv = args->argp;
760 bsd.envv = args->envp;
761
762 return execve(p, &bsd, retval);
763 }
764
765 int
766 linux_readlink(struct proc *p, struct linux_readlink_args *args, int *retval)
767 {
768 struct readlink_args bsd;
769 caddr_t sg;
770
771 sg = stackgap_init();
772 CHECKALTEXIST(p, &sg, args->name);
773
774 #ifdef DEBUG
775 printf("Linux-emul(%d): readlink(%s, 0x%x, %d)\n",
776 p->p_pid, args->name, args->buf, args->count);
777 #endif
778 bsd.path = args->name;
779 bsd.buf = args->buf;
780 bsd.count = args->count;
781
782 return readlink(p, &bsd, retval);
783 }
784
785 int
786 linux_truncate(struct proc *p, struct linux_truncate_args *args, int *retval)
787 {
788 struct otruncate_args bsd;
789 caddr_t sg;
790
791 sg = stackgap_init();
792 CHECKALTEXIST(p, &sg, args->path);
793
794 #ifdef DEBUG
795 printf("Linux-emul(%d): truncate(%s, %ld)\n",
796 p->p_pid, args->path, args->length);
797 #endif
798 bsd.path = args->path;
799 bsd.length = args->length;
800
801 return otruncate(p, &bsd, retval);
802 }
803
804 int
805 linux_lchown(struct proc *p, struct linux_lchown_args *args, int *retval)
806 {
807 struct lchown_args bsd;
808 caddr_t sg;
809
810 sg = stackgap_init();
811 CHECKALTEXIST(p, &sg, args->path);
812
813 #ifdef DEBUG
814 printf("Linux-emul(%d): lchown(%s, %d, %d)\n",
815 p->p_pid, args->path, args->uid, args->gid);
816 #endif
817 bsd.path = args->path;
818 /* XXX size casts here */
819 bsd.uid = args->uid;
820 bsd.gid = args->gid;
821
822 return lchown(p, &bsd, retval);
823 }
Cache object: 7f5ee5f75b55e3b22f926d7c6061244b
|