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.18 2004/10/12 19:20:37 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>
40 #include <sys/filedesc.h>
41 #include <sys/kern_syscall.h>
43 #include <sys/malloc.h>
44 #include <sys/mount.h>
45 #include <sys/namei.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"
63 linux_creat(struct linux_creat_args *args)
65 struct thread *td = curthread;
70 error = linux_copyin_path(args->path, &path, LINUX_PATH_CREATE);
75 printf(ARGS(creat, "%s, %d"), path, args->mode);
77 NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW, UIO_SYSSPACE, path, td);
79 error = kern_open(&nd, O_WRONLY | O_CREAT | O_TRUNC, args->mode,
80 &args->sysmsg_result);
82 linux_free_path(&path);
88 linux_open(struct linux_open_args *args)
90 struct thread *td = curthread;
91 struct proc *p = td->td_proc;
98 if (args->flags & LINUX_O_CREAT) {
99 error = linux_copyin_path(args->path, &path,
102 error = linux_copyin_path(args->path, &path,
110 printf(ARGS(open, "%s, 0x%x, 0x%x"), path, args->flags,
114 if (args->flags & LINUX_O_RDONLY)
116 if (args->flags & LINUX_O_WRONLY)
118 if (args->flags & LINUX_O_RDWR)
120 if (args->flags & LINUX_O_NDELAY)
122 if (args->flags & LINUX_O_APPEND)
124 if (args->flags & LINUX_O_SYNC)
126 if (args->flags & LINUX_O_NONBLOCK)
128 if (args->flags & LINUX_FASYNC)
130 if (args->flags & LINUX_O_CREAT)
132 if (args->flags & LINUX_O_TRUNC)
134 if (args->flags & LINUX_O_EXCL)
136 if (args->flags & LINUX_O_NOCTTY)
138 NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW, UIO_SYSSPACE, path, td);
140 error = kern_open(&nd, flags, args->mode, &args->sysmsg_result);
142 if (error == 0 && !(flags & O_NOCTTY) &&
143 SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) {
144 struct filedesc *fdp = p->p_fd;
145 struct file *fp = fdp->fd_ofiles[args->sysmsg_result];
147 if (fp->f_type == DTYPE_VNODE)
148 fo_ioctl(fp, TIOCSCTTY, (caddr_t) 0, td);
152 printf(LMSG("open returns error %d"), error);
154 linux_free_path(&path);
159 linux_lseek(struct linux_lseek_args *args)
165 printf(ARGS(lseek, "%d, %ld, %d"),
166 args->fdes, (long)args->off, args->whence);
168 error = kern_lseek(args->fdes, args->off, args->whence,
169 &args->sysmsg_offset);
176 linux_llseek(struct linux_llseek_args *args)
183 printf(ARGS(llseek, "%d, %d:%d, %d"),
184 args->fd, args->ohigh, args->olow, args->whence);
186 off = (args->olow) | (((off_t) args->ohigh) << 32);
188 error = kern_lseek(args->fd, off, args->whence, &res);
191 error = copyout(&res, args->res, sizeof(res));
194 #endif /*!__alpha__*/
198 linux_readdir(struct linux_readdir_args *args)
200 struct linux_getdents_args lda;
204 lda.dent = args->dent;
206 lda.sysmsg_result = 0;
207 error = linux_getdents(&lda);
208 args->sysmsg_result = lda.sysmsg_result;
211 #endif /*!__alpha__*/
214 * Note that linux_getdents(2) and linux_getdents64(2) have the same
215 * arguments. They only differ in the definition of struct dirent they
216 * operate on. We use this to common the code, with the exception of
217 * accessing struct dirent. Note that linux_readdir(2) is implemented
218 * by means of linux_getdents(2). In this case we never operate on
219 * struct dirent64 and thus don't need to handle it...
226 char d_name[LINUX_NAME_MAX + 1];
234 char d_name[LINUX_NAME_MAX + 1];
237 #define LINUX_RECLEN(de,namlen) \
238 ALIGN((((char *)&(de)->d_name - (char *)de) + (namlen) + 1))
240 #define LINUX_DIRBLKSIZ 512
243 getdents_common(struct linux_getdents64_args *args, int is64bit)
245 struct thread *td = curthread;
246 struct proc *p = td->td_proc;
249 caddr_t inp, buf; /* BSD-format */
250 int len, reclen; /* BSD-format */
251 caddr_t outp; /* Linux-format */
252 int resid, linuxreclen=0; /* Linux-format */
258 struct l_dirent linux_dirent;
259 struct l_dirent64 linux_dirent64;
260 int buflen, error, eofflag, nbytes, justone;
261 u_long *cookies = NULL, *cookiep;
266 if ((error = getvnode(p->p_fd, args->fd, &fp)) != 0)
269 if ((fp->f_flag & FREAD) == 0)
272 vp = (struct vnode *) fp->f_data;
273 if (vp->v_type != VDIR)
276 if ((error = VOP_GETATTR(vp, &va, td)))
279 nbytes = args->count;
281 /* readdir(2) case. Always struct dirent. */
284 nbytes = sizeof(linux_dirent);
291 buflen = max(LINUX_DIRBLKSIZ, nbytes);
292 buflen = min(buflen, MAXBSIZE);
293 buf = malloc(buflen, M_TEMP, M_WAITOK);
294 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
298 aiov.iov_len = buflen;
299 auio.uio_iov = &aiov;
301 auio.uio_rw = UIO_READ;
302 auio.uio_segflg = UIO_SYSSPACE;
304 auio.uio_resid = buflen;
305 auio.uio_offset = off;
308 free(cookies, M_TEMP);
312 if ((error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, &ncookies,
317 outp = (caddr_t)args->dirent;
319 if ((len = buflen - auio.uio_resid) <= 0)
326 * When using cookies, the vfs has the option of reading from
327 * a different offset than that supplied (UFS truncates the
328 * offset to a block boundary to make sure that it never reads
329 * partway through a directory entry, even if the directory
330 * has been compacted).
332 while (len > 0 && ncookies > 0 && *cookiep <= off) {
333 bdp = (struct dirent *) inp;
334 len -= bdp->d_reclen;
335 inp += bdp->d_reclen;
342 if (cookiep && ncookies == 0)
344 bdp = (struct dirent *) inp;
345 reclen = bdp->d_reclen;
351 if (bdp->d_fileno == 0) {
363 linuxreclen = (is64bit)
364 ? LINUX_RECLEN(&linux_dirent64, bdp->d_namlen)
365 : LINUX_RECLEN(&linux_dirent, bdp->d_namlen);
367 if (reclen > len || resid < linuxreclen) {
373 /* readdir(2) case. */
374 linux_dirent.d_ino = (l_long)bdp->d_fileno;
375 linux_dirent.d_off = (l_off_t)linuxreclen;
376 linux_dirent.d_reclen = (l_ushort)bdp->d_namlen;
377 strcpy(linux_dirent.d_name, bdp->d_name);
378 error = copyout(&linux_dirent, outp, linuxreclen);
381 linux_dirent64.d_ino = bdp->d_fileno;
382 linux_dirent64.d_off = (cookiep)
384 : (l_off_t)(off + reclen);
385 linux_dirent64.d_reclen =
386 (l_ushort)linuxreclen;
387 linux_dirent64.d_type = bdp->d_type;
388 strcpy(linux_dirent64.d_name, bdp->d_name);
389 error = copyout(&linux_dirent64, outp,
392 linux_dirent.d_ino = bdp->d_fileno;
393 linux_dirent.d_off = (cookiep)
395 : (l_off_t)(off + reclen);
396 linux_dirent.d_reclen = (l_ushort)linuxreclen;
397 strcpy(linux_dirent.d_name, bdp->d_name);
398 error = copyout(&linux_dirent, outp,
413 resid -= linuxreclen;
419 if (outp == (caddr_t)args->dirent)
424 nbytes = resid + linuxreclen;
427 args->sysmsg_result = nbytes - resid;
431 free(cookies, M_TEMP);
433 VOP_UNLOCK(vp, 0, td);
439 linux_getdents(struct linux_getdents_args *args)
442 if (ldebug(getdents))
443 printf(ARGS(getdents, "%d, *, %d"), args->fd, args->count);
445 return (getdents_common((struct linux_getdents64_args*)args, 0));
449 linux_getdents64(struct linux_getdents64_args *args)
452 if (ldebug(getdents64))
453 printf(ARGS(getdents64, "%d, *, %d"), args->fd, args->count);
455 return (getdents_common(args, 1));
459 * These exist mainly for hooks for doing /compat/linux translation.
463 linux_access(struct linux_access_args *args)
465 struct thread *td = curthread;
470 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
475 printf(ARGS(access, "%s, %d"), path, args->flags);
477 NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW | CNP_LOCKLEAF | CNP_NOOBJ,
478 UIO_SYSSPACE, path, td);
480 error = kern_access(&nd, args->flags);
482 linux_free_path(&path);
487 linux_unlink(struct linux_unlink_args *args)
489 struct thread *td = curthread;
494 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
499 printf(ARGS(unlink, "%s"), path);
501 NDINIT(&nd, NAMEI_DELETE, CNP_LOCKPARENT, UIO_SYSSPACE, path, td);
503 error = kern_unlink(&nd);
505 linux_free_path(&path);
510 linux_chdir(struct linux_chdir_args *args)
512 struct nlookupdata nd;
516 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
521 printf(ARGS(chdir, "%s"), path);
523 error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW);
525 error = kern_chdir(&nd);
528 linux_free_path(&path);
533 linux_chmod(struct linux_chmod_args *args)
535 struct thread *td = curthread;
540 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
545 printf(ARGS(chmod, "%s, %d"), path, args->mode);
547 NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW, UIO_SYSSPACE, path, td);
549 error = kern_chmod(&nd, args->mode);
551 linux_free_path(&path);
556 linux_mkdir(struct linux_mkdir_args *args)
558 struct thread *td = curthread;
563 error = linux_copyin_path(args->path, &path, LINUX_PATH_CREATE);
568 printf(ARGS(mkdir, "%s, %d"), path, args->mode);
570 NDINIT(&nd, NAMEI_CREATE, CNP_LOCKPARENT, UIO_SYSSPACE, path, td);
572 error = kern_mkdir(&nd, args->mode);
574 linux_free_path(&path);
579 linux_rmdir(struct linux_rmdir_args *args)
581 struct thread *td = curthread;
586 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
591 printf(ARGS(rmdir, "%s"), path);
593 NDINIT(&nd, NAMEI_DELETE, CNP_LOCKPARENT | CNP_LOCKLEAF,
594 UIO_SYSSPACE, path, td);
596 error = kern_rmdir(&nd);
598 linux_free_path(&path);
603 linux_rename(struct linux_rename_args *args)
605 struct thread *td = curthread;
606 struct nameidata fromnd, tond;
610 error = linux_copyin_path(args->from, &from, LINUX_PATH_EXISTS);
613 error = linux_copyin_path(args->to, &to, LINUX_PATH_CREATE);
615 linux_free_path(&from);
620 printf(ARGS(rename, "%s, %s"), from, to);
622 NDINIT(&fromnd, NAMEI_DELETE, CNP_WANTPARENT | CNP_SAVESTART,
623 UIO_SYSSPACE, from, td);
624 NDINIT(&tond, NAMEI_RENAME,
625 CNP_LOCKPARENT | CNP_LOCKLEAF | CNP_NOCACHE |
626 CNP_SAVESTART | CNP_NOOBJ,
627 UIO_SYSSPACE, to, td);
629 error = kern_rename(&fromnd, &tond);
631 linux_free_path(&from);
632 linux_free_path(&to);
637 linux_symlink(struct linux_symlink_args *args)
639 struct thread *td = curthread;
644 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
647 error = linux_copyin_path(args->to, &link, LINUX_PATH_CREATE);
649 linux_free_path(&path);
654 printf(ARGS(symlink, "%s, %s"), path, link);
656 NDINIT(&nd, NAMEI_CREATE, CNP_LOCKPARENT | CNP_NOOBJ, UIO_SYSSPACE,
659 error = kern_symlink(path, &nd);
661 linux_free_path(&path);
662 linux_free_path(&link);
667 linux_readlink(struct linux_readlink_args *args)
669 struct thread *td = curthread;
674 error = linux_copyin_path(args->name, &path, LINUX_PATH_EXISTS);
678 if (ldebug(readlink))
679 printf(ARGS(readlink, "%s, %p, %d"), path, (void *)args->buf,
682 NDINIT(&nd, NAMEI_LOOKUP, CNP_LOCKLEAF | CNP_NOOBJ, UIO_SYSSPACE,
685 error = kern_readlink(&nd, args->buf, args->count,
686 &args->sysmsg_result);
688 linux_free_path(&path);
693 linux_truncate(struct linux_truncate_args *args)
695 struct thread *td = curthread;
700 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
704 if (ldebug(truncate))
705 printf(ARGS(truncate, "%s, %ld"), path,
708 NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW, UIO_SYSSPACE, path, td);
710 error = kern_truncate(&nd, args->length);
712 linux_free_path(&path);
717 linux_truncate64(struct linux_truncate64_args *args)
719 struct thread *td = curthread;
724 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
728 if (ldebug(truncate64))
729 printf(ARGS(truncate64, "%s, %lld"), path,
730 (off_t)args->length);
732 NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW, UIO_SYSSPACE, path, td);
734 error = kern_truncate(&nd, args->length);
736 linux_free_path(&path);
741 linux_ftruncate(struct linux_ftruncate_args *args)
746 if (ldebug(ftruncate))
747 printf(ARGS(ftruncate, "%d, %ld"), args->fd,
750 error = kern_ftruncate(args->fd, args->length);
756 linux_ftruncate64(struct linux_ftruncate64_args *args)
761 if (ldebug(ftruncate))
762 printf(ARGS(ftruncate64, "%d, %lld"), args->fd,
763 (off_t)args->length);
765 error = kern_ftruncate(args->fd, args->length);
771 linux_link(struct linux_link_args *args)
773 struct thread *td = curthread;
774 struct nameidata nd, linknd;
778 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
781 error = linux_copyin_path(args->to, &link, LINUX_PATH_CREATE);
783 linux_free_path(&path);
788 printf(ARGS(link, "%s, %s"), path, link);
790 NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW | CNP_NOOBJ, UIO_SYSSPACE,
792 NDINIT(&linknd, NAMEI_CREATE, CNP_LOCKPARENT | CNP_NOOBJ,
793 UIO_SYSSPACE, link, td);
795 error = kern_link(&nd, &linknd);
797 linux_free_path(&path);
798 linux_free_path(&link);
804 linux_fdatasync(struct linux_fdatasync_args *uap)
806 struct fsync_args bsd;
810 bsd.sysmsg_result = 0;
813 uap->sysmsg_result = bsd.sysmsg_result;
816 #endif /*!__alpha__*/
819 linux_pread(struct linux_pread_args *uap)
821 struct thread *td = curthread;
826 aiov.iov_base = uap->buf;
827 aiov.iov_len = uap->nbyte;
828 auio.uio_iov = &aiov;
830 auio.uio_offset = uap->offset;
831 auio.uio_resid = uap->nbyte;
832 auio.uio_rw = UIO_READ;
833 auio.uio_segflg = UIO_USERSPACE;
836 error = kern_readv(uap->fd, &auio, FOF_OFFSET, &uap->sysmsg_result);
842 linux_pwrite(struct linux_pwrite_args *uap)
844 struct thread *td = curthread;
849 aiov.iov_base = uap->buf;
850 aiov.iov_len = uap->nbyte;
851 auio.uio_iov = &aiov;
853 auio.uio_offset = uap->offset;
854 auio.uio_resid = uap->nbyte;
855 auio.uio_rw = UIO_WRITE;
856 auio.uio_segflg = UIO_USERSPACE;
859 error = kern_writev(uap->fd, &auio, FOF_OFFSET, &uap->sysmsg_result);
865 linux_oldumount(struct linux_oldumount_args *args)
867 struct linux_umount_args args2;
870 args2.path = args->path;
872 args2.sysmsg_result = 0;
873 error = linux_umount(&args2);
874 args->sysmsg_result = args2.sysmsg_result;
879 linux_umount(struct linux_umount_args *args)
881 struct unmount_args bsd;
884 bsd.path = args->path;
885 bsd.flags = args->flags; /* XXX correct? */
886 bsd.sysmsg_result = 0;
888 error = unmount(&bsd);
889 args->sysmsg_result = bsd.sysmsg_result;
894 * fcntl family of syscalls
906 linux_to_bsd_flock(struct l_flock *linux_flock, struct flock *bsd_flock)
908 switch (linux_flock->l_type) {
910 bsd_flock->l_type = F_RDLCK;
913 bsd_flock->l_type = F_WRLCK;
916 bsd_flock->l_type = F_UNLCK;
919 bsd_flock->l_type = -1;
922 bsd_flock->l_whence = linux_flock->l_whence;
923 bsd_flock->l_start = (off_t)linux_flock->l_start;
924 bsd_flock->l_len = (off_t)linux_flock->l_len;
925 bsd_flock->l_pid = (pid_t)linux_flock->l_pid;
929 bsd_to_linux_flock(struct flock *bsd_flock, struct l_flock *linux_flock)
931 switch (bsd_flock->l_type) {
933 linux_flock->l_type = LINUX_F_RDLCK;
936 linux_flock->l_type = LINUX_F_WRLCK;
939 linux_flock->l_type = LINUX_F_UNLCK;
942 linux_flock->l_whence = bsd_flock->l_whence;
943 linux_flock->l_start = (l_off_t)bsd_flock->l_start;
944 linux_flock->l_len = (l_off_t)bsd_flock->l_len;
945 linux_flock->l_pid = (l_pid_t)bsd_flock->l_pid;
948 #if defined(__i386__)
958 linux_to_bsd_flock64(struct l_flock64 *linux_flock, struct flock *bsd_flock)
960 switch (linux_flock->l_type) {
962 bsd_flock->l_type = F_RDLCK;
965 bsd_flock->l_type = F_WRLCK;
968 bsd_flock->l_type = F_UNLCK;
971 bsd_flock->l_type = -1;
974 bsd_flock->l_whence = linux_flock->l_whence;
975 bsd_flock->l_start = (off_t)linux_flock->l_start;
976 bsd_flock->l_len = (off_t)linux_flock->l_len;
977 bsd_flock->l_pid = (pid_t)linux_flock->l_pid;
981 bsd_to_linux_flock64(struct flock *bsd_flock, struct l_flock64 *linux_flock)
983 switch (bsd_flock->l_type) {
985 linux_flock->l_type = LINUX_F_RDLCK;
988 linux_flock->l_type = LINUX_F_WRLCK;
991 linux_flock->l_type = LINUX_F_UNLCK;
994 linux_flock->l_whence = bsd_flock->l_whence;
995 linux_flock->l_start = (l_loff_t)bsd_flock->l_start;
996 linux_flock->l_len = (l_loff_t)bsd_flock->l_len;
997 linux_flock->l_pid = (l_pid_t)bsd_flock->l_pid;
999 #endif /* __i386__ */
1001 #if defined(__alpha__)
1002 #define linux_fcntl64_args linux_fcntl_args
1006 linux_fcntl_common(struct linux_fcntl64_args *args)
1008 struct proc *p = curproc;
1009 struct l_flock linux_flock;
1010 struct filedesc *fdp;
1012 union fcntl_dat dat;
1015 switch (args->cmd) {
1018 dat.fc_fd = args->arg;
1025 dat.fc_cloexec = args->arg;
1033 if (args->arg & LINUX_O_NDELAY)
1034 dat.fc_flags |= O_NONBLOCK;
1035 if (args->arg & LINUX_O_APPEND)
1036 dat.fc_flags |= O_APPEND;
1037 if (args->arg & LINUX_O_SYNC)
1038 dat.fc_flags |= O_FSYNC;
1039 if (args->arg & LINUX_FASYNC)
1040 dat.fc_flags |= O_ASYNC;
1044 case LINUX_F_SETLKW:
1046 error = copyin((caddr_t)args->arg, &linux_flock,
1047 sizeof(linux_flock));
1050 linux_to_bsd_flock(&linux_flock, &dat.fc_flock);
1052 case LINUX_F_GETOWN:
1055 case LINUX_F_SETOWN:
1057 * XXX some Linux applications depend on F_SETOWN having no
1058 * significant effect for pipes (SIGIO is not delivered for
1059 * pipes under Linux-2.2.35 at least).
1062 if ((u_int)args->fd >= fdp->fd_nfiles ||
1063 (fp = fdp->fd_ofiles[args->fd]) == NULL)
1065 if (fp->f_type == DTYPE_PIPE)
1068 dat.fc_owner = args->arg;
1074 error = kern_fcntl(args->fd, cmd, &dat);
1077 switch (args->cmd) {
1079 args->sysmsg_result = dat.fc_fd;
1082 args->sysmsg_result = dat.fc_cloexec;
1087 args->sysmsg_result = 0;
1088 if (dat.fc_flags & O_RDONLY)
1089 args->sysmsg_result |= LINUX_O_RDONLY;
1090 if (dat.fc_flags & O_WRONLY)
1091 args->sysmsg_result |= LINUX_O_WRONLY;
1092 if (dat.fc_flags & O_RDWR)
1093 args->sysmsg_result |= LINUX_O_RDWR;
1094 if (dat.fc_flags & O_NDELAY)
1095 args->sysmsg_result |= LINUX_O_NONBLOCK;
1096 if (dat.fc_flags & O_APPEND)
1097 args->sysmsg_result |= LINUX_O_APPEND;
1098 if (dat.fc_flags & O_FSYNC)
1099 args->sysmsg_result |= LINUX_O_SYNC;
1100 if (dat.fc_flags & O_ASYNC)
1101 args->sysmsg_result |= LINUX_FASYNC;
1104 bsd_to_linux_flock(&dat.fc_flock, &linux_flock);
1105 error = copyout(&linux_flock, (caddr_t)args->arg,
1106 sizeof(linux_flock));
1109 case LINUX_F_SETLKW:
1111 case LINUX_F_GETOWN:
1112 args->sysmsg_result = dat.fc_owner;
1114 case LINUX_F_SETOWN:
1123 linux_fcntl(struct linux_fcntl_args *args)
1125 struct linux_fcntl64_args args64;
1130 printf(ARGS(fcntl, "%d, %08x, *"), args->fd, args->cmd);
1133 args64.fd = args->fd;
1134 args64.cmd = args->cmd;
1135 args64.arg = args->arg;
1136 args64.sysmsg_result = 0;
1137 error = linux_fcntl_common(&args64);
1138 args->sysmsg_result = args64.sysmsg_result;
1142 #if defined(__i386__)
1144 linux_fcntl64(struct linux_fcntl64_args *args)
1146 struct l_flock64 linux_flock;
1147 union fcntl_dat dat;
1151 if (ldebug(fcntl64))
1152 printf(ARGS(fcntl64, "%d, %08x, *"), args->fd, args->cmd);
1154 if (args->cmd == LINUX_F_GETLK64 || args->cmd == LINUX_F_SETLK64 ||
1155 args->cmd == LINUX_F_SETLKW64) {
1156 switch (args->cmd) {
1157 case LINUX_F_GETLK64:
1160 case LINUX_F_SETLK64:
1163 case LINUX_F_SETLKW64:
1168 error = copyin((caddr_t)args->arg, &linux_flock,
1169 sizeof(linux_flock));
1172 linux_to_bsd_flock64(&linux_flock, &dat.fc_flock);
1174 error = kern_fcntl(args->fd, cmd, &dat);
1176 if (error == 0 && args->cmd == LINUX_F_GETLK64) {
1177 bsd_to_linux_flock64(&dat.fc_flock, &linux_flock);
1178 error = copyout(&linux_flock, (caddr_t)args->arg,
1179 sizeof(linux_flock));
1182 error = linux_fcntl_common(args);
1187 #endif /* __i386__ */
1190 linux_chown(struct linux_chown_args *args)
1192 struct thread *td = curthread;
1193 struct nameidata nd;
1197 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
1202 printf(ARGS(chown, "%s, %d, %d"), path, args->uid, args->gid);
1204 NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW, UIO_SYSSPACE, path, td);
1206 error = kern_chown(&nd, args->uid, args->gid);
1208 linux_free_path(&path);
1213 linux_lchown(struct linux_lchown_args *args)
1215 struct thread *td = curthread;
1216 struct nameidata nd;
1220 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
1225 printf(ARGS(lchown, "%s, %d, %d"), path, args->uid, args->gid);
1227 NDINIT(&nd, NAMEI_LOOKUP, 0, UIO_SYSSPACE, path, td);
1229 error = kern_chown(&nd, args->uid, args->gid);
1231 linux_free_path(&path);