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 without 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 $
31 #include "opt_compat.h"
33 #include <sys/param.h>
34 #include <sys/systm.h>
36 #include <sys/dirent.h>
37 #include <sys/fcntl.h>
40 #include <sys/filedesc.h>
41 #include <sys/kern_syscall.h>
43 #include <sys/malloc.h>
44 #include <sys/mount.h>
45 #include <sys/nlookup.h>
47 #include <sys/sysproto.h>
49 #include <sys/vnode.h>
51 #include <vfs/ufs/quota.h>
52 #include <vfs/ufs/ufsmount.h>
54 #include <sys/file2.h>
55 #include <sys/mplock2.h>
57 #include <arch_linux/linux.h>
58 #include <arch_linux/linux_proto.h>
59 #include "linux_util.h"
65 sys_linux_creat(struct linux_creat_args
*args
)
67 struct nlookupdata nd
;
71 error
= linux_copyin_path(args
->path
, &path
, LINUX_PATH_CREATE
);
76 kprintf(ARGS(creat
, "%s, %d"), path
, args
->mode
);
78 error
= nlookup_init(&nd
, path
, UIO_SYSSPACE
, NLC_FOLLOW
);
80 error
= kern_open(&nd
, O_WRONLY
| O_CREAT
| O_TRUNC
,
81 args
->mode
, &args
->sysmsg_iresult
);
83 linux_free_path(&path
);
91 linux_open_common(int dfd
, char *lpath
, int lflags
, int mode
, int *iresult
)
93 struct thread
*td
= curthread
;
94 struct proc
*p
= td
->td_proc
;
95 struct nlookupdata nd
;
100 if (lflags
& LINUX_O_CREAT
) {
101 error
= linux_copyin_path(lpath
, &path
,
104 error
= linux_copyin_path(lpath
, &path
,
111 if (lflags
& LINUX_O_RDONLY
)
113 if (lflags
& LINUX_O_WRONLY
)
115 if (lflags
& LINUX_O_RDWR
)
117 if (lflags
& LINUX_O_NDELAY
)
119 if (lflags
& LINUX_O_APPEND
)
121 if (lflags
& LINUX_O_SYNC
)
123 if (lflags
& LINUX_O_NONBLOCK
)
125 if (lflags
& LINUX_FASYNC
)
127 if (lflags
& LINUX_O_CREAT
)
129 if (lflags
& LINUX_O_TRUNC
)
131 if (lflags
& LINUX_O_EXCL
)
133 if (lflags
& LINUX_O_NOCTTY
)
136 error
= nlookup_init_at(&nd
, &fp
, dfd
, path
, UIO_SYSSPACE
, NLC_FOLLOW
);
138 error
= kern_open(&nd
, flags
, mode
, iresult
);
140 nlookup_done_at(&nd
, fp
);
142 if (error
== 0 && !(flags
& O_NOCTTY
) &&
143 SESS_LEADER(p
) && !(p
->p_flags
& P_CONTROLT
)) {
146 fp
= holdfp(p
->p_fd
, *iresult
, -1);
148 if (fp
->f_type
== DTYPE_VNODE
) {
149 fo_ioctl(fp
, TIOCSCTTY
, NULL
,
156 if (error
== 0 && lflags
& LINUX_O_DIRECTORY
) {
160 fp
= holdfp(p
->p_fd
, *iresult
, -1);
162 vp
= (struct vnode
*) fp
->f_data
;
163 if (vp
->v_type
!= VDIR
)
168 kern_close(*iresult
);
172 linux_free_path(&path
);
177 sys_linux_open(struct linux_open_args
*args
)
183 kprintf(ARGS(open
, "%s, 0x%x, 0x%x"), args
->path
, args
->flags
,
187 error
= linux_open_common(AT_FDCWD
, args
->path
, args
->flags
,
188 args
->mode
, &args
->sysmsg_iresult
);
192 kprintf(LMSG("open returns error %d"), error
);
198 sys_linux_openat(struct linux_openat_args
*args
)
205 kprintf(ARGS(openat
, "%s, 0x%x, 0x%x"), args
->path
,
206 args
->flags
, args
->mode
);
209 dfd
= (args
->dfd
== LINUX_AT_FDCWD
) ? AT_FDCWD
: args
->dfd
;
211 error
= linux_open_common(dfd
, args
->path
, args
->flags
,
212 args
->mode
, &args
->sysmsg_iresult
);
216 kprintf(LMSG("openat returns error %d"), error
);
225 sys_linux_lseek(struct linux_lseek_args
*args
)
231 kprintf(ARGS(lseek
, "%d, %ld, %d"),
232 args
->fdes
, (long)args
->off
, args
->whence
);
234 error
= kern_lseek(args
->fdes
, args
->off
, args
->whence
,
235 &args
->sysmsg_offset
);
244 sys_linux_llseek(struct linux_llseek_args
*args
)
251 kprintf(ARGS(llseek
, "%d, %d:%d, %d"),
252 args
->fd
, args
->ohigh
, args
->olow
, args
->whence
);
254 off
= (args
->olow
) | (((off_t
) args
->ohigh
) << 32);
256 error
= kern_lseek(args
->fd
, off
, args
->whence
, &res
);
259 error
= copyout(&res
, args
->res
, sizeof(res
));
267 sys_linux_readdir(struct linux_readdir_args
*args
)
269 struct linux_getdents_args lda
;
273 lda
.dent
= args
->dent
;
275 lda
.sysmsg_iresult
= 0;
276 error
= sys_linux_getdents(&lda
);
277 args
->sysmsg_iresult
= lda
.sysmsg_iresult
;
282 * Note that linux_getdents(2) and linux_getdents64(2) have the same
283 * arguments. They only differ in the definition of struct dirent they
284 * operate on. We use this to common the code, with the exception of
285 * accessing struct dirent. Note that linux_readdir(2) is implemented
286 * by means of linux_getdents(2). In this case we never operate on
287 * struct dirent64 and thus don't need to handle it...
294 char d_name
[LINUX_NAME_MAX
+ 1];
302 char d_name
[LINUX_NAME_MAX
+ 1];
305 #define LINUX_RECLEN(de,namlen) \
306 ALIGN((((char *)&(de)->d_name - (char *)de) + (namlen) + 1))
308 #define LINUX_DIRBLKSIZ 512
314 getdents_common(struct linux_getdents64_args
*args
, int is64bit
)
316 struct thread
*td
= curthread
;
317 struct proc
*p
= td
->td_proc
;
320 caddr_t inp
, buf
; /* BSD-format */
321 int reclen
; /* BSD-format */
323 caddr_t outp
; /* Linux-format */
324 int linuxreclen
= 0; /* Linux-format */
331 struct l_dirent linux_dirent
;
332 struct l_dirent64 linux_dirent64
;
333 int error
, eofflag
, justone
;
334 size_t buflen
, nbytes
;
335 off_t
*cookies
= NULL
, *cookiep
;
338 if ((error
= holdvnode(p
->p_fd
, args
->fd
, &fp
)) != 0)
342 if ((fp
->f_flag
& FREAD
) == 0) {
347 vp
= (struct vnode
*) fp
->f_data
;
348 if (vp
->v_type
!= VDIR
) {
353 if ((error
= VOP_GETATTR(vp
, &va
)) != 0)
356 nbytes
= args
->count
;
357 if (nbytes
== (size_t)-1) {
358 /* readdir(2) case. Always struct dirent. */
363 nbytes
= sizeof(linux_dirent
);
368 if ((ssize_t
)nbytes
< 0)
373 buflen
= max(LINUX_DIRBLKSIZ
, nbytes
);
374 buflen
= min(buflen
, MAXBSIZE
);
375 buf
= kmalloc(buflen
, M_TEMP
, M_WAITOK
);
379 aiov
.iov_len
= buflen
;
380 auio
.uio_iov
= &aiov
;
382 auio
.uio_rw
= UIO_READ
;
383 auio
.uio_segflg
= UIO_SYSSPACE
;
385 auio
.uio_resid
= buflen
;
386 auio
.uio_offset
= off
;
389 kfree(cookies
, M_TEMP
);
395 if ((error
= VOP_READDIR(vp
, &auio
, fp
->f_cred
, &eofflag
, &ncookies
,
400 outp
= (caddr_t
)args
->dirent
;
402 if (auio
.uio_resid
>= buflen
)
404 len
= buflen
- auio
.uio_resid
;
409 * When using cookies, the vfs has the option of reading from
410 * a different offset than that supplied (UFS truncates the
411 * offset to a block boundary to make sure that it never reads
412 * partway through a directory entry, even if the directory
413 * has been compacted).
415 while (len
> 0 && ncookies
> 0 && *cookiep
< off
) {
416 bdp
= (struct dirent
*) inp
;
417 len
-= _DIRENT_DIRSIZ(bdp
);
418 inp
+= _DIRENT_DIRSIZ(bdp
);
425 if (cookiep
&& ncookies
== 0)
427 bdp
= (struct dirent
*) inp
;
428 reclen
= _DIRENT_DIRSIZ(bdp
);
434 if (bdp
->d_ino
== 0) {
447 linuxreclen
= (is64bit
)
448 ? LINUX_RECLEN(&linux_dirent64
, bdp
->d_namlen
)
449 : LINUX_RECLEN(&linux_dirent
, bdp
->d_namlen
);
451 if (reclen
> len
|| resid
< linuxreclen
) {
456 bzero(&linux_dirent
, sizeof(linux_dirent
));
457 bzero(&linux_dirent64
, sizeof(linux_dirent64
));
459 /* readdir(2) case. */
460 linux_dirent
.d_ino
= (l_long
)INO64TO32(bdp
->d_ino
);
461 linux_dirent
.d_off
= (l_off_t
)linuxreclen
;
462 linux_dirent
.d_reclen
= (l_ushort
)bdp
->d_namlen
;
463 strcpy(linux_dirent
.d_name
, bdp
->d_name
);
464 error
= copyout(&linux_dirent
, outp
, linuxreclen
);
467 linux_dirent64
.d_ino
= INO64TO32(bdp
->d_ino
);
468 linux_dirent64
.d_off
= (cookiep
)
470 : (l_off_t
)(off
+ reclen
);
471 linux_dirent64
.d_reclen
=
472 (l_ushort
)linuxreclen
;
473 linux_dirent64
.d_type
= bdp
->d_type
;
474 strcpy(linux_dirent64
.d_name
, bdp
->d_name
);
475 error
= copyout(&linux_dirent64
, outp
,
478 linux_dirent
.d_ino
= INO64TO32(bdp
->d_ino
);
479 linux_dirent
.d_off
= (cookiep
)
481 : (l_off_t
)(off
+ reclen
);
482 linux_dirent
.d_reclen
= (l_ushort
)linuxreclen
;
483 strcpy(linux_dirent
.d_name
, bdp
->d_name
);
484 error
= copyout(&linux_dirent
, outp
,
501 resid
-= linuxreclen
;
507 if (outp
== (caddr_t
)args
->dirent
&& eofflag
== 0)
512 nbytes
= resid
+ linuxreclen
;
515 args
->sysmsg_iresult
= (int)(nbytes
- resid
);
519 kfree(cookies
, M_TEMP
);
532 sys_linux_getdents(struct linux_getdents_args
*args
)
535 if (ldebug(getdents
))
536 kprintf(ARGS(getdents
, "%d, *, %d"), args
->fd
, args
->count
);
538 return (getdents_common((struct linux_getdents64_args
*)args
, 0));
545 sys_linux_getdents64(struct linux_getdents64_args
*args
)
548 if (ldebug(getdents64
))
549 kprintf(ARGS(getdents64
, "%d, *, %d"), args
->fd
, args
->count
);
551 return (getdents_common(args
, 1));
555 * These exist mainly for hooks for doing /compat/linux translation.
560 sys_linux_access(struct linux_access_args
*args
)
562 struct nlookupdata nd
;
566 error
= linux_copyin_path(args
->path
, &path
, LINUX_PATH_EXISTS
);
571 kprintf(ARGS(access
, "%s, %d"), path
, args
->flags
);
574 error
= nlookup_init(&nd
, path
, UIO_SYSSPACE
, NLC_FOLLOW
);
576 error
= kern_access(&nd
, args
->flags
, 0);
579 linux_free_path(&path
);
587 sys_linux_unlink(struct linux_unlink_args
*args
)
589 struct nlookupdata nd
;
593 error
= linux_copyin_path(args
->path
, &path
, LINUX_PATH_EXISTS
);
598 kprintf(ARGS(unlink
, "%s"), path
);
601 error
= nlookup_init(&nd
, path
, UIO_SYSSPACE
, 0);
603 error
= kern_unlink(&nd
);
606 linux_free_path(&path
);
611 sys_linux_unlinkat(struct linux_unlinkat_args
*args
)
613 struct nlookupdata nd
;
618 if (args
->flag
& ~LINUX_AT_REMOVEDIR
)
621 error
= linux_copyin_path(args
->path
, &path
, LINUX_PATH_EXISTS
);
623 kprintf("linux_copyin_path says error = %d\n", error
);
628 kprintf(ARGS(unlink
, "%s"), path
);
631 dfd
= (args
->dfd
== LINUX_AT_FDCWD
) ? AT_FDCWD
: args
->dfd
;
633 error
= nlookup_init_at(&nd
, &fp
, dfd
, path
, UIO_SYSSPACE
, 0);
635 if (args
->flag
& LINUX_AT_REMOVEDIR
)
636 error
= kern_rmdir(&nd
);
638 error
= kern_unlink(&nd
);
640 nlookup_done_at(&nd
, fp
);
642 linux_free_path(&path
);
650 sys_linux_chdir(struct linux_chdir_args
*args
)
652 struct nlookupdata nd
;
656 error
= linux_copyin_path(args
->path
, &path
, LINUX_PATH_EXISTS
);
661 kprintf(ARGS(chdir
, "%s"), path
);
664 error
= nlookup_init(&nd
, path
, UIO_SYSSPACE
, NLC_FOLLOW
);
666 error
= kern_chdir(&nd
);
670 linux_free_path(&path
);
678 sys_linux_chmod(struct linux_chmod_args
*args
)
680 struct nlookupdata nd
;
684 error
= linux_copyin_path(args
->path
, &path
, LINUX_PATH_EXISTS
);
689 kprintf(ARGS(chmod
, "%s, %d"), path
, args
->mode
);
692 error
= nlookup_init(&nd
, path
, UIO_SYSSPACE
, NLC_FOLLOW
);
694 error
= kern_chmod(&nd
, args
->mode
);
697 linux_free_path(&path
);
705 sys_linux_mkdir(struct linux_mkdir_args
*args
)
707 struct nlookupdata nd
;
711 error
= linux_copyin_path(args
->path
, &path
, LINUX_PATH_CREATE
);
716 kprintf(ARGS(mkdir
, "%s, %d"), path
, args
->mode
);
719 error
= nlookup_init(&nd
, path
, UIO_SYSSPACE
, 0);
721 error
= kern_mkdir(&nd
, args
->mode
);
725 linux_free_path(&path
);
730 sys_linux_mkdirat(struct linux_mkdirat_args
*args
)
732 struct nlookupdata nd
;
737 error
= linux_copyin_path(args
->path
, &path
, LINUX_PATH_CREATE
);
742 kprintf(ARGS(mkdir
, "%s, %d"), path
, args
->mode
);
744 dfd
= (args
->dfd
== LINUX_AT_FDCWD
) ? AT_FDCWD
: args
->dfd
;
746 error
= nlookup_init_at(&nd
, &fp
, dfd
, path
, UIO_SYSSPACE
, 0);
748 error
= kern_mkdir(&nd
, args
->mode
);
749 nlookup_done_at(&nd
, fp
);
752 linux_free_path(&path
);
760 sys_linux_rmdir(struct linux_rmdir_args
*args
)
762 struct nlookupdata nd
;
766 error
= linux_copyin_path(args
->path
, &path
, LINUX_PATH_EXISTS
);
771 kprintf(ARGS(rmdir
, "%s"), path
);
774 error
= nlookup_init(&nd
, path
, UIO_SYSSPACE
, 0);
776 error
= kern_rmdir(&nd
);
779 linux_free_path(&path
);
787 sys_linux_rename(struct linux_rename_args
*args
)
789 struct nlookupdata fromnd
, tond
;
793 error
= linux_copyin_path(args
->from
, &from
, LINUX_PATH_EXISTS
);
796 error
= linux_copyin_path(args
->to
, &to
, LINUX_PATH_CREATE
);
798 linux_free_path(&from
);
803 kprintf(ARGS(rename
, "%s, %s"), from
, to
);
807 error
= nlookup_init(&fromnd
, from
, UIO_SYSSPACE
, 0);
809 error
= nlookup_init(&tond
, to
, UIO_SYSSPACE
, 0);
811 error
= kern_rename(&fromnd
, &tond
);
814 nlookup_done(&fromnd
);
815 } while (error
== EAGAIN
);
817 linux_free_path(&from
);
818 linux_free_path(&to
);
823 sys_linux_renameat(struct linux_renameat_args
*args
)
825 struct nlookupdata fromnd
, tond
;
826 struct file
*fp
, *fp2
;
828 int olddfd
, newdfd
,error
;
830 error
= linux_copyin_path(args
->from
, &from
, LINUX_PATH_EXISTS
);
833 error
= linux_copyin_path(args
->to
, &to
, LINUX_PATH_CREATE
);
835 linux_free_path(&from
);
840 kprintf(ARGS(rename
, "%s, %s"), from
, to
);
842 olddfd
= (args
->olddfd
== LINUX_AT_FDCWD
) ? AT_FDCWD
: args
->olddfd
;
843 newdfd
= (args
->newdfd
== LINUX_AT_FDCWD
) ? AT_FDCWD
: args
->newdfd
;
845 error
= nlookup_init_at(&fromnd
, &fp
, olddfd
, from
, UIO_SYSSPACE
, 0);
847 error
= nlookup_init_at(&tond
, &fp2
, newdfd
, to
, UIO_SYSSPACE
, 0);
849 error
= kern_rename(&fromnd
, &tond
);
850 nlookup_done_at(&tond
, fp2
);
852 nlookup_done_at(&fromnd
, fp
);
854 linux_free_path(&from
);
855 linux_free_path(&to
);
863 sys_linux_symlink(struct linux_symlink_args
*args
)
865 struct thread
*td
= curthread
;
866 struct nlookupdata nd
;
871 error
= linux_copyin_path(args
->path
, &path
, LINUX_PATH_EXISTS
);
874 error
= linux_copyin_path(args
->to
, &link
, LINUX_PATH_CREATE
);
876 linux_free_path(&path
);
881 kprintf(ARGS(symlink
, "%s, %s"), path
, link
);
884 error
= nlookup_init(&nd
, link
, UIO_SYSSPACE
, 0);
886 mode
= ACCESSPERMS
& ~td
->td_proc
->p_fd
->fd_cmask
;
887 error
= kern_symlink(&nd
, path
, mode
);
891 linux_free_path(&path
);
892 linux_free_path(&link
);
897 sys_linux_symlinkat(struct linux_symlinkat_args
*args
)
899 struct thread
*td
= curthread
;
900 struct nlookupdata nd
;
906 error
= linux_copyin_path(args
->path
, &path
, LINUX_PATH_EXISTS
);
909 error
= linux_copyin_path(args
->to
, &link
, LINUX_PATH_CREATE
);
911 linux_free_path(&path
);
916 kprintf(ARGS(symlink
, "%s, %s"), path
, link
);
918 newdfd
= (args
->newdfd
== LINUX_AT_FDCWD
) ? AT_FDCWD
: args
->newdfd
;
920 error
= nlookup_init_at(&nd
, &fp
, newdfd
, link
, UIO_SYSSPACE
, 0);
922 mode
= ACCESSPERMS
& ~td
->td_proc
->p_fd
->fd_cmask
;
923 error
= kern_symlink(&nd
, path
, mode
);
925 nlookup_done_at(&nd
, fp
);
927 linux_free_path(&path
);
928 linux_free_path(&link
);
936 sys_linux_readlink(struct linux_readlink_args
*args
)
938 struct nlookupdata nd
;
942 error
= linux_copyin_path(args
->name
, &path
, LINUX_PATH_EXISTS
);
946 if (ldebug(readlink
))
947 kprintf(ARGS(readlink
, "%s, %p, %d"), path
, (void *)args
->buf
,
951 error
= nlookup_init(&nd
, path
, UIO_SYSSPACE
, 0);
953 error
= kern_readlink(&nd
, args
->buf
, args
->count
,
954 &args
->sysmsg_iresult
);
958 linux_free_path(&path
);
963 sys_linux_readlinkat(struct linux_readlinkat_args
*args
)
965 struct nlookupdata nd
;
970 error
= linux_copyin_path(args
->path
, &path
, LINUX_PATH_EXISTS
);
974 if (ldebug(readlink
))
975 kprintf(ARGS(readlink
, "%s, %p, %d"), path
, (void *)args
->buf
,
978 dfd
= (args
->dfd
== LINUX_AT_FDCWD
) ? AT_FDCWD
: args
->dfd
;
980 error
= nlookup_init_at(&nd
, &fp
, dfd
, path
, UIO_SYSSPACE
, 0);
982 error
= kern_readlink(&nd
, args
->buf
, args
->count
,
983 &args
->sysmsg_iresult
);
985 nlookup_done_at(&nd
, fp
);
987 linux_free_path(&path
);
995 sys_linux_truncate(struct linux_truncate_args
*args
)
997 struct nlookupdata nd
;
1001 error
= linux_copyin_path(args
->path
, &path
, LINUX_PATH_EXISTS
);
1005 if (ldebug(truncate
))
1006 kprintf(ARGS(truncate
, "%s, %ld"), path
,
1007 (long)args
->length
);
1010 error
= nlookup_init(&nd
, path
, UIO_SYSSPACE
, NLC_FOLLOW
);
1012 error
= kern_truncate(&nd
, args
->length
);
1015 linux_free_path(&path
);
1023 sys_linux_truncate64(struct linux_truncate64_args
*args
)
1025 struct nlookupdata nd
;
1029 error
= linux_copyin_path(args
->path
, &path
, LINUX_PATH_EXISTS
);
1033 if (ldebug(truncate64
))
1034 kprintf(ARGS(truncate64
, "%s, %lld"), path
,
1035 (off_t
)args
->length
);
1038 error
= nlookup_init(&nd
, path
, UIO_SYSSPACE
, NLC_FOLLOW
);
1040 error
= kern_truncate(&nd
, args
->length
);
1043 linux_free_path(&path
);
1051 sys_linux_ftruncate(struct linux_ftruncate_args
*args
)
1056 if (ldebug(ftruncate
))
1057 kprintf(ARGS(ftruncate
, "%d, %ld"), args
->fd
,
1058 (long)args
->length
);
1061 error
= kern_ftruncate(args
->fd
, args
->length
);
1071 sys_linux_ftruncate64(struct linux_ftruncate64_args
*args
)
1076 if (ldebug(ftruncate
))
1077 kprintf(ARGS(ftruncate64
, "%d, %lld"), args
->fd
,
1078 (off_t
)args
->length
);
1081 error
= kern_ftruncate(args
->fd
, args
->length
);
1091 sys_linux_link(struct linux_link_args
*args
)
1093 struct nlookupdata nd
, linknd
;
1097 error
= linux_copyin_path(args
->path
, &path
, LINUX_PATH_EXISTS
);
1100 error
= linux_copyin_path(args
->to
, &link
, LINUX_PATH_CREATE
);
1102 linux_free_path(&path
);
1107 kprintf(ARGS(link
, "%s, %s"), path
, link
);
1110 error
= nlookup_init(&nd
, path
, UIO_SYSSPACE
, NLC_FOLLOW
);
1112 error
= nlookup_init(&linknd
, link
, UIO_SYSSPACE
, 0);
1114 error
= kern_link(&nd
, &linknd
);
1115 nlookup_done(&linknd
);
1119 linux_free_path(&path
);
1120 linux_free_path(&link
);
1125 sys_linux_linkat(struct linux_linkat_args
*args
)
1127 struct nlookupdata nd
, linknd
;
1128 struct file
*fp
, *fp2
;
1130 int olddfd
, newdfd
, error
;
1132 if (args
->flags
!= 0)
1135 error
= linux_copyin_path(args
->path
, &path
, LINUX_PATH_EXISTS
);
1138 error
= linux_copyin_path(args
->to
, &link
, LINUX_PATH_CREATE
);
1140 linux_free_path(&path
);
1145 kprintf(ARGS(link
, "%s, %s"), path
, link
);
1147 olddfd
= (args
->olddfd
== LINUX_AT_FDCWD
) ? AT_FDCWD
: args
->olddfd
;
1148 newdfd
= (args
->newdfd
== LINUX_AT_FDCWD
) ? AT_FDCWD
: args
->newdfd
;
1150 error
= nlookup_init_at(&nd
, &fp
, olddfd
, path
, UIO_SYSSPACE
, NLC_FOLLOW
);
1152 error
= nlookup_init_at(&linknd
, &fp2
, newdfd
, link
, UIO_SYSSPACE
, 0);
1154 error
= kern_link(&nd
, &linknd
);
1155 nlookup_done_at(&linknd
, fp2
);
1157 nlookup_done_at(&nd
, fp
);
1159 linux_free_path(&path
);
1160 linux_free_path(&link
);
1168 sys_linux_fdatasync(struct linux_fdatasync_args
*uap
)
1170 struct fsync_args bsd
;
1174 bsd
.sysmsg_iresult
= 0;
1176 error
= sys_fsync(&bsd
);
1177 uap
->sysmsg_iresult
= bsd
.sysmsg_iresult
;
1185 sys_linux_pread(struct linux_pread_args
*uap
)
1187 struct thread
*td
= curthread
;
1192 aiov
.iov_base
= uap
->buf
;
1193 aiov
.iov_len
= uap
->nbyte
;
1194 auio
.uio_iov
= &aiov
;
1195 auio
.uio_iovcnt
= 1;
1196 auio
.uio_offset
= uap
->offset
;
1197 auio
.uio_resid
= uap
->nbyte
;
1198 auio
.uio_rw
= UIO_READ
;
1199 auio
.uio_segflg
= UIO_USERSPACE
;
1202 if ((ssize_t
)auio
.uio_resid
< 0) {
1205 error
= kern_preadv(uap
->fd
, &auio
, O_FOFFSET
,
1206 &uap
->sysmsg_szresult
);
1215 sys_linux_pwrite(struct linux_pwrite_args
*uap
)
1217 struct thread
*td
= curthread
;
1222 aiov
.iov_base
= uap
->buf
;
1223 aiov
.iov_len
= uap
->nbyte
;
1224 auio
.uio_iov
= &aiov
;
1225 auio
.uio_iovcnt
= 1;
1226 auio
.uio_offset
= uap
->offset
;
1227 auio
.uio_resid
= uap
->nbyte
;
1228 auio
.uio_rw
= UIO_WRITE
;
1229 auio
.uio_segflg
= UIO_USERSPACE
;
1232 if ((ssize_t
)auio
.uio_resid
< 0) {
1235 error
= kern_pwritev(uap
->fd
, &auio
, O_FOFFSET
,
1236 &uap
->sysmsg_szresult
);
1245 sys_linux_oldumount(struct linux_oldumount_args
*args
)
1247 struct linux_umount_args args2
;
1250 args2
.path
= args
->path
;
1252 args2
.sysmsg_iresult
= 0;
1253 error
= sys_linux_umount(&args2
);
1254 args
->sysmsg_iresult
= args2
.sysmsg_iresult
;
1262 sys_linux_umount(struct linux_umount_args
*args
)
1264 struct unmount_args bsd
;
1267 bsd
.path
= args
->path
;
1268 bsd
.flags
= args
->flags
; /* XXX correct? */
1269 bsd
.sysmsg_iresult
= 0;
1271 error
= sys_unmount(&bsd
);
1272 args
->sysmsg_iresult
= bsd
.sysmsg_iresult
;
1277 * fcntl family of syscalls
1291 linux_to_bsd_flock(struct l_flock
*linux_flock
, struct flock
*bsd_flock
)
1293 switch (linux_flock
->l_type
) {
1295 bsd_flock
->l_type
= F_RDLCK
;
1298 bsd_flock
->l_type
= F_WRLCK
;
1301 bsd_flock
->l_type
= F_UNLCK
;
1304 bsd_flock
->l_type
= -1;
1307 bsd_flock
->l_whence
= linux_flock
->l_whence
;
1308 bsd_flock
->l_start
= (off_t
)linux_flock
->l_start
;
1309 bsd_flock
->l_len
= (off_t
)linux_flock
->l_len
;
1310 bsd_flock
->l_pid
= (pid_t
)linux_flock
->l_pid
;
1317 bsd_to_linux_flock(struct flock
*bsd_flock
, struct l_flock
*linux_flock
)
1319 switch (bsd_flock
->l_type
) {
1321 linux_flock
->l_type
= LINUX_F_RDLCK
;
1324 linux_flock
->l_type
= LINUX_F_WRLCK
;
1327 linux_flock
->l_type
= LINUX_F_UNLCK
;
1330 linux_flock
->l_whence
= bsd_flock
->l_whence
;
1331 linux_flock
->l_start
= (l_off_t
)bsd_flock
->l_start
;
1332 linux_flock
->l_len
= (l_off_t
)bsd_flock
->l_len
;
1333 linux_flock
->l_pid
= (l_pid_t
)bsd_flock
->l_pid
;
1336 #if defined(__i386__)
1349 linux_to_bsd_flock64(struct l_flock64
*linux_flock
, struct flock
*bsd_flock
)
1351 switch (linux_flock
->l_type
) {
1353 bsd_flock
->l_type
= F_RDLCK
;
1356 bsd_flock
->l_type
= F_WRLCK
;
1359 bsd_flock
->l_type
= F_UNLCK
;
1362 bsd_flock
->l_type
= -1;
1365 bsd_flock
->l_whence
= linux_flock
->l_whence
;
1366 bsd_flock
->l_start
= (off_t
)linux_flock
->l_start
;
1367 bsd_flock
->l_len
= (off_t
)linux_flock
->l_len
;
1368 bsd_flock
->l_pid
= (pid_t
)linux_flock
->l_pid
;
1375 bsd_to_linux_flock64(struct flock
*bsd_flock
, struct l_flock64
*linux_flock
)
1377 switch (bsd_flock
->l_type
) {
1379 linux_flock
->l_type
= LINUX_F_RDLCK
;
1382 linux_flock
->l_type
= LINUX_F_WRLCK
;
1385 linux_flock
->l_type
= LINUX_F_UNLCK
;
1388 linux_flock
->l_whence
= bsd_flock
->l_whence
;
1389 linux_flock
->l_start
= (l_loff_t
)bsd_flock
->l_start
;
1390 linux_flock
->l_len
= (l_loff_t
)bsd_flock
->l_len
;
1391 linux_flock
->l_pid
= (l_pid_t
)bsd_flock
->l_pid
;
1393 #endif /* __i386__ */
1399 linux_fcntl_common(struct linux_fcntl64_args
*args
)
1401 struct thread
*td
= curthread
;
1402 struct l_flock linux_flock
;
1404 union fcntl_dat dat
;
1407 switch (args
->cmd
) {
1410 dat
.fc_fd
= args
->arg
;
1417 dat
.fc_cloexec
= args
->arg
;
1425 if (args
->arg
& LINUX_O_NDELAY
)
1426 dat
.fc_flags
|= O_NONBLOCK
;
1427 if (args
->arg
& LINUX_O_APPEND
)
1428 dat
.fc_flags
|= O_APPEND
;
1429 if (args
->arg
& LINUX_O_SYNC
)
1430 dat
.fc_flags
|= O_FSYNC
;
1431 if (args
->arg
& LINUX_FASYNC
)
1432 dat
.fc_flags
|= O_ASYNC
;
1436 case LINUX_F_SETLKW
:
1438 error
= copyin((caddr_t
)args
->arg
, &linux_flock
,
1439 sizeof(linux_flock
));
1442 linux_to_bsd_flock(&linux_flock
, &dat
.fc_flock
);
1444 case LINUX_F_GETOWN
:
1447 case LINUX_F_SETOWN
:
1449 * XXX some Linux applications depend on F_SETOWN having no
1450 * significant effect for pipes (SIGIO is not delivered for
1451 * pipes under Linux-2.2.35 at least).
1453 fp
= holdfp(td
->td_proc
->p_fd
, args
->fd
, -1);
1456 if (fp
->f_type
== DTYPE_PIPE
) {
1462 dat
.fc_owner
= args
->arg
;
1469 error
= kern_fcntl(args
->fd
, cmd
, &dat
, td
->td_ucred
);
1472 switch (args
->cmd
) {
1474 args
->sysmsg_iresult
= dat
.fc_fd
;
1477 args
->sysmsg_iresult
= dat
.fc_cloexec
;
1482 args
->sysmsg_iresult
= 0;
1483 if (dat
.fc_flags
& O_RDONLY
)
1484 args
->sysmsg_iresult
|= LINUX_O_RDONLY
;
1485 if (dat
.fc_flags
& O_WRONLY
)
1486 args
->sysmsg_iresult
|= LINUX_O_WRONLY
;
1487 if (dat
.fc_flags
& O_RDWR
)
1488 args
->sysmsg_iresult
|= LINUX_O_RDWR
;
1489 if (dat
.fc_flags
& O_NDELAY
)
1490 args
->sysmsg_iresult
|= LINUX_O_NONBLOCK
;
1491 if (dat
.fc_flags
& O_APPEND
)
1492 args
->sysmsg_iresult
|= LINUX_O_APPEND
;
1493 if (dat
.fc_flags
& O_FSYNC
)
1494 args
->sysmsg_iresult
|= LINUX_O_SYNC
;
1495 if (dat
.fc_flags
& O_ASYNC
)
1496 args
->sysmsg_iresult
|= LINUX_FASYNC
;
1499 bsd_to_linux_flock(&dat
.fc_flock
, &linux_flock
);
1500 error
= copyout(&linux_flock
, (caddr_t
)args
->arg
,
1501 sizeof(linux_flock
));
1504 case LINUX_F_SETLKW
:
1506 case LINUX_F_GETOWN
:
1507 args
->sysmsg_iresult
= dat
.fc_owner
;
1509 case LINUX_F_SETOWN
:
1521 sys_linux_fcntl(struct linux_fcntl_args
*args
)
1523 struct linux_fcntl64_args args64
;
1528 kprintf(ARGS(fcntl
, "%d, %08x, *"), args
->fd
, args
->cmd
);
1531 args64
.fd
= args
->fd
;
1532 args64
.cmd
= args
->cmd
;
1533 args64
.arg
= args
->arg
;
1534 args64
.sysmsg_iresult
= 0;
1535 error
= linux_fcntl_common(&args64
);
1536 args
->sysmsg_iresult
= args64
.sysmsg_iresult
;
1540 #if defined(__i386__)
1545 sys_linux_fcntl64(struct linux_fcntl64_args
*args
)
1547 struct thread
*td
= curthread
;
1548 struct l_flock64 linux_flock
;
1549 union fcntl_dat dat
;
1553 if (ldebug(fcntl64
))
1554 kprintf(ARGS(fcntl64
, "%d, %08x, *"), args
->fd
, args
->cmd
);
1556 if (args
->cmd
== LINUX_F_GETLK64
|| args
->cmd
== LINUX_F_SETLK64
||
1557 args
->cmd
== LINUX_F_SETLKW64
) {
1558 switch (args
->cmd
) {
1559 case LINUX_F_GETLK64
:
1562 case LINUX_F_SETLK64
:
1565 case LINUX_F_SETLKW64
:
1570 error
= copyin((caddr_t
)args
->arg
, &linux_flock
,
1571 sizeof(linux_flock
));
1574 linux_to_bsd_flock64(&linux_flock
, &dat
.fc_flock
);
1577 error
= kern_fcntl(args
->fd
, cmd
, &dat
, td
->td_ucred
);
1579 if (error
== 0 && args
->cmd
== LINUX_F_GETLK64
) {
1580 bsd_to_linux_flock64(&dat
.fc_flock
, &linux_flock
);
1581 error
= copyout(&linux_flock
, (caddr_t
)args
->arg
,
1582 sizeof(linux_flock
));
1585 error
= linux_fcntl_common(args
);
1590 #endif /* __i386__ */
1596 sys_linux_chown(struct linux_chown_args
*args
)
1598 struct nlookupdata nd
;
1602 error
= linux_copyin_path(args
->path
, &path
, LINUX_PATH_EXISTS
);
1607 kprintf(ARGS(chown
, "%s, %d, %d"), path
, args
->uid
, args
->gid
);
1610 error
= nlookup_init(&nd
, path
, UIO_SYSSPACE
, NLC_FOLLOW
);
1612 error
= kern_chown(&nd
, args
->uid
, args
->gid
);
1615 linux_free_path(&path
);
1623 sys_linux_lchown(struct linux_lchown_args
*args
)
1625 struct nlookupdata nd
;
1629 error
= linux_copyin_path(args
->path
, &path
, LINUX_PATH_EXISTS
);
1634 kprintf(ARGS(lchown
, "%s, %d, %d"), path
, args
->uid
, args
->gid
);
1637 error
= nlookup_init(&nd
, path
, UIO_SYSSPACE
, 0);
1639 error
= kern_chown(&nd
, args
->uid
, args
->gid
);
1642 linux_free_path(&path
);
1647 sys_linux_fchmodat(struct linux_fchmodat_args
*args
)
1649 struct fchmodat_args uap
;
1652 uap
.fd
= (args
->dfd
== LINUX_AT_FDCWD
) ? AT_FDCWD
: args
->dfd
;
1653 uap
.path
= args
->filename
;
1654 uap
.mode
= args
->mode
;
1657 error
= sys_fchmodat(&uap
);
1663 sys_linux_fchownat(struct linux_fchownat_args
*args
)
1665 struct fchownat_args uap
;
1668 if (args
->flag
& ~LINUX_AT_SYMLINK_NOFOLLOW
)
1671 uap
.fd
= (args
->dfd
== LINUX_AT_FDCWD
) ? AT_FDCWD
: args
->dfd
;
1672 uap
.path
= args
->filename
;
1673 uap
.uid
= args
->uid
;
1674 uap
.gid
= args
->gid
;
1675 uap
.flags
= (args
->flag
& LINUX_AT_SYMLINK_NOFOLLOW
) == 0 ? 0 :
1676 AT_SYMLINK_NOFOLLOW
;
1678 error
= sys_fchownat(&uap
);
1684 sys_linux_faccessat(struct linux_faccessat_args
*args
)
1686 struct faccessat_args uap
;
1689 uap
.fd
= (args
->dfd
== LINUX_AT_FDCWD
) ? AT_FDCWD
: args
->dfd
;
1690 uap
.path
= args
->filename
;
1691 uap
.amode
= args
->mode
;
1694 error
= sys_faccessat(&uap
);