2 * Copyright (c) 1994-1995 Søren Schmidt
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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
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.
28 * $FreeBSD: src/sys/compat/linux/linux_file.c,v 1.41.2.6 2003/01/06 09:19:43 fjoe Exp $
29 * $DragonFly: src/sys/emulation/linux/linux_file.c,v 1.24 2005/08/27 20:23:05 joerg Exp $
32 #include "opt_compat.h"
34 #include <sys/param.h>
35 #include <sys/systm.h>
37 #include <sys/dirent.h>
38 #include <sys/fcntl.h>
41 #include <sys/filedesc.h>
42 #include <sys/kern_syscall.h>
44 #include <sys/malloc.h>
45 #include <sys/mount.h>
46 #include <sys/nlookup.h>
48 #include <sys/sysproto.h>
50 #include <sys/vnode.h>
52 #include <vfs/ufs/quota.h>
53 #include <vfs/ufs/ufsmount.h>
55 #include <sys/file2.h>
57 #include <arch_linux/linux.h>
58 #include <arch_linux/linux_proto.h>
59 #include "linux_util.h"
62 linux_creat(struct linux_creat_args
*args
)
64 struct nlookupdata nd
;
68 error
= linux_copyin_path(args
->path
, &path
, LINUX_PATH_CREATE
);
73 printf(ARGS(creat
, "%s, %d"), path
, args
->mode
);
75 error
= nlookup_init(&nd
, path
, UIO_SYSSPACE
, NLC_FOLLOW
);
77 error
= kern_open(&nd
, O_WRONLY
| O_CREAT
| O_TRUNC
,
78 args
->mode
, &args
->sysmsg_result
);
80 linux_free_path(&path
);
85 linux_open(struct linux_open_args
*args
)
87 struct thread
*td
= curthread
;
88 struct proc
*p
= td
->td_proc
;
89 struct nlookupdata nd
;
95 if (args
->flags
& LINUX_O_CREAT
) {
96 error
= linux_copyin_path(args
->path
, &path
,
99 error
= linux_copyin_path(args
->path
, &path
,
107 printf(ARGS(open
, "%s, 0x%x, 0x%x"), path
, args
->flags
,
111 if (args
->flags
& LINUX_O_RDONLY
)
113 if (args
->flags
& LINUX_O_WRONLY
)
115 if (args
->flags
& LINUX_O_RDWR
)
117 if (args
->flags
& LINUX_O_NDELAY
)
119 if (args
->flags
& LINUX_O_APPEND
)
121 if (args
->flags
& LINUX_O_SYNC
)
123 if (args
->flags
& LINUX_O_NONBLOCK
)
125 if (args
->flags
& LINUX_FASYNC
)
127 if (args
->flags
& LINUX_O_CREAT
)
129 if (args
->flags
& LINUX_O_TRUNC
)
131 if (args
->flags
& LINUX_O_EXCL
)
133 if (args
->flags
& LINUX_O_NOCTTY
)
135 error
= nlookup_init(&nd
, path
, UIO_SYSSPACE
, NLC_FOLLOW
);
137 error
= kern_open(&nd
, flags
,
138 args
->mode
, &args
->sysmsg_result
);
141 if (error
== 0 && !(flags
& O_NOCTTY
) &&
142 SESS_LEADER(p
) && !(p
->p_flag
& P_CONTROLT
)) {
143 struct filedesc
*fdp
= p
->p_fd
;
144 struct file
*fp
= fdp
->fd_files
[args
->sysmsg_result
].fp
;
146 if (fp
->f_type
== DTYPE_VNODE
)
147 fo_ioctl(fp
, TIOCSCTTY
, (caddr_t
) 0, td
);
151 printf(LMSG("open returns error %d"), error
);
153 linux_free_path(&path
);
158 linux_lseek(struct linux_lseek_args
*args
)
164 printf(ARGS(lseek
, "%d, %ld, %d"),
165 args
->fdes
, (long)args
->off
, args
->whence
);
167 error
= kern_lseek(args
->fdes
, args
->off
, args
->whence
,
168 &args
->sysmsg_offset
);
174 linux_llseek(struct linux_llseek_args
*args
)
181 printf(ARGS(llseek
, "%d, %d:%d, %d"),
182 args
->fd
, args
->ohigh
, args
->olow
, args
->whence
);
184 off
= (args
->olow
) | (((off_t
) args
->ohigh
) << 32);
186 error
= kern_lseek(args
->fd
, off
, args
->whence
, &res
);
189 error
= copyout(&res
, args
->res
, sizeof(res
));
194 linux_readdir(struct linux_readdir_args
*args
)
196 struct linux_getdents_args lda
;
200 lda
.dent
= args
->dent
;
202 lda
.sysmsg_result
= 0;
203 error
= linux_getdents(&lda
);
204 args
->sysmsg_result
= lda
.sysmsg_result
;
209 * Note that linux_getdents(2) and linux_getdents64(2) have the same
210 * arguments. They only differ in the definition of struct dirent they
211 * operate on. We use this to common the code, with the exception of
212 * accessing struct dirent. Note that linux_readdir(2) is implemented
213 * by means of linux_getdents(2). In this case we never operate on
214 * struct dirent64 and thus don't need to handle it...
221 char d_name
[LINUX_NAME_MAX
+ 1];
229 char d_name
[LINUX_NAME_MAX
+ 1];
232 #define LINUX_RECLEN(de,namlen) \
233 ALIGN((((char *)&(de)->d_name - (char *)de) + (namlen) + 1))
235 #define LINUX_DIRBLKSIZ 512
238 getdents_common(struct linux_getdents64_args
*args
, int is64bit
)
240 struct thread
*td
= curthread
;
241 struct proc
*p
= td
->td_proc
;
244 caddr_t inp
, buf
; /* BSD-format */
245 int len
, reclen
; /* BSD-format */
246 caddr_t outp
; /* Linux-format */
247 int resid
, linuxreclen
=0; /* Linux-format */
253 struct l_dirent linux_dirent
;
254 struct l_dirent64 linux_dirent64
;
255 int buflen
, error
, eofflag
, nbytes
, justone
;
256 u_long
*cookies
= NULL
, *cookiep
;
261 if ((error
= getvnode(p
->p_fd
, args
->fd
, &fp
)) != 0)
264 if ((fp
->f_flag
& FREAD
) == 0)
267 vp
= (struct vnode
*) fp
->f_data
;
268 if (vp
->v_type
!= VDIR
)
271 if ((error
= VOP_GETATTR(vp
, &va
, td
)))
274 nbytes
= args
->count
;
276 /* readdir(2) case. Always struct dirent. */
279 nbytes
= sizeof(linux_dirent
);
286 buflen
= max(LINUX_DIRBLKSIZ
, nbytes
);
287 buflen
= min(buflen
, MAXBSIZE
);
288 buf
= malloc(buflen
, M_TEMP
, M_WAITOK
);
289 vn_lock(vp
, LK_EXCLUSIVE
| LK_RETRY
, td
);
293 aiov
.iov_len
= buflen
;
294 auio
.uio_iov
= &aiov
;
296 auio
.uio_rw
= UIO_READ
;
297 auio
.uio_segflg
= UIO_SYSSPACE
;
299 auio
.uio_resid
= buflen
;
300 auio
.uio_offset
= off
;
303 free(cookies
, M_TEMP
);
307 if ((error
= VOP_READDIR(vp
, &auio
, fp
->f_cred
, &eofflag
, &ncookies
,
312 outp
= (caddr_t
)args
->dirent
;
314 if ((len
= buflen
- auio
.uio_resid
) <= 0)
321 * When using cookies, the vfs has the option of reading from
322 * a different offset than that supplied (UFS truncates the
323 * offset to a block boundary to make sure that it never reads
324 * partway through a directory entry, even if the directory
325 * has been compacted).
327 while (len
> 0 && ncookies
> 0 && *cookiep
<= off
) {
328 bdp
= (struct dirent
*) inp
;
329 len
-= _DIRENT_DIRSIZ(bdp
);
330 inp
+= _DIRENT_DIRSIZ(bdp
);
337 if (cookiep
&& ncookies
== 0)
339 bdp
= (struct dirent
*) inp
;
340 reclen
= _DIRENT_DIRSIZ(bdp
);
346 if (bdp
->d_ino
== 0) {
358 linuxreclen
= (is64bit
)
359 ? LINUX_RECLEN(&linux_dirent64
, bdp
->d_namlen
)
360 : LINUX_RECLEN(&linux_dirent
, bdp
->d_namlen
);
362 if (reclen
> len
|| resid
< linuxreclen
) {
368 /* readdir(2) case. */
369 linux_dirent
.d_ino
= (l_long
)bdp
->d_ino
;
370 linux_dirent
.d_off
= (l_off_t
)linuxreclen
;
371 linux_dirent
.d_reclen
= (l_ushort
)bdp
->d_namlen
;
372 strcpy(linux_dirent
.d_name
, bdp
->d_name
);
373 error
= copyout(&linux_dirent
, outp
, linuxreclen
);
376 linux_dirent64
.d_ino
= bdp
->d_ino
;
377 linux_dirent64
.d_off
= (cookiep
)
379 : (l_off_t
)(off
+ reclen
);
380 linux_dirent64
.d_reclen
=
381 (l_ushort
)linuxreclen
;
382 linux_dirent64
.d_type
= bdp
->d_type
;
383 strcpy(linux_dirent64
.d_name
, bdp
->d_name
);
384 error
= copyout(&linux_dirent64
, outp
,
387 linux_dirent
.d_ino
= bdp
->d_ino
;
388 linux_dirent
.d_off
= (cookiep
)
390 : (l_off_t
)(off
+ reclen
);
391 linux_dirent
.d_reclen
= (l_ushort
)linuxreclen
;
392 strcpy(linux_dirent
.d_name
, bdp
->d_name
);
393 error
= copyout(&linux_dirent
, outp
,
408 resid
-= linuxreclen
;
414 if (outp
== (caddr_t
)args
->dirent
)
419 nbytes
= resid
+ linuxreclen
;
422 args
->sysmsg_result
= nbytes
- resid
;
426 free(cookies
, M_TEMP
);
428 VOP_UNLOCK(vp
, 0, td
);
434 linux_getdents(struct linux_getdents_args
*args
)
437 if (ldebug(getdents
))
438 printf(ARGS(getdents
, "%d, *, %d"), args
->fd
, args
->count
);
440 return (getdents_common((struct linux_getdents64_args
*)args
, 0));
444 linux_getdents64(struct linux_getdents64_args
*args
)
447 if (ldebug(getdents64
))
448 printf(ARGS(getdents64
, "%d, *, %d"), args
->fd
, args
->count
);
450 return (getdents_common(args
, 1));
454 * These exist mainly for hooks for doing /compat/linux translation.
458 linux_access(struct linux_access_args
*args
)
460 struct nlookupdata nd
;
464 error
= linux_copyin_path(args
->path
, &path
, LINUX_PATH_EXISTS
);
469 printf(ARGS(access
, "%s, %d"), path
, args
->flags
);
471 error
= nlookup_init(&nd
, path
, UIO_SYSSPACE
, NLC_FOLLOW
);
473 error
= kern_access(&nd
, args
->flags
);
475 linux_free_path(&path
);
480 linux_unlink(struct linux_unlink_args
*args
)
482 struct nlookupdata nd
;
486 error
= linux_copyin_path(args
->path
, &path
, LINUX_PATH_EXISTS
);
491 printf(ARGS(unlink
, "%s"), path
);
493 error
= nlookup_init(&nd
, path
, UIO_SYSSPACE
, 0);
495 error
= kern_unlink(&nd
);
497 linux_free_path(&path
);
502 linux_chdir(struct linux_chdir_args
*args
)
504 struct nlookupdata nd
;
508 error
= linux_copyin_path(args
->path
, &path
, LINUX_PATH_EXISTS
);
513 printf(ARGS(chdir
, "%s"), path
);
515 error
= nlookup_init(&nd
, path
, UIO_SYSSPACE
, NLC_FOLLOW
);
517 error
= kern_chdir(&nd
);
520 linux_free_path(&path
);
525 linux_chmod(struct linux_chmod_args
*args
)
527 struct nlookupdata nd
;
531 error
= linux_copyin_path(args
->path
, &path
, LINUX_PATH_EXISTS
);
536 printf(ARGS(chmod
, "%s, %d"), path
, args
->mode
);
538 error
= nlookup_init(&nd
, path
, UIO_SYSSPACE
, NLC_FOLLOW
);
540 error
= kern_chmod(&nd
, args
->mode
);
542 linux_free_path(&path
);
547 linux_mkdir(struct linux_mkdir_args
*args
)
549 struct nlookupdata nd
;
553 error
= linux_copyin_path(args
->path
, &path
, LINUX_PATH_CREATE
);
558 printf(ARGS(mkdir
, "%s, %d"), path
, args
->mode
);
560 error
= nlookup_init(&nd
, path
, UIO_SYSSPACE
, 0);
562 error
= kern_mkdir(&nd
, args
->mode
);
565 linux_free_path(&path
);
570 linux_rmdir(struct linux_rmdir_args
*args
)
572 struct nlookupdata nd
;
576 error
= linux_copyin_path(args
->path
, &path
, LINUX_PATH_EXISTS
);
581 printf(ARGS(rmdir
, "%s"), path
);
583 error
= nlookup_init(&nd
, path
, UIO_SYSSPACE
, 0);
585 error
= kern_rmdir(&nd
);
587 linux_free_path(&path
);
592 linux_rename(struct linux_rename_args
*args
)
594 struct nlookupdata fromnd
, tond
;
598 error
= linux_copyin_path(args
->from
, &from
, LINUX_PATH_EXISTS
);
601 error
= linux_copyin_path(args
->to
, &to
, LINUX_PATH_CREATE
);
603 linux_free_path(&from
);
608 printf(ARGS(rename
, "%s, %s"), from
, to
);
610 error
= nlookup_init(&fromnd
, from
, UIO_SYSSPACE
, 0);
612 error
= nlookup_init(&tond
, to
, UIO_SYSSPACE
, 0);
614 error
= kern_rename(&fromnd
, &tond
);
617 nlookup_done(&fromnd
);
618 linux_free_path(&from
);
619 linux_free_path(&to
);
624 linux_symlink(struct linux_symlink_args
*args
)
626 struct thread
*td
= curthread
;
627 struct nlookupdata nd
;
632 error
= linux_copyin_path(args
->path
, &path
, LINUX_PATH_EXISTS
);
635 error
= linux_copyin_path(args
->to
, &link
, LINUX_PATH_CREATE
);
637 linux_free_path(&path
);
642 printf(ARGS(symlink
, "%s, %s"), path
, link
);
644 error
= nlookup_init(&nd
, link
, UIO_SYSSPACE
, 0);
646 mode
= ACCESSPERMS
& ~td
->td_proc
->p_fd
->fd_cmask
;
647 error
= kern_symlink(&nd
, path
, mode
);
650 linux_free_path(&path
);
651 linux_free_path(&link
);
656 linux_readlink(struct linux_readlink_args
*args
)
658 struct nlookupdata nd
;
662 error
= linux_copyin_path(args
->name
, &path
, LINUX_PATH_EXISTS
);
666 if (ldebug(readlink
))
667 printf(ARGS(readlink
, "%s, %p, %d"), path
, (void *)args
->buf
,
670 error
= nlookup_init(&nd
, path
, UIO_SYSSPACE
, 0);
672 error
= kern_readlink(&nd
, args
->buf
, args
->count
,
673 &args
->sysmsg_result
);
676 linux_free_path(&path
);
681 linux_truncate(struct linux_truncate_args
*args
)
683 struct nlookupdata nd
;
687 error
= linux_copyin_path(args
->path
, &path
, LINUX_PATH_EXISTS
);
691 if (ldebug(truncate
))
692 printf(ARGS(truncate
, "%s, %ld"), path
,
695 error
= nlookup_init(&nd
, path
, UIO_SYSSPACE
, NLC_FOLLOW
);
697 error
= kern_truncate(&nd
, args
->length
);
699 linux_free_path(&path
);
704 linux_truncate64(struct linux_truncate64_args
*args
)
706 struct nlookupdata nd
;
710 error
= linux_copyin_path(args
->path
, &path
, LINUX_PATH_EXISTS
);
714 if (ldebug(truncate64
))
715 printf(ARGS(truncate64
, "%s, %lld"), path
,
716 (off_t
)args
->length
);
718 error
= nlookup_init(&nd
, path
, UIO_SYSSPACE
, NLC_FOLLOW
);
720 error
= kern_truncate(&nd
, args
->length
);
722 linux_free_path(&path
);
727 linux_ftruncate(struct linux_ftruncate_args
*args
)
732 if (ldebug(ftruncate
))
733 printf(ARGS(ftruncate
, "%d, %ld"), args
->fd
,
736 error
= kern_ftruncate(args
->fd
, args
->length
);
742 linux_ftruncate64(struct linux_ftruncate64_args
*args
)
747 if (ldebug(ftruncate
))
748 printf(ARGS(ftruncate64
, "%d, %lld"), args
->fd
,
749 (off_t
)args
->length
);
751 error
= kern_ftruncate(args
->fd
, args
->length
);
757 linux_link(struct linux_link_args
*args
)
759 struct nlookupdata nd
, linknd
;
763 error
= linux_copyin_path(args
->path
, &path
, LINUX_PATH_EXISTS
);
766 error
= linux_copyin_path(args
->to
, &link
, LINUX_PATH_CREATE
);
768 linux_free_path(&path
);
773 printf(ARGS(link
, "%s, %s"), path
, link
);
775 error
= nlookup_init(&nd
, path
, UIO_SYSSPACE
, NLC_FOLLOW
);
777 error
= nlookup_init(&linknd
, link
, UIO_SYSSPACE
, 0);
779 error
= kern_link(&nd
, &linknd
);
780 nlookup_done(&linknd
);
783 linux_free_path(&path
);
784 linux_free_path(&link
);
789 linux_fdatasync(struct linux_fdatasync_args
*uap
)
791 struct fsync_args bsd
;
795 bsd
.sysmsg_result
= 0;
798 uap
->sysmsg_result
= bsd
.sysmsg_result
;
803 linux_pread(struct linux_pread_args
*uap
)
805 struct thread
*td
= curthread
;
810 aiov
.iov_base
= uap
->buf
;
811 aiov
.iov_len
= uap
->nbyte
;
812 auio
.uio_iov
= &aiov
;
814 auio
.uio_offset
= uap
->offset
;
815 auio
.uio_resid
= uap
->nbyte
;
816 auio
.uio_rw
= UIO_READ
;
817 auio
.uio_segflg
= UIO_USERSPACE
;
820 error
= kern_readv(uap
->fd
, &auio
, FOF_OFFSET
, &uap
->sysmsg_result
);
826 linux_pwrite(struct linux_pwrite_args
*uap
)
828 struct thread
*td
= curthread
;
833 aiov
.iov_base
= uap
->buf
;
834 aiov
.iov_len
= uap
->nbyte
;
835 auio
.uio_iov
= &aiov
;
837 auio
.uio_offset
= uap
->offset
;
838 auio
.uio_resid
= uap
->nbyte
;
839 auio
.uio_rw
= UIO_WRITE
;
840 auio
.uio_segflg
= UIO_USERSPACE
;
843 error
= kern_writev(uap
->fd
, &auio
, FOF_OFFSET
, &uap
->sysmsg_result
);
849 linux_oldumount(struct linux_oldumount_args
*args
)
851 struct linux_umount_args args2
;
854 args2
.path
= args
->path
;
856 args2
.sysmsg_result
= 0;
857 error
= linux_umount(&args2
);
858 args
->sysmsg_result
= args2
.sysmsg_result
;
863 linux_umount(struct linux_umount_args
*args
)
865 struct unmount_args bsd
;
868 bsd
.path
= args
->path
;
869 bsd
.flags
= args
->flags
; /* XXX correct? */
870 bsd
.sysmsg_result
= 0;
872 error
= unmount(&bsd
);
873 args
->sysmsg_result
= bsd
.sysmsg_result
;
878 * fcntl family of syscalls
890 linux_to_bsd_flock(struct l_flock
*linux_flock
, struct flock
*bsd_flock
)
892 switch (linux_flock
->l_type
) {
894 bsd_flock
->l_type
= F_RDLCK
;
897 bsd_flock
->l_type
= F_WRLCK
;
900 bsd_flock
->l_type
= F_UNLCK
;
903 bsd_flock
->l_type
= -1;
906 bsd_flock
->l_whence
= linux_flock
->l_whence
;
907 bsd_flock
->l_start
= (off_t
)linux_flock
->l_start
;
908 bsd_flock
->l_len
= (off_t
)linux_flock
->l_len
;
909 bsd_flock
->l_pid
= (pid_t
)linux_flock
->l_pid
;
913 bsd_to_linux_flock(struct flock
*bsd_flock
, struct l_flock
*linux_flock
)
915 switch (bsd_flock
->l_type
) {
917 linux_flock
->l_type
= LINUX_F_RDLCK
;
920 linux_flock
->l_type
= LINUX_F_WRLCK
;
923 linux_flock
->l_type
= LINUX_F_UNLCK
;
926 linux_flock
->l_whence
= bsd_flock
->l_whence
;
927 linux_flock
->l_start
= (l_off_t
)bsd_flock
->l_start
;
928 linux_flock
->l_len
= (l_off_t
)bsd_flock
->l_len
;
929 linux_flock
->l_pid
= (l_pid_t
)bsd_flock
->l_pid
;
932 #if defined(__i386__)
942 linux_to_bsd_flock64(struct l_flock64
*linux_flock
, struct flock
*bsd_flock
)
944 switch (linux_flock
->l_type
) {
946 bsd_flock
->l_type
= F_RDLCK
;
949 bsd_flock
->l_type
= F_WRLCK
;
952 bsd_flock
->l_type
= F_UNLCK
;
955 bsd_flock
->l_type
= -1;
958 bsd_flock
->l_whence
= linux_flock
->l_whence
;
959 bsd_flock
->l_start
= (off_t
)linux_flock
->l_start
;
960 bsd_flock
->l_len
= (off_t
)linux_flock
->l_len
;
961 bsd_flock
->l_pid
= (pid_t
)linux_flock
->l_pid
;
965 bsd_to_linux_flock64(struct flock
*bsd_flock
, struct l_flock64
*linux_flock
)
967 switch (bsd_flock
->l_type
) {
969 linux_flock
->l_type
= LINUX_F_RDLCK
;
972 linux_flock
->l_type
= LINUX_F_WRLCK
;
975 linux_flock
->l_type
= LINUX_F_UNLCK
;
978 linux_flock
->l_whence
= bsd_flock
->l_whence
;
979 linux_flock
->l_start
= (l_loff_t
)bsd_flock
->l_start
;
980 linux_flock
->l_len
= (l_loff_t
)bsd_flock
->l_len
;
981 linux_flock
->l_pid
= (l_pid_t
)bsd_flock
->l_pid
;
983 #endif /* __i386__ */
986 linux_fcntl_common(struct linux_fcntl64_args
*args
)
988 struct proc
*p
= curproc
;
989 struct l_flock linux_flock
;
990 struct filedesc
*fdp
;
998 dat
.fc_fd
= args
->arg
;
1005 dat
.fc_cloexec
= args
->arg
;
1013 if (args
->arg
& LINUX_O_NDELAY
)
1014 dat
.fc_flags
|= O_NONBLOCK
;
1015 if (args
->arg
& LINUX_O_APPEND
)
1016 dat
.fc_flags
|= O_APPEND
;
1017 if (args
->arg
& LINUX_O_SYNC
)
1018 dat
.fc_flags
|= O_FSYNC
;
1019 if (args
->arg
& LINUX_FASYNC
)
1020 dat
.fc_flags
|= O_ASYNC
;
1024 case LINUX_F_SETLKW
:
1026 error
= copyin((caddr_t
)args
->arg
, &linux_flock
,
1027 sizeof(linux_flock
));
1030 linux_to_bsd_flock(&linux_flock
, &dat
.fc_flock
);
1032 case LINUX_F_GETOWN
:
1035 case LINUX_F_SETOWN
:
1037 * XXX some Linux applications depend on F_SETOWN having no
1038 * significant effect for pipes (SIGIO is not delivered for
1039 * pipes under Linux-2.2.35 at least).
1042 if ((u_int
)args
->fd
>= fdp
->fd_nfiles
||
1043 (fp
= fdp
->fd_files
[args
->fd
].fp
) == NULL
)
1045 if (fp
->f_type
== DTYPE_PIPE
)
1048 dat
.fc_owner
= args
->arg
;
1054 error
= kern_fcntl(args
->fd
, cmd
, &dat
);
1057 switch (args
->cmd
) {
1059 args
->sysmsg_result
= dat
.fc_fd
;
1062 args
->sysmsg_result
= dat
.fc_cloexec
;
1067 args
->sysmsg_result
= 0;
1068 if (dat
.fc_flags
& O_RDONLY
)
1069 args
->sysmsg_result
|= LINUX_O_RDONLY
;
1070 if (dat
.fc_flags
& O_WRONLY
)
1071 args
->sysmsg_result
|= LINUX_O_WRONLY
;
1072 if (dat
.fc_flags
& O_RDWR
)
1073 args
->sysmsg_result
|= LINUX_O_RDWR
;
1074 if (dat
.fc_flags
& O_NDELAY
)
1075 args
->sysmsg_result
|= LINUX_O_NONBLOCK
;
1076 if (dat
.fc_flags
& O_APPEND
)
1077 args
->sysmsg_result
|= LINUX_O_APPEND
;
1078 if (dat
.fc_flags
& O_FSYNC
)
1079 args
->sysmsg_result
|= LINUX_O_SYNC
;
1080 if (dat
.fc_flags
& O_ASYNC
)
1081 args
->sysmsg_result
|= LINUX_FASYNC
;
1084 bsd_to_linux_flock(&dat
.fc_flock
, &linux_flock
);
1085 error
= copyout(&linux_flock
, (caddr_t
)args
->arg
,
1086 sizeof(linux_flock
));
1089 case LINUX_F_SETLKW
:
1091 case LINUX_F_GETOWN
:
1092 args
->sysmsg_result
= dat
.fc_owner
;
1094 case LINUX_F_SETOWN
:
1103 linux_fcntl(struct linux_fcntl_args
*args
)
1105 struct linux_fcntl64_args args64
;
1110 printf(ARGS(fcntl
, "%d, %08x, *"), args
->fd
, args
->cmd
);
1113 args64
.fd
= args
->fd
;
1114 args64
.cmd
= args
->cmd
;
1115 args64
.arg
= args
->arg
;
1116 args64
.sysmsg_result
= 0;
1117 error
= linux_fcntl_common(&args64
);
1118 args
->sysmsg_result
= args64
.sysmsg_result
;
1122 #if defined(__i386__)
1124 linux_fcntl64(struct linux_fcntl64_args
*args
)
1126 struct l_flock64 linux_flock
;
1127 union fcntl_dat dat
;
1131 if (ldebug(fcntl64
))
1132 printf(ARGS(fcntl64
, "%d, %08x, *"), args
->fd
, args
->cmd
);
1134 if (args
->cmd
== LINUX_F_GETLK64
|| args
->cmd
== LINUX_F_SETLK64
||
1135 args
->cmd
== LINUX_F_SETLKW64
) {
1136 switch (args
->cmd
) {
1137 case LINUX_F_GETLK64
:
1140 case LINUX_F_SETLK64
:
1143 case LINUX_F_SETLKW64
:
1148 error
= copyin((caddr_t
)args
->arg
, &linux_flock
,
1149 sizeof(linux_flock
));
1152 linux_to_bsd_flock64(&linux_flock
, &dat
.fc_flock
);
1154 error
= kern_fcntl(args
->fd
, cmd
, &dat
);
1156 if (error
== 0 && args
->cmd
== LINUX_F_GETLK64
) {
1157 bsd_to_linux_flock64(&dat
.fc_flock
, &linux_flock
);
1158 error
= copyout(&linux_flock
, (caddr_t
)args
->arg
,
1159 sizeof(linux_flock
));
1162 error
= linux_fcntl_common(args
);
1167 #endif /* __i386__ */
1170 linux_chown(struct linux_chown_args
*args
)
1172 struct nlookupdata nd
;
1176 error
= linux_copyin_path(args
->path
, &path
, LINUX_PATH_EXISTS
);
1181 printf(ARGS(chown
, "%s, %d, %d"), path
, args
->uid
, args
->gid
);
1183 error
= nlookup_init(&nd
, path
, UIO_SYSSPACE
, NLC_FOLLOW
);
1185 error
= kern_chown(&nd
, args
->uid
, args
->gid
);
1187 linux_free_path(&path
);
1192 linux_lchown(struct linux_lchown_args
*args
)
1194 struct nlookupdata nd
;
1198 error
= linux_copyin_path(args
->path
, &path
, LINUX_PATH_EXISTS
);
1203 printf(ARGS(lchown
, "%s, %d, %d"), path
, args
->uid
, args
->gid
);
1205 error
= nlookup_init(&nd
, path
, UIO_SYSSPACE
, 0);
1207 error
= kern_chown(&nd
, args
->uid
, args
->gid
);
1209 linux_free_path(&path
);