Deleted Added
full compact
linux_file.c (177633) linux_file.c (177997)
1/*-
2 * Copyright (c) 1994-1995 S�ren Schmidt
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 13 unchanged lines hidden (view full) ---

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.
27 */
28
29#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 1994-1995 S�ren Schmidt
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 13 unchanged lines hidden (view full) ---

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.
27 */
28
29#include <sys/cdefs.h>
30__FBSDID("$FreeBSD: head/sys/compat/linux/linux_file.c 177633 2008-03-26 15:23:12Z dfr $");
30__FBSDID("$FreeBSD: head/sys/compat/linux/linux_file.c 177997 2008-04-08 09:45:49Z kib $");
31
32#include "opt_compat.h"
33#include "opt_mac.h"
34
35#include <sys/param.h>
36#include <sys/systm.h>
37#include <sys/conf.h>
38#include <sys/dirent.h>

--- 23 unchanged lines hidden (view full) ---

62#ifdef COMPAT_LINUX32
63#include <machine/../linux32/linux.h>
64#include <machine/../linux32/linux32_proto.h>
65#else
66#include <machine/../linux/linux.h>
67#include <machine/../linux/linux_proto.h>
68#endif
69#include <compat/linux/linux_util.h>
31
32#include "opt_compat.h"
33#include "opt_mac.h"
34
35#include <sys/param.h>
36#include <sys/systm.h>
37#include <sys/conf.h>
38#include <sys/dirent.h>

--- 23 unchanged lines hidden (view full) ---

62#ifdef COMPAT_LINUX32
63#include <machine/../linux32/linux.h>
64#include <machine/../linux32/linux32_proto.h>
65#else
66#include <machine/../linux/linux.h>
67#include <machine/../linux/linux_proto.h>
68#endif
69#include <compat/linux/linux_util.h>
70#include <compat/linux/linux_file.h>
70
71int
72linux_creat(struct thread *td, struct linux_creat_args *args)
73{
74 char *path;
75 int error;
76
77 LCONVPATHEXIST(td, args->path, &path);

--- 5 unchanged lines hidden (view full) ---

83 error = kern_open(td, path, UIO_SYSSPACE, O_WRONLY | O_CREAT | O_TRUNC,
84 args->mode);
85 LFREEPATH(path);
86 return (error);
87}
88
89
90static int
71
72int
73linux_creat(struct thread *td, struct linux_creat_args *args)
74{
75 char *path;
76 int error;
77
78 LCONVPATHEXIST(td, args->path, &path);

--- 5 unchanged lines hidden (view full) ---

84 error = kern_open(td, path, UIO_SYSSPACE, O_WRONLY | O_CREAT | O_TRUNC,
85 args->mode);
86 LFREEPATH(path);
87 return (error);
88}
89
90
91static int
91linux_common_open(struct thread *td, char *path, int l_flags, int mode, int openat)
92linux_common_open(struct thread *td, int dirfd, char *path, int l_flags, int mode)
92{
93 struct proc *p = td->td_proc;
94 struct file *fp;
95 int fd;
96 int bsd_flags, error;
97
98 bsd_flags = 0;
99 switch (l_flags & LINUX_O_ACCMODE) {

--- 25 unchanged lines hidden (view full) ---

125 if (l_flags & LINUX_O_NOCTTY)
126 bsd_flags |= O_NOCTTY;
127 if (l_flags & LINUX_O_DIRECT)
128 bsd_flags |= O_DIRECT;
129 if (l_flags & LINUX_O_NOFOLLOW)
130 bsd_flags |= O_NOFOLLOW;
131 /* XXX LINUX_O_NOATIME: unable to be easily implemented. */
132
93{
94 struct proc *p = td->td_proc;
95 struct file *fp;
96 int fd;
97 int bsd_flags, error;
98
99 bsd_flags = 0;
100 switch (l_flags & LINUX_O_ACCMODE) {

--- 25 unchanged lines hidden (view full) ---

126 if (l_flags & LINUX_O_NOCTTY)
127 bsd_flags |= O_NOCTTY;
128 if (l_flags & LINUX_O_DIRECT)
129 bsd_flags |= O_DIRECT;
130 if (l_flags & LINUX_O_NOFOLLOW)
131 bsd_flags |= O_NOFOLLOW;
132 /* XXX LINUX_O_NOATIME: unable to be easily implemented. */
133
133 error = kern_open(td, path, UIO_SYSSPACE, bsd_flags, mode);
134 if (dirfd != -1)
135 error = kern_openat(td, dirfd, path, UIO_SYSSPACE, bsd_flags, mode);
136 else
137 error = kern_open(td, path, UIO_SYSSPACE, bsd_flags, mode);
134 if (!error) {
135 fd = td->td_retval[0];
136 /*
137 * XXX In between kern_open() and fget(), another process
138 * having the same filedesc could use that fd without
139 * checking below.
140 */
141 error = fget(td, fd, &fp);

--- 25 unchanged lines hidden (view full) ---

167 kern_close(td, fd);
168 }
169 }
170
171#ifdef DEBUG
172 if (ldebug(open))
173 printf(LMSG("open returns error %d"), error);
174#endif
138 if (!error) {
139 fd = td->td_retval[0];
140 /*
141 * XXX In between kern_open() and fget(), another process
142 * having the same filedesc could use that fd without
143 * checking below.
144 */
145 error = fget(td, fd, &fp);

--- 25 unchanged lines hidden (view full) ---

171 kern_close(td, fd);
172 }
173 }
174
175#ifdef DEBUG
176 if (ldebug(open))
177 printf(LMSG("open returns error %d"), error);
178#endif
175 if (!openat)
176 LFREEPATH(path);
177 return error;
179 LFREEPATH(path);
180 return (error);
178}
179
181}
182
180/*
181 * common code for linux *at set of syscalls
182 *
183 * works like this:
184 * if filename is absolute
185 * ignore dirfd
186 * else
187 * if dirfd == AT_FDCWD
188 * return CWD/filename
189 * else
190 * return DIRFD/filename
191 */
192static int
193linux_at(struct thread *td, int dirfd, char *filename, char **newpath, char **freebuf)
194{
195 struct file *fp;
196 int error = 0, vfslocked;
197 struct vnode *dvp;
198 struct filedesc *fdp = td->td_proc->p_fd;
199 char *fullpath = "unknown";
200 char *freepath = NULL;
201
202 /* don't do anything if the pathname is absolute */
203 if (*filename == '/') {
204 *newpath= filename;
205 return (0);
206 }
207
208 /* check for AT_FDWCD */
209 if (dirfd == LINUX_AT_FDCWD) {
210 FILEDESC_SLOCK(fdp);
211 dvp = fdp->fd_cdir;
212 vref(dvp);
213 FILEDESC_SUNLOCK(fdp);
214 } else {
215 error = fget(td, dirfd, &fp);
216 if (error)
217 return (error);
218 dvp = fp->f_vnode;
219 /* only a dir can be dfd */
220 if (dvp->v_type != VDIR) {
221 fdrop(fp, td);
222 return (ENOTDIR);
223 }
224 vref(dvp);
225 fdrop(fp, td);
226 }
227
228 /*
229 * XXXRW: This is bogus, as vn_fullpath() returns only an advisory
230 * file path, and may fail in several common situations, including
231 * for file systmes that don't use the name cache, and if the entry
232 * for the file falls out of the name cache. We should implement
233 * openat() in the FreeBSD native system call layer properly (using a
234 * requested starting directory), and have Linux and other ABIs wrap
235 * the native implementation.
236 */
237 error = vn_fullpath(td, dvp, &fullpath, &freepath);
238 if (!error) {
239 *newpath = malloc(strlen(fullpath) + strlen(filename) + 2, M_TEMP, M_WAITOK | M_ZERO);
240 *freebuf = freepath;
241 sprintf(*newpath, "%s/%s", fullpath, filename);
242 } else {
243 *newpath = NULL;
244 }
245 vfslocked = VFS_LOCK_GIANT(dvp->v_mount);
246 vrele(dvp);
247 VFS_UNLOCK_GIANT(vfslocked);
248 return (error);
249}
250
251int
252linux_openat(struct thread *td, struct linux_openat_args *args)
253{
183int
184linux_openat(struct thread *td, struct linux_openat_args *args)
185{
254 char *newpath, *oldpath, *freebuf, *path;
255 int error;
186 char *path;
187 int dfd;
256
188
257 oldpath = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
258 error = copyinstr(args->filename, oldpath, MAXPATHLEN, NULL);
259 if (error) {
260 free(oldpath, M_TEMP);
261 return (error);
262 }
189 dfd = (args->dfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->dfd;
190 if (args->flags & LINUX_O_CREAT)
191 LCONVPATH_AT(td, args->filename, &path, 1, dfd);
192 else
193 LCONVPATH_AT(td, args->filename, &path, 0, dfd);
263#ifdef DEBUG
264 if (ldebug(openat))
265 printf(ARGS(openat, "%i, %s, 0x%x, 0x%x"), args->dfd,
194#ifdef DEBUG
195 if (ldebug(openat))
196 printf(ARGS(openat, "%i, %s, 0x%x, 0x%x"), args->dfd,
266 oldpath, args->flags, args->mode);
197 path, args->flags, args->mode);
267#endif
198#endif
268 newpath = freebuf = NULL;
269 error = linux_at(td, args->dfd, oldpath, &newpath, &freebuf);
270 if (error == 0) {
271#ifdef DEBUG
272 if (ldebug(openat))
273 printf(LMSG("newpath: %s"), newpath);
274#endif
275 if (args->flags & LINUX_O_CREAT)
276 LCONVPATH_SEG(td, newpath, &path, 1, UIO_SYSSPACE);
277 else
278 LCONVPATH_SEG(td, newpath, &path, 0, UIO_SYSSPACE);
279 }
280 if (freebuf)
281 free(freebuf, M_TEMP);
282 if (*oldpath != '/')
283 free(newpath, M_TEMP);
284 if (error == 0) {
285 error = linux_common_open(td, path, args->flags,
286 args->mode, 1);
287 LFREEPATH(path);
288 }
289 free(oldpath, M_TEMP);
290 return (error);
199 return (linux_common_open(td, dfd, path, args->flags, args->mode));
291}
292
293int
294linux_open(struct thread *td, struct linux_open_args *args)
295{
296 char *path;
297
298 if (args->flags & LINUX_O_CREAT)
299 LCONVPATHCREAT(td, args->path, &path);
300 else
301 LCONVPATHEXIST(td, args->path, &path);
302
303#ifdef DEBUG
304 if (ldebug(open))
305 printf(ARGS(open, "%s, 0x%x, 0x%x"),
306 path, args->flags, args->mode);
307#endif
308
200}
201
202int
203linux_open(struct thread *td, struct linux_open_args *args)
204{
205 char *path;
206
207 if (args->flags & LINUX_O_CREAT)
208 LCONVPATHCREAT(td, args->path, &path);
209 else
210 LCONVPATHEXIST(td, args->path, &path);
211
212#ifdef DEBUG
213 if (ldebug(open))
214 printf(ARGS(open, "%s, 0x%x, 0x%x"),
215 path, args->flags, args->mode);
216#endif
217
309 return linux_common_open(td, path, args->flags, args->mode, 0);
218 return (linux_common_open(td, -1, path, args->flags, args->mode));
310}
311
312int
313linux_lseek(struct thread *td, struct linux_lseek_args *args)
314{
315
316 struct lseek_args /* {
317 int fd;

--- 333 unchanged lines hidden (view full) ---

651#endif
652 error = kern_access(td, path, UIO_SYSSPACE, args->flags);
653 LFREEPATH(path);
654
655 return (error);
656}
657
658int
219}
220
221int
222linux_lseek(struct thread *td, struct linux_lseek_args *args)
223{
224
225 struct lseek_args /* {
226 int fd;

--- 333 unchanged lines hidden (view full) ---

560#endif
561 error = kern_access(td, path, UIO_SYSSPACE, args->flags);
562 LFREEPATH(path);
563
564 return (error);
565}
566
567int
568linux_faccessat(struct thread *td, struct linux_faccessat_args *args)
569{
570 char *path;
571 int error, dfd;
572
573 /* linux convention */
574 if (args->mode & ~(F_OK | X_OK | W_OK | R_OK))
575 return (EINVAL);
576
577 dfd = (args->dfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->dfd;
578 LCONVPATHEXIST_AT(td, args->filename, &path, dfd);
579
580#ifdef DEBUG
581 if (ldebug(access))
582 printf(ARGS(access, "%s, %d"), path, args->mode);
583#endif
584
585 error = kern_accessat(td, dfd, path, UIO_SYSSPACE, 0 /* XXX */,
586 args->mode);
587 LFREEPATH(path);
588
589 return (error);
590}
591
592int
659linux_unlink(struct thread *td, struct linux_unlink_args *args)
660{
661 char *path;
662 int error;
663 struct stat st;
664
665 LCONVPATHEXIST(td, args->path, &path);
666

--- 8 unchanged lines hidden (view full) ---

675 if (kern_stat(td, path, UIO_SYSSPACE, &st) == 0)
676 if (S_ISDIR(st.st_mode))
677 error = EISDIR;
678 LFREEPATH(path);
679 return (error);
680}
681
682int
593linux_unlink(struct thread *td, struct linux_unlink_args *args)
594{
595 char *path;
596 int error;
597 struct stat st;
598
599 LCONVPATHEXIST(td, args->path, &path);
600

--- 8 unchanged lines hidden (view full) ---

609 if (kern_stat(td, path, UIO_SYSSPACE, &st) == 0)
610 if (S_ISDIR(st.st_mode))
611 error = EISDIR;
612 LFREEPATH(path);
613 return (error);
614}
615
616int
617linux_unlinkat(struct thread *td, struct linux_unlinkat_args *args)
618{
619 char *path;
620 int error, dfd;
621 struct stat st;
622
623 if (args->flag & ~LINUX_AT_REMOVEDIR)
624 return (EINVAL);
625
626 dfd = (args->dfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->dfd;
627 LCONVPATHEXIST_AT(td, args->pathname, &path, dfd);
628
629#ifdef DEBUG
630 if (ldebug(unlinkat))
631 printf(ARGS(unlinkat, "%s"), path);
632#endif
633
634 if (args->flag & LINUX_AT_REMOVEDIR)
635 error = kern_rmdirat(td, dfd, path, UIO_SYSSPACE);
636 else
637 error = kern_unlinkat(td, dfd, path, UIO_SYSSPACE);
638 if (error == EPERM && !(args->flag & LINUX_AT_REMOVEDIR)) {
639 /* Introduce POSIX noncompliant behaviour of Linux */
640 if (kern_statat(td, AT_SYMLINK_NOFOLLOW, dfd, path,
641 UIO_SYSSPACE, &st) == 0 && S_ISDIR(st.st_mode))
642 error = EISDIR;
643 }
644 LFREEPATH(path);
645 return (error);
646}
647int
683linux_chdir(struct thread *td, struct linux_chdir_args *args)
684{
685 char *path;
686 int error;
687
688 LCONVPATHEXIST(td, args->path, &path);
689
690#ifdef DEBUG

--- 18 unchanged lines hidden (view full) ---

709 printf(ARGS(chmod, "%s, %d"), path, args->mode);
710#endif
711 error = kern_chmod(td, path, UIO_SYSSPACE, args->mode);
712 LFREEPATH(path);
713 return (error);
714}
715
716int
648linux_chdir(struct thread *td, struct linux_chdir_args *args)
649{
650 char *path;
651 int error;
652
653 LCONVPATHEXIST(td, args->path, &path);
654
655#ifdef DEBUG

--- 18 unchanged lines hidden (view full) ---

674 printf(ARGS(chmod, "%s, %d"), path, args->mode);
675#endif
676 error = kern_chmod(td, path, UIO_SYSSPACE, args->mode);
677 LFREEPATH(path);
678 return (error);
679}
680
681int
682linux_fchmodat(struct thread *td, struct linux_fchmodat_args *args)
683{
684 char *path;
685 int error, dfd;
686
687 dfd = (args->dfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->dfd;
688 LCONVPATHEXIST_AT(td, args->filename, &path, dfd);
689
690#ifdef DEBUG
691 if (ldebug(fchmodat))
692 printf(ARGS(fchmodat, "%s, %d"), path, args->mode);
693#endif
694
695 error = kern_fchmodat(td, dfd, path, UIO_SYSSPACE, args->mode, 0);
696 LFREEPATH(path);
697 return (error);
698}
699
700int
717linux_mkdir(struct thread *td, struct linux_mkdir_args *args)
718{
719 char *path;
720 int error;
721
722 LCONVPATHCREAT(td, args->path, &path);
723
724#ifdef DEBUG
725 if (ldebug(mkdir))
726 printf(ARGS(mkdir, "%s, %d"), path, args->mode);
727#endif
728 error = kern_mkdir(td, path, UIO_SYSSPACE, args->mode);
729 LFREEPATH(path);
730 return (error);
731}
732
733int
701linux_mkdir(struct thread *td, struct linux_mkdir_args *args)
702{
703 char *path;
704 int error;
705
706 LCONVPATHCREAT(td, args->path, &path);
707
708#ifdef DEBUG
709 if (ldebug(mkdir))
710 printf(ARGS(mkdir, "%s, %d"), path, args->mode);
711#endif
712 error = kern_mkdir(td, path, UIO_SYSSPACE, args->mode);
713 LFREEPATH(path);
714 return (error);
715}
716
717int
718linux_mkdirat(struct thread *td, struct linux_mkdirat_args *args)
719{
720 char *path;
721 int error, dfd;
722
723 dfd = (args->dfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->dfd;
724 LCONVPATHCREAT_AT(td, args->pathname, &path, dfd);
725
726#ifdef DEBUG
727 if (ldebug(mkdirat))
728 printf(ARGS(mkdirat, "%s, %d"), path, args->mode);
729#endif
730 error = kern_mkdirat(td, dfd, path, UIO_SYSSPACE, args->mode);
731 LFREEPATH(path);
732 return (error);
733}
734
735int
734linux_rmdir(struct thread *td, struct linux_rmdir_args *args)
735{
736 char *path;
737 int error;
738
739 LCONVPATHEXIST(td, args->path, &path);
740
741#ifdef DEBUG

--- 8 unchanged lines hidden (view full) ---

750int
751linux_rename(struct thread *td, struct linux_rename_args *args)
752{
753 char *from, *to;
754 int error;
755
756 LCONVPATHEXIST(td, args->from, &from);
757 /* Expand LCONVPATHCREATE so that `from' can be freed on errors */
736linux_rmdir(struct thread *td, struct linux_rmdir_args *args)
737{
738 char *path;
739 int error;
740
741 LCONVPATHEXIST(td, args->path, &path);
742
743#ifdef DEBUG

--- 8 unchanged lines hidden (view full) ---

752int
753linux_rename(struct thread *td, struct linux_rename_args *args)
754{
755 char *from, *to;
756 int error;
757
758 LCONVPATHEXIST(td, args->from, &from);
759 /* Expand LCONVPATHCREATE so that `from' can be freed on errors */
758 error = linux_emul_convpath(td, args->to, UIO_USERSPACE, &to, 1);
760 error = linux_emul_convpath(td, args->to, UIO_USERSPACE, &to, 1, AT_FDCWD);
759 if (to == NULL) {
760 LFREEPATH(from);
761 return (error);
762 }
763
764#ifdef DEBUG
765 if (ldebug(rename))
766 printf(ARGS(rename, "%s, %s"), from, to);
767#endif
768 error = kern_rename(td, from, to, UIO_SYSSPACE);
769 LFREEPATH(from);
770 LFREEPATH(to);
771 return (error);
772}
773
774int
761 if (to == NULL) {
762 LFREEPATH(from);
763 return (error);
764 }
765
766#ifdef DEBUG
767 if (ldebug(rename))
768 printf(ARGS(rename, "%s, %s"), from, to);
769#endif
770 error = kern_rename(td, from, to, UIO_SYSSPACE);
771 LFREEPATH(from);
772 LFREEPATH(to);
773 return (error);
774}
775
776int
777linux_renameat(struct thread *td, struct linux_renameat_args *args)
778{
779 char *from, *to;
780 int error, olddfd, newdfd;
781
782 olddfd = (args->olddfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->olddfd;
783 newdfd = (args->newdfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->newdfd;
784 LCONVPATHEXIST_AT(td, args->oldname, &from, olddfd);
785 /* Expand LCONVPATHCREATE so that `from' can be freed on errors */
786 error = linux_emul_convpath(td, args->newname, UIO_USERSPACE, &to, 1, newdfd);
787 if (to == NULL) {
788 LFREEPATH(from);
789 return (error);
790 }
791
792#ifdef DEBUG
793 if (ldebug(renameat))
794 printf(ARGS(renameat, "%s, %s"), from, to);
795#endif
796 error = kern_renameat(td, olddfd, from, newdfd, to, UIO_SYSSPACE);
797 LFREEPATH(from);
798 LFREEPATH(to);
799 return (error);
800}
801
802int
775linux_symlink(struct thread *td, struct linux_symlink_args *args)
776{
777 char *path, *to;
778 int error;
779
780 LCONVPATHEXIST(td, args->path, &path);
781 /* Expand LCONVPATHCREATE so that `path' can be freed on errors */
803linux_symlink(struct thread *td, struct linux_symlink_args *args)
804{
805 char *path, *to;
806 int error;
807
808 LCONVPATHEXIST(td, args->path, &path);
809 /* Expand LCONVPATHCREATE so that `path' can be freed on errors */
782 error = linux_emul_convpath(td, args->to, UIO_USERSPACE, &to, 1);
810 error = linux_emul_convpath(td, args->to, UIO_USERSPACE, &to, 1, AT_FDCWD);
783 if (to == NULL) {
784 LFREEPATH(path);
785 return (error);
786 }
787
788#ifdef DEBUG
789 if (ldebug(symlink))
790 printf(ARGS(symlink, "%s, %s"), path, to);
791#endif
792 error = kern_symlink(td, path, to, UIO_SYSSPACE);
793 LFREEPATH(path);
794 LFREEPATH(to);
795 return (error);
796}
797
798int
811 if (to == NULL) {
812 LFREEPATH(path);
813 return (error);
814 }
815
816#ifdef DEBUG
817 if (ldebug(symlink))
818 printf(ARGS(symlink, "%s, %s"), path, to);
819#endif
820 error = kern_symlink(td, path, to, UIO_SYSSPACE);
821 LFREEPATH(path);
822 LFREEPATH(to);
823 return (error);
824}
825
826int
827linux_symlinkat(struct thread *td, struct linux_symlinkat_args *args)
828{
829 char *path, *to;
830 int error, dfd;
831
832 dfd = (args->newdfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->newdfd;
833 LCONVPATHEXIST_AT(td, args->oldname, &path, dfd);
834 /* Expand LCONVPATHCREATE so that `path' can be freed on errors */
835 error = linux_emul_convpath(td, args->newname, UIO_USERSPACE, &to, 1, dfd);
836 if (to == NULL) {
837 LFREEPATH(path);
838 return (error);
839 }
840
841#ifdef DEBUG
842 if (ldebug(symlinkat))
843 printf(ARGS(symlinkat, "%s, %s"), path, to);
844#endif
845
846 error = kern_symlinkat(td, path, dfd, to, UIO_SYSSPACE);
847 LFREEPATH(path);
848 LFREEPATH(to);
849 return (error);
850}
851
852int
799linux_readlink(struct thread *td, struct linux_readlink_args *args)
800{
801 char *name;
802 int error;
803
804 LCONVPATHEXIST(td, args->name, &name);
805
806#ifdef DEBUG
807 if (ldebug(readlink))
808 printf(ARGS(readlink, "%s, %p, %d"), name, (void *)args->buf,
809 args->count);
810#endif
811 error = kern_readlink(td, name, UIO_SYSSPACE, args->buf, UIO_USERSPACE,
812 args->count);
813 LFREEPATH(name);
814 return (error);
815}
816
817int
853linux_readlink(struct thread *td, struct linux_readlink_args *args)
854{
855 char *name;
856 int error;
857
858 LCONVPATHEXIST(td, args->name, &name);
859
860#ifdef DEBUG
861 if (ldebug(readlink))
862 printf(ARGS(readlink, "%s, %p, %d"), name, (void *)args->buf,
863 args->count);
864#endif
865 error = kern_readlink(td, name, UIO_SYSSPACE, args->buf, UIO_USERSPACE,
866 args->count);
867 LFREEPATH(name);
868 return (error);
869}
870
871int
872linux_readlinkat(struct thread *td, struct linux_readlinkat_args *args)
873{
874 char *name;
875 int error, dfd;
876
877 dfd = (args->dfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->dfd;
878 LCONVPATHEXIST_AT(td, args->path, &name, dfd);
879
880#ifdef DEBUG
881 if (ldebug(readlinkat))
882 printf(ARGS(readlinkat, "%s, %p, %d"), name, (void *)args->buf,
883 args->bufsiz);
884#endif
885
886 error = kern_readlinkat(td, dfd, name, UIO_SYSSPACE, args->buf,
887 UIO_USERSPACE, args->bufsiz);
888 LFREEPATH(name);
889 return (error);
890}
891int
818linux_truncate(struct thread *td, struct linux_truncate_args *args)
819{
820 char *path;
821 int error;
822
823 LCONVPATHEXIST(td, args->path, &path);
824
825#ifdef DEBUG

--- 23 unchanged lines hidden (view full) ---

849int
850linux_link(struct thread *td, struct linux_link_args *args)
851{
852 char *path, *to;
853 int error;
854
855 LCONVPATHEXIST(td, args->path, &path);
856 /* Expand LCONVPATHCREATE so that `path' can be freed on errors */
892linux_truncate(struct thread *td, struct linux_truncate_args *args)
893{
894 char *path;
895 int error;
896
897 LCONVPATHEXIST(td, args->path, &path);
898
899#ifdef DEBUG

--- 23 unchanged lines hidden (view full) ---

923int
924linux_link(struct thread *td, struct linux_link_args *args)
925{
926 char *path, *to;
927 int error;
928
929 LCONVPATHEXIST(td, args->path, &path);
930 /* Expand LCONVPATHCREATE so that `path' can be freed on errors */
857 error = linux_emul_convpath(td, args->to, UIO_USERSPACE, &to, 1);
931 error = linux_emul_convpath(td, args->to, UIO_USERSPACE, &to, 1, AT_FDCWD);
858 if (to == NULL) {
859 LFREEPATH(path);
860 return (error);
861 }
862
863#ifdef DEBUG
864 if (ldebug(link))
865 printf(ARGS(link, "%s, %s"), path, to);
866#endif
867 error = kern_link(td, path, to, UIO_SYSSPACE);
868 LFREEPATH(path);
869 LFREEPATH(to);
870 return (error);
871}
872
873int
932 if (to == NULL) {
933 LFREEPATH(path);
934 return (error);
935 }
936
937#ifdef DEBUG
938 if (ldebug(link))
939 printf(ARGS(link, "%s, %s"), path, to);
940#endif
941 error = kern_link(td, path, to, UIO_SYSSPACE);
942 LFREEPATH(path);
943 LFREEPATH(to);
944 return (error);
945}
946
947int
948linux_linkat(struct thread *td, struct linux_linkat_args *args)
949{
950 char *path, *to;
951 int error, olddfd, newdfd;
952
953 /*
954 * They really introduced flags argument which is forbidden to
955 * use.
956 */
957 if (args->flags != 0)
958 return (EINVAL);
959
960 olddfd = (args->olddfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->olddfd;
961 newdfd = (args->newdfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->newdfd;
962 LCONVPATHEXIST_AT(td, args->oldname, &path, olddfd);
963 /* Expand LCONVPATHCREATE so that `path' can be freed on errors */
964 error = linux_emul_convpath(td, args->newname, UIO_USERSPACE, &to, 1, newdfd);
965 if (to == NULL) {
966 LFREEPATH(path);
967 return (error);
968 }
969
970#ifdef DEBUG
971 if (ldebug(linkat))
972 printf(ARGS(linkat, "%i, %s, %i, %s, %i"), args->olddfd, path,
973 args->newdfd, to, args->flags);
974#endif
975
976 error = kern_linkat(td, olddfd, newdfd, path, to, UIO_SYSSPACE, FOLLOW);
977 LFREEPATH(path);
978 LFREEPATH(to);
979 return (error);
980}
981
982int
874linux_fdatasync(td, uap)
875 struct thread *td;
876 struct linux_fdatasync_args *uap;
877{
878 struct fsync_args bsd;
879
880 bsd.fd = uap->fd;
881 return fsync(td, &bsd);

--- 451 unchanged lines hidden (view full) ---

1333 printf(ARGS(chown, "%s, %d, %d"), path, args->uid, args->gid);
1334#endif
1335 error = kern_chown(td, path, UIO_SYSSPACE, args->uid, args->gid);
1336 LFREEPATH(path);
1337 return (error);
1338}
1339
1340int
983linux_fdatasync(td, uap)
984 struct thread *td;
985 struct linux_fdatasync_args *uap;
986{
987 struct fsync_args bsd;
988
989 bsd.fd = uap->fd;
990 return fsync(td, &bsd);

--- 451 unchanged lines hidden (view full) ---

1442 printf(ARGS(chown, "%s, %d, %d"), path, args->uid, args->gid);
1443#endif
1444 error = kern_chown(td, path, UIO_SYSSPACE, args->uid, args->gid);
1445 LFREEPATH(path);
1446 return (error);
1447}
1448
1449int
1450linux_fchownat(struct thread *td, struct linux_fchownat_args *args)
1451{
1452 char *path;
1453 int error, dfd, follow;
1454
1455 if (args->flag & ~LINUX_AT_SYMLINK_NOFOLLOW)
1456 return (EINVAL);
1457
1458 dfd = (args->dfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->dfd;
1459 LCONVPATHEXIST_AT(td, args->filename, &path, dfd);
1460
1461#ifdef DEBUG
1462 if (ldebug(fchownat))
1463 printf(ARGS(fchownat, "%s, %d, %d"), path, args->uid, args->gid);
1464#endif
1465
1466 follow = (args->flag & LINUX_AT_SYMLINK_NOFOLLOW) == 0 ? 0 :
1467 AT_SYMLINK_NOFOLLOW;
1468 error = kern_fchownat(td, dfd, path, UIO_SYSSPACE, args->uid, args->gid,
1469 follow);
1470 LFREEPATH(path);
1471 return (error);
1472}
1473
1474int
1341linux_lchown(struct thread *td, struct linux_lchown_args *args)
1342{
1343 char *path;
1344 int error;
1345
1346 LCONVPATHEXIST(td, args->path, &path);
1347
1348#ifdef DEBUG
1349 if (ldebug(lchown))
1350 printf(ARGS(lchown, "%s, %d, %d"), path, args->uid, args->gid);
1351#endif
1352 error = kern_lchown(td, path, UIO_SYSSPACE, args->uid, args->gid);
1353 LFREEPATH(path);
1354 return (error);
1355}
1475linux_lchown(struct thread *td, struct linux_lchown_args *args)
1476{
1477 char *path;
1478 int error;
1479
1480 LCONVPATHEXIST(td, args->path, &path);
1481
1482#ifdef DEBUG
1483 if (ldebug(lchown))
1484 printf(ARGS(lchown, "%s, %d, %d"), path, args->uid, args->gid);
1485#endif
1486 error = kern_lchown(td, path, UIO_SYSSPACE, args->uid, args->gid);
1487 LFREEPATH(path);
1488 return (error);
1489}