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.39 2008/09/28 05:08:16 dillon 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"
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);
79 error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW);
81 error = kern_open(&nd, O_WRONLY | O_CREAT | O_TRUNC,
82 args->mode, &args->sysmsg_iresult);
85 linux_free_path(&path);
93 sys_linux_open(struct linux_open_args *args)
95 struct thread *td = curthread;
96 struct proc *p = td->td_proc;
97 struct nlookupdata nd;
101 if (args->flags & LINUX_O_CREAT) {
102 error = linux_copyin_path(args->path, &path,
105 error = linux_copyin_path(args->path, &path,
113 kprintf(ARGS(open, "%s, 0x%x, 0x%x"), path, args->flags,
117 if (args->flags & LINUX_O_RDONLY)
119 if (args->flags & LINUX_O_WRONLY)
121 if (args->flags & LINUX_O_RDWR)
123 if (args->flags & LINUX_O_NDELAY)
125 if (args->flags & LINUX_O_APPEND)
127 if (args->flags & LINUX_O_SYNC)
129 if (args->flags & LINUX_O_NONBLOCK)
131 if (args->flags & LINUX_FASYNC)
133 if (args->flags & LINUX_O_CREAT)
135 if (args->flags & LINUX_O_TRUNC)
137 if (args->flags & LINUX_O_EXCL)
139 if (args->flags & LINUX_O_NOCTTY)
142 error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW);
144 error = kern_open(&nd, flags,
145 args->mode, &args->sysmsg_iresult);
148 if (error == 0 && !(flags & O_NOCTTY) &&
149 SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) {
152 fp = holdfp(p->p_fd, args->sysmsg_iresult, -1);
154 if (fp->f_type == DTYPE_VNODE)
155 fo_ioctl(fp, TIOCSCTTY, NULL, p->p_ucred, NULL);
162 kprintf(LMSG("open returns error %d"), error);
164 linux_free_path(&path);
172 sys_linux_lseek(struct linux_lseek_args *args)
178 kprintf(ARGS(lseek, "%d, %ld, %d"),
179 args->fdes, (long)args->off, args->whence);
181 error = kern_lseek(args->fdes, args->off, args->whence,
182 &args->sysmsg_offset);
191 sys_linux_llseek(struct linux_llseek_args *args)
198 kprintf(ARGS(llseek, "%d, %d:%d, %d"),
199 args->fd, args->ohigh, args->olow, args->whence);
201 off = (args->olow) | (((off_t) args->ohigh) << 32);
203 error = kern_lseek(args->fd, off, args->whence, &res);
206 error = copyout(&res, args->res, sizeof(res));
214 sys_linux_readdir(struct linux_readdir_args *args)
216 struct linux_getdents_args lda;
220 lda.dent = args->dent;
222 lda.sysmsg_iresult = 0;
223 error = sys_linux_getdents(&lda);
224 args->sysmsg_iresult = lda.sysmsg_iresult;
229 * Note that linux_getdents(2) and linux_getdents64(2) have the same
230 * arguments. They only differ in the definition of struct dirent they
231 * operate on. We use this to common the code, with the exception of
232 * accessing struct dirent. Note that linux_readdir(2) is implemented
233 * by means of linux_getdents(2). In this case we never operate on
234 * struct dirent64 and thus don't need to handle it...
241 char d_name[LINUX_NAME_MAX + 1];
249 char d_name[LINUX_NAME_MAX + 1];
252 #define LINUX_RECLEN(de,namlen) \
253 ALIGN((((char *)&(de)->d_name - (char *)de) + (namlen) + 1))
255 #define LINUX_DIRBLKSIZ 512
261 getdents_common(struct linux_getdents64_args *args, int is64bit)
263 struct thread *td = curthread;
264 struct proc *p = td->td_proc;
267 caddr_t inp, buf; /* BSD-format */
268 int reclen; /* BSD-format */
270 caddr_t outp; /* Linux-format */
271 int linuxreclen = 0; /* Linux-format */
278 struct l_dirent linux_dirent;
279 struct l_dirent64 linux_dirent64;
280 int error, eofflag, justone;
281 size_t buflen, nbytes;
282 off_t *cookies = NULL, *cookiep;
285 if ((error = holdvnode(p->p_fd, args->fd, &fp)) != 0)
289 if ((fp->f_flag & FREAD) == 0) {
294 vp = (struct vnode *) fp->f_data;
295 if (vp->v_type != VDIR) {
300 if ((error = VOP_GETATTR(vp, &va)) != 0)
303 nbytes = args->count;
304 if (nbytes == (size_t)-1) {
305 /* readdir(2) case. Always struct dirent. */
310 nbytes = sizeof(linux_dirent);
315 if ((size_t)nbytes < 0)
320 buflen = max(LINUX_DIRBLKSIZ, nbytes);
321 buflen = min(buflen, MAXBSIZE);
322 buf = kmalloc(buflen, M_TEMP, M_WAITOK);
326 aiov.iov_len = buflen;
327 auio.uio_iov = &aiov;
329 auio.uio_rw = UIO_READ;
330 auio.uio_segflg = UIO_SYSSPACE;
332 auio.uio_resid = buflen;
333 auio.uio_offset = off;
336 kfree(cookies, M_TEMP);
342 if ((error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, &ncookies,
347 outp = (caddr_t)args->dirent;
349 if (auio.uio_resid >= buflen)
351 len = buflen - auio.uio_resid;
356 * When using cookies, the vfs has the option of reading from
357 * a different offset than that supplied (UFS truncates the
358 * offset to a block boundary to make sure that it never reads
359 * partway through a directory entry, even if the directory
360 * has been compacted).
362 while (len > 0 && ncookies > 0 && *cookiep < off) {
363 bdp = (struct dirent *) inp;
364 len -= _DIRENT_DIRSIZ(bdp);
365 inp += _DIRENT_DIRSIZ(bdp);
372 if (cookiep && ncookies == 0)
374 bdp = (struct dirent *) inp;
375 reclen = _DIRENT_DIRSIZ(bdp);
381 if (bdp->d_ino == 0) {
394 linuxreclen = (is64bit)
395 ? LINUX_RECLEN(&linux_dirent64, bdp->d_namlen)
396 : LINUX_RECLEN(&linux_dirent, bdp->d_namlen);
398 if (reclen > len || resid < linuxreclen) {
403 bzero(&linux_dirent, sizeof(linux_dirent));
404 bzero(&linux_dirent64, sizeof(linux_dirent64));
406 /* readdir(2) case. */
407 linux_dirent.d_ino = (l_long)INO64TO32(bdp->d_ino);
408 linux_dirent.d_off = (l_off_t)linuxreclen;
409 linux_dirent.d_reclen = (l_ushort)bdp->d_namlen;
410 strcpy(linux_dirent.d_name, bdp->d_name);
411 error = copyout(&linux_dirent, outp, linuxreclen);
414 linux_dirent64.d_ino = bdp->d_ino;
415 linux_dirent64.d_off = (cookiep)
417 : (l_off_t)(off + reclen);
418 linux_dirent64.d_reclen =
419 (l_ushort)linuxreclen;
420 linux_dirent64.d_type = bdp->d_type;
421 strcpy(linux_dirent64.d_name, bdp->d_name);
422 error = copyout(&linux_dirent64, outp,
425 linux_dirent.d_ino = INO64TO32(bdp->d_ino);
426 linux_dirent.d_off = (cookiep)
428 : (l_off_t)(off + reclen);
429 linux_dirent.d_reclen = (l_ushort)linuxreclen;
430 strcpy(linux_dirent.d_name, bdp->d_name);
431 error = copyout(&linux_dirent, outp,
448 resid -= linuxreclen;
454 if (outp == (caddr_t)args->dirent && eofflag == 0)
459 nbytes = resid + linuxreclen;
462 args->sysmsg_iresult = (int)(nbytes - resid);
466 kfree(cookies, M_TEMP);
479 sys_linux_getdents(struct linux_getdents_args *args)
482 if (ldebug(getdents))
483 kprintf(ARGS(getdents, "%d, *, %d"), args->fd, args->count);
485 return (getdents_common((struct linux_getdents64_args*)args, 0));
492 sys_linux_getdents64(struct linux_getdents64_args *args)
495 if (ldebug(getdents64))
496 kprintf(ARGS(getdents64, "%d, *, %d"), args->fd, args->count);
498 return (getdents_common(args, 1));
502 * These exist mainly for hooks for doing /compat/linux translation.
507 sys_linux_access(struct linux_access_args *args)
509 struct nlookupdata nd;
513 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
518 kprintf(ARGS(access, "%s, %d"), path, args->flags);
521 error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW);
523 error = kern_access(&nd, args->flags, 0);
526 linux_free_path(&path);
534 sys_linux_unlink(struct linux_unlink_args *args)
536 struct nlookupdata nd;
540 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
545 kprintf(ARGS(unlink, "%s"), path);
548 error = nlookup_init(&nd, path, UIO_SYSSPACE, 0);
550 error = kern_unlink(&nd);
553 linux_free_path(&path);
561 sys_linux_chdir(struct linux_chdir_args *args)
563 struct nlookupdata nd;
567 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
572 kprintf(ARGS(chdir, "%s"), path);
575 error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW);
577 error = kern_chdir(&nd);
581 linux_free_path(&path);
589 sys_linux_chmod(struct linux_chmod_args *args)
591 struct nlookupdata nd;
595 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
600 kprintf(ARGS(chmod, "%s, %d"), path, args->mode);
603 error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW);
605 error = kern_chmod(&nd, args->mode);
608 linux_free_path(&path);
616 sys_linux_mkdir(struct linux_mkdir_args *args)
618 struct nlookupdata nd;
622 error = linux_copyin_path(args->path, &path, LINUX_PATH_CREATE);
627 kprintf(ARGS(mkdir, "%s, %d"), path, args->mode);
630 error = nlookup_init(&nd, path, UIO_SYSSPACE, 0);
632 error = kern_mkdir(&nd, args->mode);
636 linux_free_path(&path);
644 sys_linux_rmdir(struct linux_rmdir_args *args)
646 struct nlookupdata nd;
650 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
655 kprintf(ARGS(rmdir, "%s"), path);
658 error = nlookup_init(&nd, path, UIO_SYSSPACE, 0);
660 error = kern_rmdir(&nd);
663 linux_free_path(&path);
671 sys_linux_rename(struct linux_rename_args *args)
673 struct nlookupdata fromnd, tond;
677 error = linux_copyin_path(args->from, &from, LINUX_PATH_EXISTS);
680 error = linux_copyin_path(args->to, &to, LINUX_PATH_CREATE);
682 linux_free_path(&from);
687 kprintf(ARGS(rename, "%s, %s"), from, to);
690 error = nlookup_init(&fromnd, from, UIO_SYSSPACE, 0);
692 error = nlookup_init(&tond, to, UIO_SYSSPACE, 0);
694 error = kern_rename(&fromnd, &tond);
697 nlookup_done(&fromnd);
699 linux_free_path(&from);
700 linux_free_path(&to);
708 sys_linux_symlink(struct linux_symlink_args *args)
710 struct thread *td = curthread;
711 struct nlookupdata nd;
716 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
719 error = linux_copyin_path(args->to, &link, LINUX_PATH_CREATE);
721 linux_free_path(&path);
726 kprintf(ARGS(symlink, "%s, %s"), path, link);
729 error = nlookup_init(&nd, link, UIO_SYSSPACE, 0);
731 mode = ACCESSPERMS & ~td->td_proc->p_fd->fd_cmask;
732 error = kern_symlink(&nd, path, mode);
736 linux_free_path(&path);
737 linux_free_path(&link);
745 sys_linux_readlink(struct linux_readlink_args *args)
747 struct nlookupdata nd;
751 error = linux_copyin_path(args->name, &path, LINUX_PATH_EXISTS);
755 if (ldebug(readlink))
756 kprintf(ARGS(readlink, "%s, %p, %d"), path, (void *)args->buf,
760 error = nlookup_init(&nd, path, UIO_SYSSPACE, 0);
762 error = kern_readlink(&nd, args->buf, args->count,
763 &args->sysmsg_iresult);
767 linux_free_path(&path);
775 sys_linux_truncate(struct linux_truncate_args *args)
777 struct nlookupdata nd;
781 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
785 if (ldebug(truncate))
786 kprintf(ARGS(truncate, "%s, %ld"), path,
790 error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW);
792 error = kern_truncate(&nd, args->length);
795 linux_free_path(&path);
803 sys_linux_truncate64(struct linux_truncate64_args *args)
805 struct nlookupdata nd;
809 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
813 if (ldebug(truncate64))
814 kprintf(ARGS(truncate64, "%s, %lld"), path,
815 (off_t)args->length);
818 error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW);
820 error = kern_truncate(&nd, args->length);
823 linux_free_path(&path);
831 sys_linux_ftruncate(struct linux_ftruncate_args *args)
836 if (ldebug(ftruncate))
837 kprintf(ARGS(ftruncate, "%d, %ld"), args->fd,
841 error = kern_ftruncate(args->fd, args->length);
851 sys_linux_ftruncate64(struct linux_ftruncate64_args *args)
856 if (ldebug(ftruncate))
857 kprintf(ARGS(ftruncate64, "%d, %lld"), args->fd,
858 (off_t)args->length);
861 error = kern_ftruncate(args->fd, args->length);
871 sys_linux_link(struct linux_link_args *args)
873 struct nlookupdata nd, linknd;
877 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
880 error = linux_copyin_path(args->to, &link, LINUX_PATH_CREATE);
882 linux_free_path(&path);
887 kprintf(ARGS(link, "%s, %s"), path, link);
890 error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW);
892 error = nlookup_init(&linknd, link, UIO_SYSSPACE, 0);
894 error = kern_link(&nd, &linknd);
895 nlookup_done(&linknd);
899 linux_free_path(&path);
900 linux_free_path(&link);
908 sys_linux_fdatasync(struct linux_fdatasync_args *uap)
910 struct fsync_args bsd;
914 bsd.sysmsg_iresult = 0;
916 error = sys_fsync(&bsd);
917 uap->sysmsg_iresult = bsd.sysmsg_iresult;
925 sys_linux_pread(struct linux_pread_args *uap)
927 struct thread *td = curthread;
932 aiov.iov_base = uap->buf;
933 aiov.iov_len = uap->nbyte;
934 auio.uio_iov = &aiov;
936 auio.uio_offset = uap->offset;
937 auio.uio_resid = uap->nbyte;
938 auio.uio_rw = UIO_READ;
939 auio.uio_segflg = UIO_USERSPACE;
942 if ((ssize_t)auio.uio_resid < 0) {
945 error = kern_preadv(uap->fd, &auio, O_FOFFSET,
946 &uap->sysmsg_szresult);
955 sys_linux_pwrite(struct linux_pwrite_args *uap)
957 struct thread *td = curthread;
962 aiov.iov_base = uap->buf;
963 aiov.iov_len = uap->nbyte;
964 auio.uio_iov = &aiov;
966 auio.uio_offset = uap->offset;
967 auio.uio_resid = uap->nbyte;
968 auio.uio_rw = UIO_WRITE;
969 auio.uio_segflg = UIO_USERSPACE;
972 if ((ssize_t)auio.uio_resid < 0) {
975 error = kern_pwritev(uap->fd, &auio, O_FOFFSET,
976 &uap->sysmsg_szresult);
985 sys_linux_oldumount(struct linux_oldumount_args *args)
987 struct linux_umount_args args2;
990 args2.path = args->path;
992 args2.sysmsg_iresult = 0;
993 error = sys_linux_umount(&args2);
994 args->sysmsg_iresult = args2.sysmsg_iresult;
1002 sys_linux_umount(struct linux_umount_args *args)
1004 struct unmount_args bsd;
1007 bsd.path = args->path;
1008 bsd.flags = args->flags; /* XXX correct? */
1009 bsd.sysmsg_iresult = 0;
1011 error = sys_unmount(&bsd);
1012 args->sysmsg_iresult = bsd.sysmsg_iresult;
1017 * fcntl family of syscalls
1031 linux_to_bsd_flock(struct l_flock *linux_flock, struct flock *bsd_flock)
1033 switch (linux_flock->l_type) {
1035 bsd_flock->l_type = F_RDLCK;
1038 bsd_flock->l_type = F_WRLCK;
1041 bsd_flock->l_type = F_UNLCK;
1044 bsd_flock->l_type = -1;
1047 bsd_flock->l_whence = linux_flock->l_whence;
1048 bsd_flock->l_start = (off_t)linux_flock->l_start;
1049 bsd_flock->l_len = (off_t)linux_flock->l_len;
1050 bsd_flock->l_pid = (pid_t)linux_flock->l_pid;
1057 bsd_to_linux_flock(struct flock *bsd_flock, struct l_flock *linux_flock)
1059 switch (bsd_flock->l_type) {
1061 linux_flock->l_type = LINUX_F_RDLCK;
1064 linux_flock->l_type = LINUX_F_WRLCK;
1067 linux_flock->l_type = LINUX_F_UNLCK;
1070 linux_flock->l_whence = bsd_flock->l_whence;
1071 linux_flock->l_start = (l_off_t)bsd_flock->l_start;
1072 linux_flock->l_len = (l_off_t)bsd_flock->l_len;
1073 linux_flock->l_pid = (l_pid_t)bsd_flock->l_pid;
1076 #if defined(__i386__)
1089 linux_to_bsd_flock64(struct l_flock64 *linux_flock, struct flock *bsd_flock)
1091 switch (linux_flock->l_type) {
1093 bsd_flock->l_type = F_RDLCK;
1096 bsd_flock->l_type = F_WRLCK;
1099 bsd_flock->l_type = F_UNLCK;
1102 bsd_flock->l_type = -1;
1105 bsd_flock->l_whence = linux_flock->l_whence;
1106 bsd_flock->l_start = (off_t)linux_flock->l_start;
1107 bsd_flock->l_len = (off_t)linux_flock->l_len;
1108 bsd_flock->l_pid = (pid_t)linux_flock->l_pid;
1115 bsd_to_linux_flock64(struct flock *bsd_flock, struct l_flock64 *linux_flock)
1117 switch (bsd_flock->l_type) {
1119 linux_flock->l_type = LINUX_F_RDLCK;
1122 linux_flock->l_type = LINUX_F_WRLCK;
1125 linux_flock->l_type = LINUX_F_UNLCK;
1128 linux_flock->l_whence = bsd_flock->l_whence;
1129 linux_flock->l_start = (l_loff_t)bsd_flock->l_start;
1130 linux_flock->l_len = (l_loff_t)bsd_flock->l_len;
1131 linux_flock->l_pid = (l_pid_t)bsd_flock->l_pid;
1133 #endif /* __i386__ */
1139 linux_fcntl_common(struct linux_fcntl64_args *args)
1141 struct proc *p = curproc;
1142 struct l_flock linux_flock;
1144 union fcntl_dat dat;
1147 switch (args->cmd) {
1150 dat.fc_fd = args->arg;
1157 dat.fc_cloexec = args->arg;
1165 if (args->arg & LINUX_O_NDELAY)
1166 dat.fc_flags |= O_NONBLOCK;
1167 if (args->arg & LINUX_O_APPEND)
1168 dat.fc_flags |= O_APPEND;
1169 if (args->arg & LINUX_O_SYNC)
1170 dat.fc_flags |= O_FSYNC;
1171 if (args->arg & LINUX_FASYNC)
1172 dat.fc_flags |= O_ASYNC;
1176 case LINUX_F_SETLKW:
1178 error = copyin((caddr_t)args->arg, &linux_flock,
1179 sizeof(linux_flock));
1182 linux_to_bsd_flock(&linux_flock, &dat.fc_flock);
1184 case LINUX_F_GETOWN:
1187 case LINUX_F_SETOWN:
1189 * XXX some Linux applications depend on F_SETOWN having no
1190 * significant effect for pipes (SIGIO is not delivered for
1191 * pipes under Linux-2.2.35 at least).
1193 fp = holdfp(p->p_fd, args->fd, -1);
1196 if (fp->f_type == DTYPE_PIPE) {
1202 dat.fc_owner = args->arg;
1209 error = kern_fcntl(args->fd, cmd, &dat, p->p_ucred);
1212 switch (args->cmd) {
1214 args->sysmsg_iresult = dat.fc_fd;
1217 args->sysmsg_iresult = dat.fc_cloexec;
1222 args->sysmsg_iresult = 0;
1223 if (dat.fc_flags & O_RDONLY)
1224 args->sysmsg_iresult |= LINUX_O_RDONLY;
1225 if (dat.fc_flags & O_WRONLY)
1226 args->sysmsg_iresult |= LINUX_O_WRONLY;
1227 if (dat.fc_flags & O_RDWR)
1228 args->sysmsg_iresult |= LINUX_O_RDWR;
1229 if (dat.fc_flags & O_NDELAY)
1230 args->sysmsg_iresult |= LINUX_O_NONBLOCK;
1231 if (dat.fc_flags & O_APPEND)
1232 args->sysmsg_iresult |= LINUX_O_APPEND;
1233 if (dat.fc_flags & O_FSYNC)
1234 args->sysmsg_iresult |= LINUX_O_SYNC;
1235 if (dat.fc_flags & O_ASYNC)
1236 args->sysmsg_iresult |= LINUX_FASYNC;
1239 bsd_to_linux_flock(&dat.fc_flock, &linux_flock);
1240 error = copyout(&linux_flock, (caddr_t)args->arg,
1241 sizeof(linux_flock));
1244 case LINUX_F_SETLKW:
1246 case LINUX_F_GETOWN:
1247 args->sysmsg_iresult = dat.fc_owner;
1249 case LINUX_F_SETOWN:
1261 sys_linux_fcntl(struct linux_fcntl_args *args)
1263 struct linux_fcntl64_args args64;
1268 kprintf(ARGS(fcntl, "%d, %08x, *"), args->fd, args->cmd);
1271 args64.fd = args->fd;
1272 args64.cmd = args->cmd;
1273 args64.arg = args->arg;
1274 args64.sysmsg_iresult = 0;
1275 error = linux_fcntl_common(&args64);
1276 args->sysmsg_iresult = args64.sysmsg_iresult;
1280 #if defined(__i386__)
1285 sys_linux_fcntl64(struct linux_fcntl64_args *args)
1287 struct l_flock64 linux_flock;
1288 union fcntl_dat dat;
1292 if (ldebug(fcntl64))
1293 kprintf(ARGS(fcntl64, "%d, %08x, *"), args->fd, args->cmd);
1295 if (args->cmd == LINUX_F_GETLK64 || args->cmd == LINUX_F_SETLK64 ||
1296 args->cmd == LINUX_F_SETLKW64) {
1297 switch (args->cmd) {
1298 case LINUX_F_GETLK64:
1301 case LINUX_F_SETLK64:
1304 case LINUX_F_SETLKW64:
1309 error = copyin((caddr_t)args->arg, &linux_flock,
1310 sizeof(linux_flock));
1313 linux_to_bsd_flock64(&linux_flock, &dat.fc_flock);
1316 error = kern_fcntl(args->fd, cmd, &dat, curproc->p_ucred);
1318 if (error == 0 && args->cmd == LINUX_F_GETLK64) {
1319 bsd_to_linux_flock64(&dat.fc_flock, &linux_flock);
1320 error = copyout(&linux_flock, (caddr_t)args->arg,
1321 sizeof(linux_flock));
1324 error = linux_fcntl_common(args);
1329 #endif /* __i386__ */
1335 sys_linux_chown(struct linux_chown_args *args)
1337 struct nlookupdata nd;
1341 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
1346 kprintf(ARGS(chown, "%s, %d, %d"), path, args->uid, args->gid);
1349 error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW);
1351 error = kern_chown(&nd, args->uid, args->gid);
1354 linux_free_path(&path);
1362 sys_linux_lchown(struct linux_lchown_args *args)
1364 struct nlookupdata nd;
1368 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
1373 kprintf(ARGS(lchown, "%s, %d, %d"), path, args->uid, args->gid);
1376 error = nlookup_init(&nd, path, UIO_SYSSPACE, 0);
1378 error = kern_chown(&nd, args->uid, args->gid);
1381 linux_free_path(&path);