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} |