Changeset View
Changeset View
Standalone View
Standalone View
head/sys/compat/linux/linux_file.c
Show First 20 Lines • Show All 115 Lines • ▼ Show 20 Lines | linux_creat(struct thread *td, struct linux_creat_args *args) | ||||
error = kern_openat(td, AT_FDCWD, path, UIO_SYSSPACE, | error = kern_openat(td, AT_FDCWD, path, UIO_SYSSPACE, | ||||
O_WRONLY | O_CREAT | O_TRUNC, args->mode); | O_WRONLY | O_CREAT | O_TRUNC, args->mode); | ||||
LFREEPATH(path); | LFREEPATH(path); | ||||
return (error); | return (error); | ||||
} | } | ||||
#endif | #endif | ||||
static int | static int | ||||
linux_common_open(struct thread *td, int dirfd, const char *path, int l_flags, | linux_common_openflags(int l_flags) | ||||
int mode, enum uio_seg seg) | |||||
{ | { | ||||
struct proc *p = td->td_proc; | int bsd_flags; | ||||
struct file *fp; | |||||
int fd; | |||||
int bsd_flags, error; | |||||
bsd_flags = 0; | bsd_flags = 0; | ||||
switch (l_flags & LINUX_O_ACCMODE) { | switch (l_flags & LINUX_O_ACCMODE) { | ||||
case LINUX_O_WRONLY: | case LINUX_O_WRONLY: | ||||
bsd_flags |= O_WRONLY; | bsd_flags |= O_WRONLY; | ||||
break; | break; | ||||
case LINUX_O_RDWR: | case LINUX_O_RDWR: | ||||
bsd_flags |= O_RDWR; | bsd_flags |= O_RDWR; | ||||
Show All 23 Lines | if (l_flags & LINUX_O_NOCTTY) | ||||
bsd_flags |= O_NOCTTY; | bsd_flags |= O_NOCTTY; | ||||
if (l_flags & LINUX_O_DIRECT) | if (l_flags & LINUX_O_DIRECT) | ||||
bsd_flags |= O_DIRECT; | bsd_flags |= O_DIRECT; | ||||
if (l_flags & LINUX_O_NOFOLLOW) | if (l_flags & LINUX_O_NOFOLLOW) | ||||
bsd_flags |= O_NOFOLLOW; | bsd_flags |= O_NOFOLLOW; | ||||
if (l_flags & LINUX_O_DIRECTORY) | if (l_flags & LINUX_O_DIRECTORY) | ||||
bsd_flags |= O_DIRECTORY; | bsd_flags |= O_DIRECTORY; | ||||
/* XXX LINUX_O_NOATIME: unable to be easily implemented. */ | /* XXX LINUX_O_NOATIME: unable to be easily implemented. */ | ||||
return (bsd_flags); | |||||
} | |||||
static int | |||||
linux_common_open(struct thread *td, int dirfd, const char *path, int l_flags, | |||||
int mode, enum uio_seg seg) | |||||
{ | |||||
struct proc *p = td->td_proc; | |||||
struct file *fp; | |||||
int fd; | |||||
int bsd_flags, error; | |||||
bsd_flags = linux_common_openflags(l_flags); | |||||
error = kern_openat(td, dirfd, path, seg, bsd_flags, mode); | error = kern_openat(td, dirfd, path, seg, bsd_flags, mode); | ||||
if (error != 0) { | if (error != 0) { | ||||
if (error == EMLINK) | if (error == EMLINK) | ||||
error = ELOOP; | error = ELOOP; | ||||
goto done; | goto done; | ||||
} | } | ||||
if (p->p_flag & P_CONTROLT) | if (p->p_flag & P_CONTROLT) | ||||
goto done; | goto done; | ||||
▲ Show 20 Lines • Show All 69 Lines • ▼ Show 20 Lines | else | ||||
LCONVPATHEXIST(td, args->path, &path); | LCONVPATHEXIST(td, args->path, &path); | ||||
error = linux_common_open(td, AT_FDCWD, path, args->flags, args->mode, | error = linux_common_open(td, AT_FDCWD, path, args->flags, args->mode, | ||||
UIO_SYSSPACE); | UIO_SYSSPACE); | ||||
LFREEPATH(path); | LFREEPATH(path); | ||||
return (error); | return (error); | ||||
} | } | ||||
#endif | #endif | ||||
int | |||||
linux_name_to_handle_at(struct thread *td, | |||||
struct linux_name_to_handle_at_args *args) | |||||
{ | |||||
static const l_int valid_flags = (LINUX_AT_SYMLINK_FOLLOW | | |||||
LINUX_AT_EMPTY_PATH); | |||||
static const l_uint fh_size = sizeof(fhandle_t); | |||||
fhandle_t fh; | |||||
l_uint fh_bytes; | |||||
l_int mount_id; | |||||
int error, fd, bsd_flags; | |||||
if (args->flags & ~valid_flags) | |||||
return (EINVAL); | |||||
if (args->flags & LINUX_AT_EMPTY_PATH) | |||||
/* XXX: not supported yet */ | |||||
return (EOPNOTSUPP); | |||||
fd = args->dirfd; | |||||
if (fd == LINUX_AT_FDCWD) | |||||
fd = AT_FDCWD; | |||||
bsd_flags = 0; | |||||
if (!(args->flags & LINUX_AT_SYMLINK_FOLLOW)) | |||||
bsd_flags |= AT_SYMLINK_NOFOLLOW; | |||||
if (!LUSECONVPATH(td)) { | |||||
error = kern_getfhat(td, bsd_flags, fd, args->name, | |||||
UIO_USERSPACE, &fh, UIO_SYSSPACE); | |||||
} else { | |||||
char *path; | |||||
LCONVPATH_AT(td, args->name, &path, 0, fd); | |||||
error = kern_getfhat(td, bsd_flags, fd, path, UIO_SYSSPACE, | |||||
&fh, UIO_SYSSPACE); | |||||
LFREEPATH(path); | |||||
} | |||||
if (error != 0) | |||||
return (error); | |||||
/* Emit mount_id -- required before EOVERFLOW case. */ | |||||
mount_id = (fh.fh_fsid.val[0] ^ fh.fh_fsid.val[1]); | |||||
error = copyout(&mount_id, args->mnt_id, sizeof(mount_id)); | |||||
if (error != 0) | |||||
return (error); | |||||
/* Check if there is room for handle. */ | |||||
error = copyin(&args->handle->handle_bytes, &fh_bytes, | |||||
sizeof(fh_bytes)); | |||||
if (error != 0) | |||||
return (error); | |||||
if (fh_bytes < fh_size) { | |||||
error = copyout(&fh_size, &args->handle->handle_bytes, | |||||
sizeof(fh_size)); | |||||
if (error == 0) | |||||
error = EOVERFLOW; | |||||
return (error); | |||||
} | |||||
/* Emit handle. */ | |||||
mount_id = 0; | |||||
/* | |||||
* We don't use handle_type for anything yet, but initialize a known | |||||
* value. | |||||
*/ | |||||
error = copyout(&mount_id, &args->handle->handle_type, | |||||
sizeof(mount_id)); | |||||
if (error != 0) | |||||
return (error); | |||||
error = copyout(&fh, &args->handle->f_handle, | |||||
sizeof(fh)); | |||||
return (error); | |||||
} | |||||
int | |||||
linux_open_by_handle_at(struct thread *td, | |||||
struct linux_open_by_handle_at_args *args) | |||||
{ | |||||
l_uint fh_bytes; | |||||
int bsd_flags, error; | |||||
error = copyin(&args->handle->handle_bytes, &fh_bytes, | |||||
sizeof(fh_bytes)); | |||||
if (error != 0) | |||||
return (error); | |||||
if (fh_bytes < sizeof(fhandle_t)) | |||||
return (EINVAL); | |||||
bsd_flags = linux_common_openflags(args->flags); | |||||
return (kern_fhopen(td, (void *)&args->handle->f_handle, bsd_flags)); | |||||
} | |||||
int | int | ||||
linux_lseek(struct thread *td, struct linux_lseek_args *args) | linux_lseek(struct thread *td, struct linux_lseek_args *args) | ||||
{ | { | ||||
return (kern_lseek(td, args->fdes, args->off, args->whence)); | return (kern_lseek(td, args->fdes, args->off, args->whence)); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 1,657 Lines • Show Last 20 Lines |