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.36 2006/09/05 00:55:44 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"
62 sys_linux_creat(struct linux_creat_args *args)
64 struct nlookupdata nd;
68 error = linux_copyin_path(args->path, &path, LINUX_PATH_CREATE);
73 printf(ARGS(creat, "%s, %d"), path, args->mode);
75 error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW);
77 error = kern_open(&nd, O_WRONLY | O_CREAT | O_TRUNC,
78 args->mode, &args->sysmsg_result);
80 linux_free_path(&path);
85 sys_linux_open(struct linux_open_args *args)
87 struct thread *td = curthread;
88 struct proc *p = td->td_proc;
89 struct nlookupdata nd;
95 if (args->flags & LINUX_O_CREAT) {
96 error = linux_copyin_path(args->path, &path,
99 error = linux_copyin_path(args->path, &path,
107 printf(ARGS(open, "%s, 0x%x, 0x%x"), path, args->flags,
111 if (args->flags & LINUX_O_RDONLY)
113 if (args->flags & LINUX_O_WRONLY)
115 if (args->flags & LINUX_O_RDWR)
117 if (args->flags & LINUX_O_NDELAY)
119 if (args->flags & LINUX_O_APPEND)
121 if (args->flags & LINUX_O_SYNC)
123 if (args->flags & LINUX_O_NONBLOCK)
125 if (args->flags & LINUX_FASYNC)
127 if (args->flags & LINUX_O_CREAT)
129 if (args->flags & LINUX_O_TRUNC)
131 if (args->flags & LINUX_O_EXCL)
133 if (args->flags & LINUX_O_NOCTTY)
135 error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW);
137 error = kern_open(&nd, flags,
138 args->mode, &args->sysmsg_result);
141 if (error == 0 && !(flags & O_NOCTTY) &&
142 SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) {
145 fp = holdfp(p->p_fd, args->sysmsg_result, -1);
147 if (fp->f_type == DTYPE_VNODE)
148 fo_ioctl(fp, TIOCSCTTY, NULL, p->p_ucred);
154 printf(LMSG("open returns error %d"), error);
156 linux_free_path(&path);
161 sys_linux_lseek(struct linux_lseek_args *args)
167 printf(ARGS(lseek, "%d, %ld, %d"),
168 args->fdes, (long)args->off, args->whence);
170 error = kern_lseek(args->fdes, args->off, args->whence,
171 &args->sysmsg_offset);
177 sys_linux_llseek(struct linux_llseek_args *args)
184 printf(ARGS(llseek, "%d, %d:%d, %d"),
185 args->fd, args->ohigh, args->olow, args->whence);
187 off = (args->olow) | (((off_t) args->ohigh) << 32);
189 error = kern_lseek(args->fd, off, args->whence, &res);
192 error = copyout(&res, args->res, sizeof(res));
197 sys_linux_readdir(struct linux_readdir_args *args)
199 struct linux_getdents_args lda;
203 lda.dent = args->dent;
205 lda.sysmsg_result = 0;
206 error = sys_linux_getdents(&lda);
207 args->sysmsg_result = lda.sysmsg_result;
212 * Note that linux_getdents(2) and linux_getdents64(2) have the same
213 * arguments. They only differ in the definition of struct dirent they
214 * operate on. We use this to common the code, with the exception of
215 * accessing struct dirent. Note that linux_readdir(2) is implemented
216 * by means of linux_getdents(2). In this case we never operate on
217 * struct dirent64 and thus don't need to handle it...
224 char d_name[LINUX_NAME_MAX + 1];
232 char d_name[LINUX_NAME_MAX + 1];
235 #define LINUX_RECLEN(de,namlen) \
236 ALIGN((((char *)&(de)->d_name - (char *)de) + (namlen) + 1))
238 #define LINUX_DIRBLKSIZ 512
241 getdents_common(struct linux_getdents64_args *args, int is64bit)
243 struct thread *td = curthread;
244 struct proc *p = td->td_proc;
247 caddr_t inp, buf; /* BSD-format */
248 int len, reclen; /* BSD-format */
249 caddr_t outp; /* Linux-format */
250 int resid, linuxreclen=0; /* Linux-format */
256 struct l_dirent linux_dirent;
257 struct l_dirent64 linux_dirent64;
258 int buflen, error, eofflag, nbytes, justone;
259 u_long *cookies = NULL, *cookiep;
264 if ((error = holdvnode(p->p_fd, args->fd, &fp)) != 0)
267 if ((fp->f_flag & FREAD) == 0) {
272 vp = (struct vnode *) fp->f_data;
273 if (vp->v_type != VDIR) {
278 if ((error = VOP_GETATTR(vp, &va)) != 0)
281 nbytes = args->count;
283 /* readdir(2) case. Always struct dirent. */
288 nbytes = sizeof(linux_dirent);
296 buflen = max(LINUX_DIRBLKSIZ, nbytes);
297 buflen = min(buflen, MAXBSIZE);
298 buf = kmalloc(buflen, M_TEMP, M_WAITOK);
302 aiov.iov_len = buflen;
303 auio.uio_iov = &aiov;
305 auio.uio_rw = UIO_READ;
306 auio.uio_segflg = UIO_SYSSPACE;
308 auio.uio_resid = buflen;
309 auio.uio_offset = off;
312 kfree(cookies, M_TEMP);
316 if ((error = VOP_READDIR(vp, &auio, fp->f_cred, &eofflag, &ncookies,
321 outp = (caddr_t)args->dirent;
323 if ((len = buflen - auio.uio_resid) <= 0)
330 * When using cookies, the vfs has the option of reading from
331 * a different offset than that supplied (UFS truncates the
332 * offset to a block boundary to make sure that it never reads
333 * partway through a directory entry, even if the directory
334 * has been compacted).
336 while (len > 0 && ncookies > 0 && *cookiep <= off) {
337 bdp = (struct dirent *) inp;
338 len -= _DIRENT_DIRSIZ(bdp);
339 inp += _DIRENT_DIRSIZ(bdp);
346 if (cookiep && ncookies == 0)
348 bdp = (struct dirent *) inp;
349 reclen = _DIRENT_DIRSIZ(bdp);
355 if (bdp->d_ino == 0) {
367 linuxreclen = (is64bit)
368 ? LINUX_RECLEN(&linux_dirent64, bdp->d_namlen)
369 : LINUX_RECLEN(&linux_dirent, bdp->d_namlen);
371 if (reclen > len || resid < linuxreclen) {
377 /* readdir(2) case. */
378 linux_dirent.d_ino = (l_long)bdp->d_ino;
379 linux_dirent.d_off = (l_off_t)linuxreclen;
380 linux_dirent.d_reclen = (l_ushort)bdp->d_namlen;
381 strcpy(linux_dirent.d_name, bdp->d_name);
382 error = copyout(&linux_dirent, outp, linuxreclen);
385 linux_dirent64.d_ino = bdp->d_ino;
386 linux_dirent64.d_off = (cookiep)
388 : (l_off_t)(off + reclen);
389 linux_dirent64.d_reclen =
390 (l_ushort)linuxreclen;
391 linux_dirent64.d_type = bdp->d_type;
392 strcpy(linux_dirent64.d_name, bdp->d_name);
393 error = copyout(&linux_dirent64, outp,
396 linux_dirent.d_ino = bdp->d_ino;
397 linux_dirent.d_off = (cookiep)
399 : (l_off_t)(off + reclen);
400 linux_dirent.d_reclen = (l_ushort)linuxreclen;
401 strcpy(linux_dirent.d_name, bdp->d_name);
402 error = copyout(&linux_dirent, outp,
417 resid -= linuxreclen;
423 if (outp == (caddr_t)args->dirent && eofflag == 0)
428 nbytes = resid + linuxreclen;
431 args->sysmsg_result = nbytes - resid;
435 kfree(cookies, M_TEMP);
444 sys_linux_getdents(struct linux_getdents_args *args)
447 if (ldebug(getdents))
448 printf(ARGS(getdents, "%d, *, %d"), args->fd, args->count);
450 return (getdents_common((struct linux_getdents64_args*)args, 0));
454 sys_linux_getdents64(struct linux_getdents64_args *args)
457 if (ldebug(getdents64))
458 printf(ARGS(getdents64, "%d, *, %d"), args->fd, args->count);
460 return (getdents_common(args, 1));
464 * These exist mainly for hooks for doing /compat/linux translation.
468 sys_linux_access(struct linux_access_args *args)
470 struct nlookupdata nd;
474 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
479 printf(ARGS(access, "%s, %d"), path, args->flags);
481 error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW);
483 error = kern_access(&nd, args->flags);
485 linux_free_path(&path);
490 sys_linux_unlink(struct linux_unlink_args *args)
492 struct nlookupdata nd;
496 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
501 printf(ARGS(unlink, "%s"), path);
503 error = nlookup_init(&nd, path, UIO_SYSSPACE, 0);
505 error = kern_unlink(&nd);
507 linux_free_path(&path);
512 sys_linux_chdir(struct linux_chdir_args *args)
514 struct nlookupdata nd;
518 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
523 printf(ARGS(chdir, "%s"), path);
525 error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW);
527 error = kern_chdir(&nd);
530 linux_free_path(&path);
535 sys_linux_chmod(struct linux_chmod_args *args)
537 struct nlookupdata nd;
541 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
546 printf(ARGS(chmod, "%s, %d"), path, args->mode);
548 error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW);
550 error = kern_chmod(&nd, args->mode);
552 linux_free_path(&path);
557 sys_linux_mkdir(struct linux_mkdir_args *args)
559 struct nlookupdata nd;
563 error = linux_copyin_path(args->path, &path, LINUX_PATH_CREATE);
568 printf(ARGS(mkdir, "%s, %d"), path, args->mode);
570 error = nlookup_init(&nd, path, UIO_SYSSPACE, 0);
572 error = kern_mkdir(&nd, args->mode);
575 linux_free_path(&path);
580 sys_linux_rmdir(struct linux_rmdir_args *args)
582 struct nlookupdata nd;
586 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
591 printf(ARGS(rmdir, "%s"), path);
593 error = nlookup_init(&nd, path, UIO_SYSSPACE, 0);
595 error = kern_rmdir(&nd);
597 linux_free_path(&path);
602 sys_linux_rename(struct linux_rename_args *args)
604 struct nlookupdata fromnd, tond;
608 error = linux_copyin_path(args->from, &from, LINUX_PATH_EXISTS);
611 error = linux_copyin_path(args->to, &to, LINUX_PATH_CREATE);
613 linux_free_path(&from);
618 printf(ARGS(rename, "%s, %s"), from, to);
620 error = nlookup_init(&fromnd, from, UIO_SYSSPACE, 0);
622 error = nlookup_init(&tond, to, UIO_SYSSPACE, 0);
624 error = kern_rename(&fromnd, &tond);
627 nlookup_done(&fromnd);
628 linux_free_path(&from);
629 linux_free_path(&to);
634 sys_linux_symlink(struct linux_symlink_args *args)
636 struct thread *td = curthread;
637 struct nlookupdata nd;
642 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
645 error = linux_copyin_path(args->to, &link, LINUX_PATH_CREATE);
647 linux_free_path(&path);
652 printf(ARGS(symlink, "%s, %s"), path, link);
654 error = nlookup_init(&nd, link, UIO_SYSSPACE, 0);
656 mode = ACCESSPERMS & ~td->td_proc->p_fd->fd_cmask;
657 error = kern_symlink(&nd, path, mode);
660 linux_free_path(&path);
661 linux_free_path(&link);
666 sys_linux_readlink(struct linux_readlink_args *args)
668 struct nlookupdata nd;
672 error = linux_copyin_path(args->name, &path, LINUX_PATH_EXISTS);
676 if (ldebug(readlink))
677 printf(ARGS(readlink, "%s, %p, %d"), path, (void *)args->buf,
680 error = nlookup_init(&nd, path, UIO_SYSSPACE, 0);
682 error = kern_readlink(&nd, args->buf, args->count,
683 &args->sysmsg_result);
686 linux_free_path(&path);
691 sys_linux_truncate(struct linux_truncate_args *args)
693 struct nlookupdata nd;
697 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
701 if (ldebug(truncate))
702 printf(ARGS(truncate, "%s, %ld"), path,
705 error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW);
707 error = kern_truncate(&nd, args->length);
709 linux_free_path(&path);
714 sys_linux_truncate64(struct linux_truncate64_args *args)
716 struct nlookupdata nd;
720 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
724 if (ldebug(truncate64))
725 printf(ARGS(truncate64, "%s, %lld"), path,
726 (off_t)args->length);
728 error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW);
730 error = kern_truncate(&nd, args->length);
732 linux_free_path(&path);
737 sys_linux_ftruncate(struct linux_ftruncate_args *args)
742 if (ldebug(ftruncate))
743 printf(ARGS(ftruncate, "%d, %ld"), args->fd,
746 error = kern_ftruncate(args->fd, args->length);
752 sys_linux_ftruncate64(struct linux_ftruncate64_args *args)
757 if (ldebug(ftruncate))
758 printf(ARGS(ftruncate64, "%d, %lld"), args->fd,
759 (off_t)args->length);
761 error = kern_ftruncate(args->fd, args->length);
767 sys_linux_link(struct linux_link_args *args)
769 struct nlookupdata nd, linknd;
773 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
776 error = linux_copyin_path(args->to, &link, LINUX_PATH_CREATE);
778 linux_free_path(&path);
783 printf(ARGS(link, "%s, %s"), path, link);
785 error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW);
787 error = nlookup_init(&linknd, link, UIO_SYSSPACE, 0);
789 error = kern_link(&nd, &linknd);
790 nlookup_done(&linknd);
793 linux_free_path(&path);
794 linux_free_path(&link);
799 sys_linux_fdatasync(struct linux_fdatasync_args *uap)
801 struct fsync_args bsd;
805 bsd.sysmsg_result = 0;
807 error = sys_fsync(&bsd);
808 uap->sysmsg_result = bsd.sysmsg_result;
813 sys_linux_pread(struct linux_pread_args *uap)
815 struct thread *td = curthread;
820 aiov.iov_base = uap->buf;
821 aiov.iov_len = uap->nbyte;
822 auio.uio_iov = &aiov;
824 auio.uio_offset = uap->offset;
825 auio.uio_resid = uap->nbyte;
826 auio.uio_rw = UIO_READ;
827 auio.uio_segflg = UIO_USERSPACE;
830 if (auio.uio_resid < 0)
833 error = kern_preadv(uap->fd, &auio, O_FOFFSET, &uap->sysmsg_result);
838 sys_linux_pwrite(struct linux_pwrite_args *uap)
840 struct thread *td = curthread;
845 aiov.iov_base = uap->buf;
846 aiov.iov_len = uap->nbyte;
847 auio.uio_iov = &aiov;
849 auio.uio_offset = uap->offset;
850 auio.uio_resid = uap->nbyte;
851 auio.uio_rw = UIO_WRITE;
852 auio.uio_segflg = UIO_USERSPACE;
855 if (auio.uio_resid < 0)
858 error = kern_pwritev(uap->fd, &auio, O_FOFFSET, &uap->sysmsg_result);
864 sys_linux_oldumount(struct linux_oldumount_args *args)
866 struct linux_umount_args args2;
869 args2.path = args->path;
871 args2.sysmsg_result = 0;
872 error = sys_linux_umount(&args2);
873 args->sysmsg_result = args2.sysmsg_result;
878 sys_linux_umount(struct linux_umount_args *args)
880 struct unmount_args bsd;
883 bsd.path = args->path;
884 bsd.flags = args->flags; /* XXX correct? */
885 bsd.sysmsg_result = 0;
887 error = sys_unmount(&bsd);
888 args->sysmsg_result = bsd.sysmsg_result;
893 * fcntl family of syscalls
905 linux_to_bsd_flock(struct l_flock *linux_flock, struct flock *bsd_flock)
907 switch (linux_flock->l_type) {
909 bsd_flock->l_type = F_RDLCK;
912 bsd_flock->l_type = F_WRLCK;
915 bsd_flock->l_type = F_UNLCK;
918 bsd_flock->l_type = -1;
921 bsd_flock->l_whence = linux_flock->l_whence;
922 bsd_flock->l_start = (off_t)linux_flock->l_start;
923 bsd_flock->l_len = (off_t)linux_flock->l_len;
924 bsd_flock->l_pid = (pid_t)linux_flock->l_pid;
928 bsd_to_linux_flock(struct flock *bsd_flock, struct l_flock *linux_flock)
930 switch (bsd_flock->l_type) {
932 linux_flock->l_type = LINUX_F_RDLCK;
935 linux_flock->l_type = LINUX_F_WRLCK;
938 linux_flock->l_type = LINUX_F_UNLCK;
941 linux_flock->l_whence = bsd_flock->l_whence;
942 linux_flock->l_start = (l_off_t)bsd_flock->l_start;
943 linux_flock->l_len = (l_off_t)bsd_flock->l_len;
944 linux_flock->l_pid = (l_pid_t)bsd_flock->l_pid;
947 #if defined(__i386__)
957 linux_to_bsd_flock64(struct l_flock64 *linux_flock, struct flock *bsd_flock)
959 switch (linux_flock->l_type) {
961 bsd_flock->l_type = F_RDLCK;
964 bsd_flock->l_type = F_WRLCK;
967 bsd_flock->l_type = F_UNLCK;
970 bsd_flock->l_type = -1;
973 bsd_flock->l_whence = linux_flock->l_whence;
974 bsd_flock->l_start = (off_t)linux_flock->l_start;
975 bsd_flock->l_len = (off_t)linux_flock->l_len;
976 bsd_flock->l_pid = (pid_t)linux_flock->l_pid;
980 bsd_to_linux_flock64(struct flock *bsd_flock, struct l_flock64 *linux_flock)
982 switch (bsd_flock->l_type) {
984 linux_flock->l_type = LINUX_F_RDLCK;
987 linux_flock->l_type = LINUX_F_WRLCK;
990 linux_flock->l_type = LINUX_F_UNLCK;
993 linux_flock->l_whence = bsd_flock->l_whence;
994 linux_flock->l_start = (l_loff_t)bsd_flock->l_start;
995 linux_flock->l_len = (l_loff_t)bsd_flock->l_len;
996 linux_flock->l_pid = (l_pid_t)bsd_flock->l_pid;
998 #endif /* __i386__ */
1001 linux_fcntl_common(struct linux_fcntl64_args *args)
1003 struct proc *p = curproc;
1004 struct l_flock linux_flock;
1006 union fcntl_dat dat;
1009 switch (args->cmd) {
1012 dat.fc_fd = args->arg;
1019 dat.fc_cloexec = args->arg;
1027 if (args->arg & LINUX_O_NDELAY)
1028 dat.fc_flags |= O_NONBLOCK;
1029 if (args->arg & LINUX_O_APPEND)
1030 dat.fc_flags |= O_APPEND;
1031 if (args->arg & LINUX_O_SYNC)
1032 dat.fc_flags |= O_FSYNC;
1033 if (args->arg & LINUX_FASYNC)
1034 dat.fc_flags |= O_ASYNC;
1038 case LINUX_F_SETLKW:
1040 error = copyin((caddr_t)args->arg, &linux_flock,
1041 sizeof(linux_flock));
1044 linux_to_bsd_flock(&linux_flock, &dat.fc_flock);
1046 case LINUX_F_GETOWN:
1049 case LINUX_F_SETOWN:
1051 * XXX some Linux applications depend on F_SETOWN having no
1052 * significant effect for pipes (SIGIO is not delivered for
1053 * pipes under Linux-2.2.35 at least).
1055 fp = holdfp(p->p_fd, args->fd, -1);
1058 if (fp->f_type == DTYPE_PIPE) {
1064 dat.fc_owner = args->arg;
1070 error = kern_fcntl(args->fd, cmd, &dat, p->p_ucred);
1073 switch (args->cmd) {
1075 args->sysmsg_result = dat.fc_fd;
1078 args->sysmsg_result = dat.fc_cloexec;
1083 args->sysmsg_result = 0;
1084 if (dat.fc_flags & O_RDONLY)
1085 args->sysmsg_result |= LINUX_O_RDONLY;
1086 if (dat.fc_flags & O_WRONLY)
1087 args->sysmsg_result |= LINUX_O_WRONLY;
1088 if (dat.fc_flags & O_RDWR)
1089 args->sysmsg_result |= LINUX_O_RDWR;
1090 if (dat.fc_flags & O_NDELAY)
1091 args->sysmsg_result |= LINUX_O_NONBLOCK;
1092 if (dat.fc_flags & O_APPEND)
1093 args->sysmsg_result |= LINUX_O_APPEND;
1094 if (dat.fc_flags & O_FSYNC)
1095 args->sysmsg_result |= LINUX_O_SYNC;
1096 if (dat.fc_flags & O_ASYNC)
1097 args->sysmsg_result |= LINUX_FASYNC;
1100 bsd_to_linux_flock(&dat.fc_flock, &linux_flock);
1101 error = copyout(&linux_flock, (caddr_t)args->arg,
1102 sizeof(linux_flock));
1105 case LINUX_F_SETLKW:
1107 case LINUX_F_GETOWN:
1108 args->sysmsg_result = dat.fc_owner;
1110 case LINUX_F_SETOWN:
1119 sys_linux_fcntl(struct linux_fcntl_args *args)
1121 struct linux_fcntl64_args args64;
1126 printf(ARGS(fcntl, "%d, %08x, *"), args->fd, args->cmd);
1129 args64.fd = args->fd;
1130 args64.cmd = args->cmd;
1131 args64.arg = args->arg;
1132 args64.sysmsg_result = 0;
1133 error = linux_fcntl_common(&args64);
1134 args->sysmsg_result = args64.sysmsg_result;
1138 #if defined(__i386__)
1140 sys_linux_fcntl64(struct linux_fcntl64_args *args)
1142 struct l_flock64 linux_flock;
1143 union fcntl_dat dat;
1147 if (ldebug(fcntl64))
1148 printf(ARGS(fcntl64, "%d, %08x, *"), args->fd, args->cmd);
1150 if (args->cmd == LINUX_F_GETLK64 || args->cmd == LINUX_F_SETLK64 ||
1151 args->cmd == LINUX_F_SETLKW64) {
1152 switch (args->cmd) {
1153 case LINUX_F_GETLK64:
1156 case LINUX_F_SETLK64:
1159 case LINUX_F_SETLKW64:
1164 error = copyin((caddr_t)args->arg, &linux_flock,
1165 sizeof(linux_flock));
1168 linux_to_bsd_flock64(&linux_flock, &dat.fc_flock);
1170 error = kern_fcntl(args->fd, cmd, &dat, curproc->p_ucred);
1172 if (error == 0 && args->cmd == LINUX_F_GETLK64) {
1173 bsd_to_linux_flock64(&dat.fc_flock, &linux_flock);
1174 error = copyout(&linux_flock, (caddr_t)args->arg,
1175 sizeof(linux_flock));
1178 error = linux_fcntl_common(args);
1183 #endif /* __i386__ */
1186 sys_linux_chown(struct linux_chown_args *args)
1188 struct nlookupdata nd;
1192 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
1197 printf(ARGS(chown, "%s, %d, %d"), path, args->uid, args->gid);
1199 error = nlookup_init(&nd, path, UIO_SYSSPACE, NLC_FOLLOW);
1201 error = kern_chown(&nd, args->uid, args->gid);
1203 linux_free_path(&path);
1208 sys_linux_lchown(struct linux_lchown_args *args)
1210 struct nlookupdata nd;
1214 error = linux_copyin_path(args->path, &path, LINUX_PATH_EXISTS);
1219 printf(ARGS(lchown, "%s, %d, %d"), path, args->uid, args->gid);
1221 error = nlookup_init(&nd, path, UIO_SYSSPACE, 0);
1223 error = kern_chown(&nd, args->uid, args->gid);
1225 linux_free_path(&path);