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,
164 kprintf(LMSG("open returns error %d"), error);
166 linux_free_path(&path);
174 sys_linux_lseek(struct linux_lseek_args *args)
180 kprintf(ARGS(lseek, "%d, %ld, %d"),
181 args->fdes, (long)args->off, args->whence);
183 error = kern_lseek(args->fdes, args->off, args->whence,
184 &args->sysmsg_offset);
193 sys_linux_llseek(struct linux_llseek_args *args)
200 kprintf(ARGS(llseek, "%d, %d:%d, %d"),
201 args->fd, args->ohigh, args->olow, args->whence);
203 off = (args->olow) | (((off_t) args->ohigh) << 32);
205 error = kern_lseek(args->fd, off, args->whence, &res);
208 error = copyout(&res, args->res, sizeof(res));
216 sys_linux_readdir(struct linux_readdir_args *args)
218 struct linux_getdents_args lda;
222 lda.dent = args->dent;
224 lda.sysmsg_iresult = 0;
225 error = sys_linux_getdents(&lda);
226 args->sysmsg_iresult = lda.sysmsg_iresult;
231 * Note that linux_getdents(2) and linux_getdents64(2) have the same
232 * arguments. They only differ in the definition of struct dirent they
233 * operate on. We use this to common the code, with the exception of
234 * accessing struct dirent. Note that linux_readdir(2) is implemented
235 * by means of linux_getdents(2). In this case we never operate on
236 * struct dirent64 and thus don't need to handle it...
243 char d_name[LINUX_NAME_MAX + 1];
251 char d_name[LINUX_NAME_MAX + 1];
254 #define LINUX_RECLEN(de,namlen) \
255 ALIGN((((char *)&(de)->d_name - (char *)de) + (namlen) + 1))
257 #define LINUX_DIRBLKSIZ 512
263 getdents_common(struct linux_getdents64_args *args, int is64bit)
265 struct thread *td = curthread;
266 struct proc *p = td->td_proc;
269 caddr_t inp, buf; /* BSD-format */
270 int reclen; /* BSD-format */
272 caddr_t outp; /* Linux-format */
273 int linuxreclen = 0; /* Linux-format */
280 struct l_dirent linux_dirent;
281 struct l_dirent64 linux_dirent64;
282 int error, eofflag, justone;
283 size_t buflen, nbytes;
284 off_t *cookies = NULL, *cookiep;
287 if ((error = holdvnode(p->p_fd, args->fd, &fp)) != 0)
291 if ((fp->f_flag & FREAD) == 0) {
296 vp = (struct vnode *) fp->f_data;
297 if (vp->v_type != VDIR) {
302 if ((error = VOP_GETATTR(vp, &va)) != 0)
305 nbytes = args->count;
306 if (nbytes == (size_t)-1) {
307 /* readdir(2) case. Always struct dirent. */
312 nbytes = sizeof(linux_dirent);
317 if ((size_t)nbytes < 0)
322 buflen = max(LINUX_DIRBLKSIZ, nbytes);
323 buflen = min(buflen, MAXBSIZE);
324 buf = kmalloc(buflen, M_TEMP, M_WAITOK);
328 aiov.iov_len = buflen;
329 auio.uio_iov = &aiov;
331 auio.uio_rw = UIO_READ;
332 auio.uio_segflg = UIO_SYSSPACE;
334 auio.uio_resid = buflen;
335 auio.uio_offset = off;
338 kfree(cookies, M_TEMP);
344 if ((error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, &ncookies,
349 outp = (caddr_t)args->dirent;
351 if (auio.uio_resid >= buflen)
353 len = buflen - auio.uio_resid;
358 * When using cookies, the vfs has the option of reading from
359 * a different offset than that supplied (UFS truncates the
360 * offset to a block boundary to make sure that it never reads
361 * partway through a directory entry, even if the directory
362 * has been compacted).
364 while (len > 0 && ncookies > 0 && *cookiep < off) {
365 bdp = (struct dirent *) inp;
366 len -= _DIRENT_DIRSIZ(bdp);
367 inp += _DIRENT_DIRSIZ(bdp);
374 if (cookiep && ncookies == 0)
376 bdp = (struct dirent *) inp;
377 reclen = _DIRENT_DIRSIZ(bdp);
383 if (bdp->d_ino == 0) {
396 linuxreclen = (is64bit)
397 ? LINUX_RECLEN(&linux_dirent64, bdp->d_namlen)
398 : LINUX_RECLEN(&linux_dirent, bdp->d_namlen);
400 if (reclen > len || resid < linuxreclen) {
405 bzero(&linux_dirent, sizeof(linux_dirent));
406 bzero(&linux_dirent64, sizeof(linux_dirent64));
408 /* readdir(2) case. */
409 linux_dirent.d_ino = (l_long)INO64TO32(bdp->d_ino);
410 linux_dirent.d_off = (l_off_t)linuxreclen;
411 linux_dirent.d_reclen = (l_ushort)bdp->d_namlen;
412 strcpy(linux_dirent.d_name, bdp->d_name);
413 error = copyout(&linux_dirent, outp, linuxreclen);
416 linux_dirent64.d_ino = bdp->d_ino;
417 linux_dirent64.d_off = (cookiep)
419 : (l_off_t)(off + reclen);
420 linux_dirent64.d_reclen =
421 (l_ushort)linuxreclen;
422 linux_dirent64.d_type = bdp->d_type;
423 strcpy(linux_dirent64.d_name, bdp->d_name);
424 error = copyout(&linux_dirent64, outp,
427 linux_dirent.d_ino = INO64TO32(bdp->d_ino);
428 linux_dirent.d_off = (cookiep)
430 : (l_off_t)(off + reclen);
431 linux_dirent.d_reclen = (l_ushort)linuxreclen;
432 strcpy(linux_dirent.d_name, bdp->d_name);
433 error = copyout(&linux_dirent, outp,
450 resid -= linuxreclen;
456 if (outp == (caddr_t)args->dirent && eofflag == 0)
461 nbytes = resid + linuxreclen;
464 args->sysmsg_iresult = (int)(nbytes - resid);
468 kfree(cookies, M_TEMP);
481 sys_linux_getdents(struct linux_getdents_args *args)
484 if (ldebug(getdents))
485 kprintf(ARGS(getdents, "%d, *, %d"), args->fd, args->count);
487 return (getdents_common((struct linux_getdents64_args*)args, 0));
494 sys_linux_getdents64(struct linux_getdents64_args *args)
497 if (ldebug(getdents64))
498 kprintf(ARGS(getdents64, "%d, *, %d"), args->fd, args->count);
500 return (getdents_common(args, 1));
504 * These exist mainly for hooks for doing /compat/linux translation.
509 sys_linux_access(struct linux_access_args *args)
511 struct nlookupdata nd;
515 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
520 kprintf(ARGS(access, "%s, %d"), path, args->flags);
523 error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW);
525 error = kern_access(&nd, args->flags, 0);
528 linux_free_path(&path);
536 sys_linux_unlink(struct linux_unlink_args *args)
538 struct nlookupdata nd;
542 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
547 kprintf(ARGS(unlink, "%s"), path);
550 error = nlookup_init(&nd, path, UIO_SYSSPACE, 0);
552 error = kern_unlink(&nd);
555 linux_free_path(&path);
563 sys_linux_chdir(struct linux_chdir_args *args)
565 struct nlookupdata nd;
569 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
574 kprintf(ARGS(chdir, "%s"), path);
577 error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW);
579 error = kern_chdir(&nd);
583 linux_free_path(&path);
591 sys_linux_chmod(struct linux_chmod_args *args)
593 struct nlookupdata nd;
597 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
602 kprintf(ARGS(chmod, "%s, %d"), path, args->mode);
605 error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW);
607 error = kern_chmod(&nd, args->mode);
610 linux_free_path(&path);
618 sys_linux_mkdir(struct linux_mkdir_args *args)
620 struct nlookupdata nd;
624 error = linux_copyin_path(args->path, &path, LINUX_PATH_CREATE);
629 kprintf(ARGS(mkdir, "%s, %d"), path, args->mode);
632 error = nlookup_init(&nd, path, UIO_SYSSPACE, 0);
634 error = kern_mkdir(&nd, args->mode);
638 linux_free_path(&path);
646 sys_linux_rmdir(struct linux_rmdir_args *args)
648 struct nlookupdata nd;
652 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
657 kprintf(ARGS(rmdir, "%s"), path);
660 error = nlookup_init(&nd, path, UIO_SYSSPACE, 0);
662 error = kern_rmdir(&nd);
665 linux_free_path(&path);
673 sys_linux_rename(struct linux_rename_args *args)
675 struct nlookupdata fromnd, tond;
679 error = linux_copyin_path(args->from, &from, LINUX_PATH_EXISTS);
682 error = linux_copyin_path(args->to, &to, LINUX_PATH_CREATE);
684 linux_free_path(&from);
689 kprintf(ARGS(rename, "%s, %s"), from, to);
692 error = nlookup_init(&fromnd, from, UIO_SYSSPACE, 0);
694 error = nlookup_init(&tond, to, UIO_SYSSPACE, 0);
696 error = kern_rename(&fromnd, &tond);
699 nlookup_done(&fromnd);
701 linux_free_path(&from);
702 linux_free_path(&to);
710 sys_linux_symlink(struct linux_symlink_args *args)
712 struct thread *td = curthread;
713 struct nlookupdata nd;
718 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
721 error = linux_copyin_path(args->to, &link, LINUX_PATH_CREATE);
723 linux_free_path(&path);
728 kprintf(ARGS(symlink, "%s, %s"), path, link);
731 error = nlookup_init(&nd, link, UIO_SYSSPACE, 0);
733 mode = ACCESSPERMS & ~td->td_proc->p_fd->fd_cmask;
734 error = kern_symlink(&nd, path, mode);
738 linux_free_path(&path);
739 linux_free_path(&link);
747 sys_linux_readlink(struct linux_readlink_args *args)
749 struct nlookupdata nd;
753 error = linux_copyin_path(args->name, &path, LINUX_PATH_EXISTS);
757 if (ldebug(readlink))
758 kprintf(ARGS(readlink, "%s, %p, %d"), path, (void *)args->buf,
762 error = nlookup_init(&nd, path, UIO_SYSSPACE, 0);
764 error = kern_readlink(&nd, args->buf, args->count,
765 &args->sysmsg_iresult);
769 linux_free_path(&path);
777 sys_linux_truncate(struct linux_truncate_args *args)
779 struct nlookupdata nd;
783 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
787 if (ldebug(truncate))
788 kprintf(ARGS(truncate, "%s, %ld"), path,
792 error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW);
794 error = kern_truncate(&nd, args->length);
797 linux_free_path(&path);
805 sys_linux_truncate64(struct linux_truncate64_args *args)
807 struct nlookupdata nd;
811 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
815 if (ldebug(truncate64))
816 kprintf(ARGS(truncate64, "%s, %lld"), path,
817 (off_t)args->length);
820 error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW);
822 error = kern_truncate(&nd, args->length);
825 linux_free_path(&path);
833 sys_linux_ftruncate(struct linux_ftruncate_args *args)
838 if (ldebug(ftruncate))
839 kprintf(ARGS(ftruncate, "%d, %ld"), args->fd,
843 error = kern_ftruncate(args->fd, args->length);
853 sys_linux_ftruncate64(struct linux_ftruncate64_args *args)
858 if (ldebug(ftruncate))
859 kprintf(ARGS(ftruncate64, "%d, %lld"), args->fd,
860 (off_t)args->length);
863 error = kern_ftruncate(args->fd, args->length);
873 sys_linux_link(struct linux_link_args *args)
875 struct nlookupdata nd, linknd;
879 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
882 error = linux_copyin_path(args->to, &link, LINUX_PATH_CREATE);
884 linux_free_path(&path);
889 kprintf(ARGS(link, "%s, %s"), path, link);
892 error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW);
894 error = nlookup_init(&linknd, link, UIO_SYSSPACE, 0);
896 error = kern_link(&nd, &linknd);
897 nlookup_done(&linknd);
901 linux_free_path(&path);
902 linux_free_path(&link);
910 sys_linux_fdatasync(struct linux_fdatasync_args *uap)
912 struct fsync_args bsd;
916 bsd.sysmsg_iresult = 0;
918 error = sys_fsync(&bsd);
919 uap->sysmsg_iresult = bsd.sysmsg_iresult;
927 sys_linux_pread(struct linux_pread_args *uap)
929 struct thread *td = curthread;
934 aiov.iov_base = uap->buf;
935 aiov.iov_len = uap->nbyte;
936 auio.uio_iov = &aiov;
938 auio.uio_offset = uap->offset;
939 auio.uio_resid = uap->nbyte;
940 auio.uio_rw = UIO_READ;
941 auio.uio_segflg = UIO_USERSPACE;
944 if ((ssize_t)auio.uio_resid < 0) {
947 error = kern_preadv(uap->fd, &auio, O_FOFFSET,
948 &uap->sysmsg_szresult);
957 sys_linux_pwrite(struct linux_pwrite_args *uap)
959 struct thread *td = curthread;
964 aiov.iov_base = uap->buf;
965 aiov.iov_len = uap->nbyte;
966 auio.uio_iov = &aiov;
968 auio.uio_offset = uap->offset;
969 auio.uio_resid = uap->nbyte;
970 auio.uio_rw = UIO_WRITE;
971 auio.uio_segflg = UIO_USERSPACE;
974 if ((ssize_t)auio.uio_resid < 0) {
977 error = kern_pwritev(uap->fd, &auio, O_FOFFSET,
978 &uap->sysmsg_szresult);
987 sys_linux_oldumount(struct linux_oldumount_args *args)
989 struct linux_umount_args args2;
992 args2.path = args->path;
994 args2.sysmsg_iresult = 0;
995 error = sys_linux_umount(&args2);
996 args->sysmsg_iresult = args2.sysmsg_iresult;
1004 sys_linux_umount(struct linux_umount_args *args)
1006 struct unmount_args bsd;
1009 bsd.path = args->path;
1010 bsd.flags = args->flags; /* XXX correct? */
1011 bsd.sysmsg_iresult = 0;
1013 error = sys_unmount(&bsd);
1014 args->sysmsg_iresult = bsd.sysmsg_iresult;
1019 * fcntl family of syscalls
1033 linux_to_bsd_flock(struct l_flock *linux_flock, struct flock *bsd_flock)
1035 switch (linux_flock->l_type) {
1037 bsd_flock->l_type = F_RDLCK;
1040 bsd_flock->l_type = F_WRLCK;
1043 bsd_flock->l_type = F_UNLCK;
1046 bsd_flock->l_type = -1;
1049 bsd_flock->l_whence = linux_flock->l_whence;
1050 bsd_flock->l_start = (off_t)linux_flock->l_start;
1051 bsd_flock->l_len = (off_t)linux_flock->l_len;
1052 bsd_flock->l_pid = (pid_t)linux_flock->l_pid;
1059 bsd_to_linux_flock(struct flock *bsd_flock, struct l_flock *linux_flock)
1061 switch (bsd_flock->l_type) {
1063 linux_flock->l_type = LINUX_F_RDLCK;
1066 linux_flock->l_type = LINUX_F_WRLCK;
1069 linux_flock->l_type = LINUX_F_UNLCK;
1072 linux_flock->l_whence = bsd_flock->l_whence;
1073 linux_flock->l_start = (l_off_t)bsd_flock->l_start;
1074 linux_flock->l_len = (l_off_t)bsd_flock->l_len;
1075 linux_flock->l_pid = (l_pid_t)bsd_flock->l_pid;
1078 #if defined(__i386__)
1091 linux_to_bsd_flock64(struct l_flock64 *linux_flock, struct flock *bsd_flock)
1093 switch (linux_flock->l_type) {
1095 bsd_flock->l_type = F_RDLCK;
1098 bsd_flock->l_type = F_WRLCK;
1101 bsd_flock->l_type = F_UNLCK;
1104 bsd_flock->l_type = -1;
1107 bsd_flock->l_whence = linux_flock->l_whence;
1108 bsd_flock->l_start = (off_t)linux_flock->l_start;
1109 bsd_flock->l_len = (off_t)linux_flock->l_len;
1110 bsd_flock->l_pid = (pid_t)linux_flock->l_pid;
1117 bsd_to_linux_flock64(struct flock *bsd_flock, struct l_flock64 *linux_flock)
1119 switch (bsd_flock->l_type) {
1121 linux_flock->l_type = LINUX_F_RDLCK;
1124 linux_flock->l_type = LINUX_F_WRLCK;
1127 linux_flock->l_type = LINUX_F_UNLCK;
1130 linux_flock->l_whence = bsd_flock->l_whence;
1131 linux_flock->l_start = (l_loff_t)bsd_flock->l_start;
1132 linux_flock->l_len = (l_loff_t)bsd_flock->l_len;
1133 linux_flock->l_pid = (l_pid_t)bsd_flock->l_pid;
1135 #endif /* __i386__ */
1141 linux_fcntl_common(struct linux_fcntl64_args *args)
1143 struct thread *td = curthread;
1144 struct l_flock linux_flock;
1146 union fcntl_dat dat;
1149 switch (args->cmd) {
1152 dat.fc_fd = args->arg;
1159 dat.fc_cloexec = args->arg;
1167 if (args->arg & LINUX_O_NDELAY)
1168 dat.fc_flags |= O_NONBLOCK;
1169 if (args->arg & LINUX_O_APPEND)
1170 dat.fc_flags |= O_APPEND;
1171 if (args->arg & LINUX_O_SYNC)
1172 dat.fc_flags |= O_FSYNC;
1173 if (args->arg & LINUX_FASYNC)
1174 dat.fc_flags |= O_ASYNC;
1178 case LINUX_F_SETLKW:
1180 error = copyin((caddr_t)args->arg, &linux_flock,
1181 sizeof(linux_flock));
1184 linux_to_bsd_flock(&linux_flock, &dat.fc_flock);
1186 case LINUX_F_GETOWN:
1189 case LINUX_F_SETOWN:
1191 * XXX some Linux applications depend on F_SETOWN having no
1192 * significant effect for pipes (SIGIO is not delivered for
1193 * pipes under Linux-2.2.35 at least).
1195 fp = holdfp(td->td_proc->p_fd, args->fd, -1);
1198 if (fp->f_type == DTYPE_PIPE) {
1204 dat.fc_owner = args->arg;
1211 error = kern_fcntl(args->fd, cmd, &dat, td->td_ucred);
1214 switch (args->cmd) {
1216 args->sysmsg_iresult = dat.fc_fd;
1219 args->sysmsg_iresult = dat.fc_cloexec;
1224 args->sysmsg_iresult = 0;
1225 if (dat.fc_flags & O_RDONLY)
1226 args->sysmsg_iresult |= LINUX_O_RDONLY;
1227 if (dat.fc_flags & O_WRONLY)
1228 args->sysmsg_iresult |= LINUX_O_WRONLY;
1229 if (dat.fc_flags & O_RDWR)
1230 args->sysmsg_iresult |= LINUX_O_RDWR;
1231 if (dat.fc_flags & O_NDELAY)
1232 args->sysmsg_iresult |= LINUX_O_NONBLOCK;
1233 if (dat.fc_flags & O_APPEND)
1234 args->sysmsg_iresult |= LINUX_O_APPEND;
1235 if (dat.fc_flags & O_FSYNC)
1236 args->sysmsg_iresult |= LINUX_O_SYNC;
1237 if (dat.fc_flags & O_ASYNC)
1238 args->sysmsg_iresult |= LINUX_FASYNC;
1241 bsd_to_linux_flock(&dat.fc_flock, &linux_flock);
1242 error = copyout(&linux_flock, (caddr_t)args->arg,
1243 sizeof(linux_flock));
1246 case LINUX_F_SETLKW:
1248 case LINUX_F_GETOWN:
1249 args->sysmsg_iresult = dat.fc_owner;
1251 case LINUX_F_SETOWN:
1263 sys_linux_fcntl(struct linux_fcntl_args *args)
1265 struct linux_fcntl64_args args64;
1270 kprintf(ARGS(fcntl, "%d, %08x, *"), args->fd, args->cmd);
1273 args64.fd = args->fd;
1274 args64.cmd = args->cmd;
1275 args64.arg = args->arg;
1276 args64.sysmsg_iresult = 0;
1277 error = linux_fcntl_common(&args64);
1278 args->sysmsg_iresult = args64.sysmsg_iresult;
1282 #if defined(__i386__)
1287 sys_linux_fcntl64(struct linux_fcntl64_args *args)
1289 struct thread *td = curthread;
1290 struct l_flock64 linux_flock;
1291 union fcntl_dat dat;
1295 if (ldebug(fcntl64))
1296 kprintf(ARGS(fcntl64, "%d, %08x, *"), args->fd, args->cmd);
1298 if (args->cmd == LINUX_F_GETLK64 || args->cmd == LINUX_F_SETLK64 ||
1299 args->cmd == LINUX_F_SETLKW64) {
1300 switch (args->cmd) {
1301 case LINUX_F_GETLK64:
1304 case LINUX_F_SETLK64:
1307 case LINUX_F_SETLKW64:
1312 error = copyin((caddr_t)args->arg, &linux_flock,
1313 sizeof(linux_flock));
1316 linux_to_bsd_flock64(&linux_flock, &dat.fc_flock);
1319 error = kern_fcntl(args->fd, cmd, &dat, td->td_ucred);
1321 if (error == 0 && args->cmd == LINUX_F_GETLK64) {
1322 bsd_to_linux_flock64(&dat.fc_flock, &linux_flock);
1323 error = copyout(&linux_flock, (caddr_t)args->arg,
1324 sizeof(linux_flock));
1327 error = linux_fcntl_common(args);
1332 #endif /* __i386__ */
1338 sys_linux_chown(struct linux_chown_args *args)
1340 struct nlookupdata nd;
1344 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
1349 kprintf(ARGS(chown, "%s, %d, %d"), path, args->uid, args->gid);
1352 error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW);
1354 error = kern_chown(&nd, args->uid, args->gid);
1357 linux_free_path(&path);
1365 sys_linux_lchown(struct linux_lchown_args *args)
1367 struct nlookupdata nd;
1371 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
1376 kprintf(ARGS(lchown, "%s, %d, %d"), path, args->uid, args->gid);
1379 error = nlookup_init(&nd, path, UIO_SYSSPACE, 0);
1381 error = kern_chown(&nd, args->uid, args->gid);
1384 linux_free_path(&path);