Changeset View
Changeset View
Standalone View
Standalone View
head/sys/compat/linux/linux_file.c
Show First 20 Lines • Show All 62 Lines • ▼ Show 20 Lines | |||||
#include <compat/linux/linux_misc.h> | #include <compat/linux/linux_misc.h> | ||||
#include <compat/linux/linux_util.h> | #include <compat/linux/linux_util.h> | ||||
#include <compat/linux/linux_file.h> | #include <compat/linux/linux_file.h> | ||||
static int linux_common_open(struct thread *, int, char *, int, int); | static int linux_common_open(struct thread *, int, char *, int, int); | ||||
static int linux_getdents_error(struct thread *, int, int); | static int linux_getdents_error(struct thread *, int, int); | ||||
#ifdef LINUX_LEGACY_SYSCALLS | |||||
int | int | ||||
linux_creat(struct thread *td, struct linux_creat_args *args) | linux_creat(struct thread *td, struct linux_creat_args *args) | ||||
{ | { | ||||
char *path; | char *path; | ||||
int error; | int error; | ||||
LCONVPATHEXIST(td, args->path, &path); | LCONVPATHEXIST(td, args->path, &path); | ||||
#ifdef DEBUG | #ifdef DEBUG | ||||
if (ldebug(creat)) | if (ldebug(creat)) | ||||
printf(ARGS(creat, "%s, %d"), path, args->mode); | printf(ARGS(creat, "%s, %d"), path, args->mode); | ||||
#endif | #endif | ||||
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 | |||||
static int | static int | ||||
linux_common_open(struct thread *td, int dirfd, char *path, int l_flags, int mode) | linux_common_open(struct thread *td, int dirfd, char *path, int l_flags, int mode) | ||||
{ | { | ||||
struct proc *p = td->td_proc; | struct proc *p = td->td_proc; | ||||
struct file *fp; | struct file *fp; | ||||
int fd; | int fd; | ||||
int bsd_flags, error; | int bsd_flags, error; | ||||
▲ Show 20 Lines • Show All 63 Lines • ▼ Show 20 Lines | if (SESS_LEADER(p) && !(p->p_flag & P_CONTROLT)) { | ||||
PROC_UNLOCK(p); | PROC_UNLOCK(p); | ||||
sx_sunlock(&proctree_lock); | sx_sunlock(&proctree_lock); | ||||
} | } | ||||
fdrop(fp, td); | fdrop(fp, td); | ||||
} | } | ||||
done: | done: | ||||
#ifdef DEBUG | #ifdef DEBUG | ||||
#ifdef LINUX_LEGACY_SYSCALLS | |||||
if (ldebug(open)) | if (ldebug(open)) | ||||
#else | |||||
if (ldebug(openat)) | |||||
#endif | |||||
printf(LMSG("open returns error %d"), error); | printf(LMSG("open returns error %d"), error); | ||||
#endif | #endif | ||||
LFREEPATH(path); | LFREEPATH(path); | ||||
return (error); | return (error); | ||||
} | } | ||||
int | int | ||||
linux_openat(struct thread *td, struct linux_openat_args *args) | linux_openat(struct thread *td, struct linux_openat_args *args) | ||||
Show All 9 Lines | |||||
#ifdef DEBUG | #ifdef DEBUG | ||||
if (ldebug(openat)) | if (ldebug(openat)) | ||||
printf(ARGS(openat, "%i, %s, 0x%x, 0x%x"), args->dfd, | printf(ARGS(openat, "%i, %s, 0x%x, 0x%x"), args->dfd, | ||||
path, args->flags, args->mode); | path, args->flags, args->mode); | ||||
#endif | #endif | ||||
return (linux_common_open(td, dfd, path, args->flags, args->mode)); | return (linux_common_open(td, dfd, path, args->flags, args->mode)); | ||||
} | } | ||||
#ifdef LINUX_LEGACY_SYSCALLS | |||||
int | int | ||||
linux_open(struct thread *td, struct linux_open_args *args) | linux_open(struct thread *td, struct linux_open_args *args) | ||||
{ | { | ||||
char *path; | char *path; | ||||
if (args->flags & LINUX_O_CREAT) | if (args->flags & LINUX_O_CREAT) | ||||
LCONVPATHCREAT(td, args->path, &path); | LCONVPATHCREAT(td, args->path, &path); | ||||
else | else | ||||
LCONVPATHEXIST(td, args->path, &path); | LCONVPATHEXIST(td, args->path, &path); | ||||
#ifdef DEBUG | #ifdef DEBUG | ||||
if (ldebug(open)) | if (ldebug(open)) | ||||
printf(ARGS(open, "%s, 0x%x, 0x%x"), | printf(ARGS(open, "%s, 0x%x, 0x%x"), | ||||
path, args->flags, args->mode); | path, args->flags, args->mode); | ||||
#endif | #endif | ||||
return (linux_common_open(td, AT_FDCWD, path, args->flags, args->mode)); | return (linux_common_open(td, AT_FDCWD, path, args->flags, args->mode)); | ||||
} | } | ||||
#endif | |||||
int | int | ||||
linux_lseek(struct thread *td, struct linux_lseek_args *args) | linux_lseek(struct thread *td, struct linux_lseek_args *args) | ||||
{ | { | ||||
#ifdef DEBUG | #ifdef DEBUG | ||||
if (ldebug(lseek)) | if (ldebug(lseek)) | ||||
printf(ARGS(lseek, "%d, %ld, %d"), | printf(ARGS(lseek, "%d, %ld, %d"), | ||||
▲ Show 20 Lines • Show All 82 Lines • ▼ Show 20 Lines | |||||
*/ | */ | ||||
#define LINUX_RECLEN(namlen) \ | #define LINUX_RECLEN(namlen) \ | ||||
roundup(offsetof(struct l_dirent, d_name) + (namlen) + 2, sizeof(l_ulong)) | roundup(offsetof(struct l_dirent, d_name) + (namlen) + 2, sizeof(l_ulong)) | ||||
#define LINUX_RECLEN64(namlen) \ | #define LINUX_RECLEN64(namlen) \ | ||||
roundup(offsetof(struct l_dirent64, d_name) + (namlen) + 1, \ | roundup(offsetof(struct l_dirent64, d_name) + (namlen) + 1, \ | ||||
sizeof(uint64_t)) | sizeof(uint64_t)) | ||||
#ifdef LINUX_LEGACY_SYSCALLS | |||||
int | int | ||||
linux_getdents(struct thread *td, struct linux_getdents_args *args) | linux_getdents(struct thread *td, struct linux_getdents_args *args) | ||||
{ | { | ||||
struct dirent *bdp; | struct dirent *bdp; | ||||
caddr_t inp, buf; /* BSD-format */ | caddr_t inp, buf; /* BSD-format */ | ||||
int len, reclen; /* BSD-format */ | int len, reclen; /* BSD-format */ | ||||
caddr_t outp; /* Linux-format */ | caddr_t outp; /* Linux-format */ | ||||
int resid, linuxreclen; /* Linux-format */ | int resid, linuxreclen; /* Linux-format */ | ||||
▲ Show 20 Lines • Show All 63 Lines • ▼ Show 20 Lines | #endif | ||||
td->td_retval[0] = retval; | td->td_retval[0] = retval; | ||||
out: | out: | ||||
free(lbuf, M_TEMP); | free(lbuf, M_TEMP); | ||||
out1: | out1: | ||||
free(buf, M_TEMP); | free(buf, M_TEMP); | ||||
return (error); | return (error); | ||||
} | } | ||||
#endif | |||||
int | int | ||||
linux_getdents64(struct thread *td, struct linux_getdents64_args *args) | linux_getdents64(struct thread *td, struct linux_getdents64_args *args) | ||||
{ | { | ||||
struct dirent *bdp; | struct dirent *bdp; | ||||
caddr_t inp, buf; /* BSD-format */ | caddr_t inp, buf; /* BSD-format */ | ||||
int len, reclen; /* BSD-format */ | int len, reclen; /* BSD-format */ | ||||
caddr_t outp; /* Linux-format */ | caddr_t outp; /* Linux-format */ | ||||
▲ Show 20 Lines • Show All 117 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ | #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ | ||||
/* | /* | ||||
* These exist mainly for hooks for doing /compat/linux translation. | * These exist mainly for hooks for doing /compat/linux translation. | ||||
*/ | */ | ||||
#ifdef LINUX_LEGACY_SYSCALLS | |||||
int | int | ||||
linux_access(struct thread *td, struct linux_access_args *args) | linux_access(struct thread *td, struct linux_access_args *args) | ||||
{ | { | ||||
char *path; | char *path; | ||||
int error; | int error; | ||||
/* Linux convention. */ | /* Linux convention. */ | ||||
if (args->amode & ~(F_OK | X_OK | W_OK | R_OK)) | if (args->amode & ~(F_OK | X_OK | W_OK | R_OK)) | ||||
return (EINVAL); | return (EINVAL); | ||||
LCONVPATHEXIST(td, args->path, &path); | LCONVPATHEXIST(td, args->path, &path); | ||||
#ifdef DEBUG | #ifdef DEBUG | ||||
if (ldebug(access)) | if (ldebug(access)) | ||||
printf(ARGS(access, "%s, %d"), path, args->amode); | printf(ARGS(access, "%s, %d"), path, args->amode); | ||||
#endif | #endif | ||||
error = kern_accessat(td, AT_FDCWD, path, UIO_SYSSPACE, 0, | error = kern_accessat(td, AT_FDCWD, path, UIO_SYSSPACE, 0, | ||||
args->amode); | args->amode); | ||||
LFREEPATH(path); | LFREEPATH(path); | ||||
return (error); | return (error); | ||||
} | } | ||||
#endif | |||||
int | int | ||||
linux_faccessat(struct thread *td, struct linux_faccessat_args *args) | linux_faccessat(struct thread *td, struct linux_faccessat_args *args) | ||||
{ | { | ||||
char *path; | char *path; | ||||
int error, dfd; | int error, dfd; | ||||
/* Linux convention. */ | /* Linux convention. */ | ||||
Show All 9 Lines | |||||
#endif | #endif | ||||
error = kern_accessat(td, dfd, path, UIO_SYSSPACE, 0, args->amode); | error = kern_accessat(td, dfd, path, UIO_SYSSPACE, 0, args->amode); | ||||
LFREEPATH(path); | LFREEPATH(path); | ||||
return (error); | return (error); | ||||
} | } | ||||
#ifdef LINUX_LEGACY_SYSCALLS | |||||
int | int | ||||
linux_unlink(struct thread *td, struct linux_unlink_args *args) | linux_unlink(struct thread *td, struct linux_unlink_args *args) | ||||
{ | { | ||||
char *path; | char *path; | ||||
int error; | int error; | ||||
struct stat st; | struct stat st; | ||||
LCONVPATHEXIST(td, args->path, &path); | LCONVPATHEXIST(td, args->path, &path); | ||||
Show All 10 Lines | if (kern_statat(td, 0, AT_FDCWD, path, UIO_SYSSPACE, &st, | ||||
NULL) == 0) { | NULL) == 0) { | ||||
if (S_ISDIR(st.st_mode)) | if (S_ISDIR(st.st_mode)) | ||||
error = EISDIR; | error = EISDIR; | ||||
} | } | ||||
} | } | ||||
LFREEPATH(path); | LFREEPATH(path); | ||||
return (error); | return (error); | ||||
} | } | ||||
#endif | |||||
int | int | ||||
linux_unlinkat(struct thread *td, struct linux_unlinkat_args *args) | linux_unlinkat(struct thread *td, struct linux_unlinkat_args *args) | ||||
{ | { | ||||
char *path; | char *path; | ||||
int error, dfd; | int error, dfd; | ||||
struct stat st; | struct stat st; | ||||
Show All 33 Lines | #ifdef DEBUG | ||||
if (ldebug(chdir)) | if (ldebug(chdir)) | ||||
printf(ARGS(chdir, "%s"), path); | printf(ARGS(chdir, "%s"), path); | ||||
#endif | #endif | ||||
error = kern_chdir(td, path, UIO_SYSSPACE); | error = kern_chdir(td, path, UIO_SYSSPACE); | ||||
LFREEPATH(path); | LFREEPATH(path); | ||||
return (error); | return (error); | ||||
} | } | ||||
#ifdef LINUX_LEGACY_SYSCALLS | |||||
int | int | ||||
linux_chmod(struct thread *td, struct linux_chmod_args *args) | linux_chmod(struct thread *td, struct linux_chmod_args *args) | ||||
{ | { | ||||
char *path; | char *path; | ||||
int error; | int error; | ||||
LCONVPATHEXIST(td, args->path, &path); | LCONVPATHEXIST(td, args->path, &path); | ||||
#ifdef DEBUG | #ifdef DEBUG | ||||
if (ldebug(chmod)) | if (ldebug(chmod)) | ||||
printf(ARGS(chmod, "%s, %d"), path, args->mode); | printf(ARGS(chmod, "%s, %d"), path, args->mode); | ||||
#endif | #endif | ||||
error = kern_fchmodat(td, AT_FDCWD, path, UIO_SYSSPACE, | error = kern_fchmodat(td, AT_FDCWD, path, UIO_SYSSPACE, | ||||
args->mode, 0); | args->mode, 0); | ||||
LFREEPATH(path); | LFREEPATH(path); | ||||
return (error); | return (error); | ||||
} | } | ||||
#endif | |||||
int | int | ||||
linux_fchmodat(struct thread *td, struct linux_fchmodat_args *args) | linux_fchmodat(struct thread *td, struct linux_fchmodat_args *args) | ||||
{ | { | ||||
char *path; | char *path; | ||||
int error, dfd; | int error, dfd; | ||||
dfd = (args->dfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->dfd; | dfd = (args->dfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->dfd; | ||||
LCONVPATHEXIST_AT(td, args->filename, &path, dfd); | LCONVPATHEXIST_AT(td, args->filename, &path, dfd); | ||||
#ifdef DEBUG | #ifdef DEBUG | ||||
if (ldebug(fchmodat)) | if (ldebug(fchmodat)) | ||||
printf(ARGS(fchmodat, "%s, %d"), path, args->mode); | printf(ARGS(fchmodat, "%s, %d"), path, args->mode); | ||||
#endif | #endif | ||||
error = kern_fchmodat(td, dfd, path, UIO_SYSSPACE, args->mode, 0); | error = kern_fchmodat(td, dfd, path, UIO_SYSSPACE, args->mode, 0); | ||||
LFREEPATH(path); | LFREEPATH(path); | ||||
return (error); | return (error); | ||||
} | } | ||||
#ifdef LINUX_LEGACY_SYSCALLS | |||||
int | int | ||||
linux_mkdir(struct thread *td, struct linux_mkdir_args *args) | linux_mkdir(struct thread *td, struct linux_mkdir_args *args) | ||||
{ | { | ||||
char *path; | char *path; | ||||
int error; | int error; | ||||
LCONVPATHCREAT(td, args->path, &path); | LCONVPATHCREAT(td, args->path, &path); | ||||
#ifdef DEBUG | #ifdef DEBUG | ||||
if (ldebug(mkdir)) | if (ldebug(mkdir)) | ||||
printf(ARGS(mkdir, "%s, %d"), path, args->mode); | printf(ARGS(mkdir, "%s, %d"), path, args->mode); | ||||
#endif | #endif | ||||
error = kern_mkdirat(td, AT_FDCWD, path, UIO_SYSSPACE, args->mode); | error = kern_mkdirat(td, AT_FDCWD, path, UIO_SYSSPACE, args->mode); | ||||
LFREEPATH(path); | LFREEPATH(path); | ||||
return (error); | return (error); | ||||
} | } | ||||
#endif | |||||
int | int | ||||
linux_mkdirat(struct thread *td, struct linux_mkdirat_args *args) | linux_mkdirat(struct thread *td, struct linux_mkdirat_args *args) | ||||
{ | { | ||||
char *path; | char *path; | ||||
int error, dfd; | int error, dfd; | ||||
dfd = (args->dfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->dfd; | dfd = (args->dfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->dfd; | ||||
LCONVPATHCREAT_AT(td, args->pathname, &path, dfd); | LCONVPATHCREAT_AT(td, args->pathname, &path, dfd); | ||||
#ifdef DEBUG | #ifdef DEBUG | ||||
if (ldebug(mkdirat)) | if (ldebug(mkdirat)) | ||||
printf(ARGS(mkdirat, "%s, %d"), path, args->mode); | printf(ARGS(mkdirat, "%s, %d"), path, args->mode); | ||||
#endif | #endif | ||||
error = kern_mkdirat(td, dfd, path, UIO_SYSSPACE, args->mode); | error = kern_mkdirat(td, dfd, path, UIO_SYSSPACE, args->mode); | ||||
LFREEPATH(path); | LFREEPATH(path); | ||||
return (error); | return (error); | ||||
} | } | ||||
#ifdef LINUX_LEGACY_SYSCALLS | |||||
int | int | ||||
linux_rmdir(struct thread *td, struct linux_rmdir_args *args) | linux_rmdir(struct thread *td, struct linux_rmdir_args *args) | ||||
{ | { | ||||
char *path; | char *path; | ||||
int error; | int error; | ||||
LCONVPATHEXIST(td, args->path, &path); | LCONVPATHEXIST(td, args->path, &path); | ||||
Show All 24 Lines | #ifdef DEBUG | ||||
if (ldebug(rename)) | if (ldebug(rename)) | ||||
printf(ARGS(rename, "%s, %s"), from, to); | printf(ARGS(rename, "%s, %s"), from, to); | ||||
#endif | #endif | ||||
error = kern_renameat(td, AT_FDCWD, from, AT_FDCWD, to, UIO_SYSSPACE); | error = kern_renameat(td, AT_FDCWD, from, AT_FDCWD, to, UIO_SYSSPACE); | ||||
LFREEPATH(from); | LFREEPATH(from); | ||||
LFREEPATH(to); | LFREEPATH(to); | ||||
return (error); | return (error); | ||||
} | } | ||||
#endif | |||||
int | int | ||||
linux_renameat(struct thread *td, struct linux_renameat_args *args) | linux_renameat(struct thread *td, struct linux_renameat_args *args) | ||||
{ | { | ||||
char *from, *to; | char *from, *to; | ||||
int error, olddfd, newdfd; | int error, olddfd, newdfd; | ||||
olddfd = (args->olddfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->olddfd; | olddfd = (args->olddfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->olddfd; | ||||
Show All 11 Lines | if (ldebug(renameat)) | ||||
printf(ARGS(renameat, "%s, %s"), from, to); | printf(ARGS(renameat, "%s, %s"), from, to); | ||||
#endif | #endif | ||||
error = kern_renameat(td, olddfd, from, newdfd, to, UIO_SYSSPACE); | error = kern_renameat(td, olddfd, from, newdfd, to, UIO_SYSSPACE); | ||||
LFREEPATH(from); | LFREEPATH(from); | ||||
LFREEPATH(to); | LFREEPATH(to); | ||||
return (error); | return (error); | ||||
} | } | ||||
#ifdef LINUX_LEGACY_SYSCALLS | |||||
int | int | ||||
linux_symlink(struct thread *td, struct linux_symlink_args *args) | linux_symlink(struct thread *td, struct linux_symlink_args *args) | ||||
{ | { | ||||
char *path, *to; | char *path, *to; | ||||
int error; | int error; | ||||
LCONVPATHEXIST(td, args->path, &path); | LCONVPATHEXIST(td, args->path, &path); | ||||
/* Expand LCONVPATHCREATE so that `path' can be freed on errors */ | /* Expand LCONVPATHCREATE so that `path' can be freed on errors */ | ||||
error = linux_emul_convpath(td, args->to, UIO_USERSPACE, &to, 1, AT_FDCWD); | error = linux_emul_convpath(td, args->to, UIO_USERSPACE, &to, 1, AT_FDCWD); | ||||
if (to == NULL) { | if (to == NULL) { | ||||
LFREEPATH(path); | LFREEPATH(path); | ||||
return (error); | return (error); | ||||
} | } | ||||
#ifdef DEBUG | #ifdef DEBUG | ||||
if (ldebug(symlink)) | if (ldebug(symlink)) | ||||
printf(ARGS(symlink, "%s, %s"), path, to); | printf(ARGS(symlink, "%s, %s"), path, to); | ||||
#endif | #endif | ||||
error = kern_symlinkat(td, path, AT_FDCWD, to, UIO_SYSSPACE); | error = kern_symlinkat(td, path, AT_FDCWD, to, UIO_SYSSPACE); | ||||
LFREEPATH(path); | LFREEPATH(path); | ||||
LFREEPATH(to); | LFREEPATH(to); | ||||
return (error); | return (error); | ||||
} | } | ||||
#endif | |||||
int | int | ||||
linux_symlinkat(struct thread *td, struct linux_symlinkat_args *args) | linux_symlinkat(struct thread *td, struct linux_symlinkat_args *args) | ||||
{ | { | ||||
char *path, *to; | char *path, *to; | ||||
int error, dfd; | int error, dfd; | ||||
dfd = (args->newdfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->newdfd; | dfd = (args->newdfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->newdfd; | ||||
Show All 11 Lines | |||||
#endif | #endif | ||||
error = kern_symlinkat(td, path, dfd, to, UIO_SYSSPACE); | error = kern_symlinkat(td, path, dfd, to, UIO_SYSSPACE); | ||||
LFREEPATH(path); | LFREEPATH(path); | ||||
LFREEPATH(to); | LFREEPATH(to); | ||||
return (error); | return (error); | ||||
} | } | ||||
#ifdef LINUX_LEGACY_SYSCALLS | |||||
int | int | ||||
linux_readlink(struct thread *td, struct linux_readlink_args *args) | linux_readlink(struct thread *td, struct linux_readlink_args *args) | ||||
{ | { | ||||
char *name; | char *name; | ||||
int error; | int error; | ||||
LCONVPATHEXIST(td, args->name, &name); | LCONVPATHEXIST(td, args->name, &name); | ||||
#ifdef DEBUG | #ifdef DEBUG | ||||
if (ldebug(readlink)) | if (ldebug(readlink)) | ||||
printf(ARGS(readlink, "%s, %p, %d"), name, (void *)args->buf, | printf(ARGS(readlink, "%s, %p, %d"), name, (void *)args->buf, | ||||
args->count); | args->count); | ||||
#endif | #endif | ||||
error = kern_readlinkat(td, AT_FDCWD, name, UIO_SYSSPACE, | error = kern_readlinkat(td, AT_FDCWD, name, UIO_SYSSPACE, | ||||
args->buf, UIO_USERSPACE, args->count); | args->buf, UIO_USERSPACE, args->count); | ||||
LFREEPATH(name); | LFREEPATH(name); | ||||
return (error); | return (error); | ||||
} | } | ||||
#endif | |||||
int | int | ||||
linux_readlinkat(struct thread *td, struct linux_readlinkat_args *args) | linux_readlinkat(struct thread *td, struct linux_readlinkat_args *args) | ||||
{ | { | ||||
char *name; | char *name; | ||||
int error, dfd; | int error, dfd; | ||||
dfd = (args->dfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->dfd; | dfd = (args->dfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->dfd; | ||||
▲ Show 20 Lines • Show All 51 Lines • ▼ Show 20 Lines | |||||
int | int | ||||
linux_ftruncate(struct thread *td, struct linux_ftruncate_args *args) | linux_ftruncate(struct thread *td, struct linux_ftruncate_args *args) | ||||
{ | { | ||||
return (kern_ftruncate(td, args->fd, args->length)); | return (kern_ftruncate(td, args->fd, args->length)); | ||||
} | } | ||||
#ifdef LINUX_LEGACY_SYSCALLS | |||||
int | int | ||||
linux_link(struct thread *td, struct linux_link_args *args) | linux_link(struct thread *td, struct linux_link_args *args) | ||||
{ | { | ||||
char *path, *to; | char *path, *to; | ||||
int error; | int error; | ||||
LCONVPATHEXIST(td, args->path, &path); | LCONVPATHEXIST(td, args->path, &path); | ||||
/* Expand LCONVPATHCREATE so that `path' can be freed on errors */ | /* Expand LCONVPATHCREATE so that `path' can be freed on errors */ | ||||
error = linux_emul_convpath(td, args->to, UIO_USERSPACE, &to, 1, AT_FDCWD); | error = linux_emul_convpath(td, args->to, UIO_USERSPACE, &to, 1, AT_FDCWD); | ||||
if (to == NULL) { | if (to == NULL) { | ||||
LFREEPATH(path); | LFREEPATH(path); | ||||
return (error); | return (error); | ||||
} | } | ||||
#ifdef DEBUG | #ifdef DEBUG | ||||
if (ldebug(link)) | if (ldebug(link)) | ||||
printf(ARGS(link, "%s, %s"), path, to); | printf(ARGS(link, "%s, %s"), path, to); | ||||
#endif | #endif | ||||
error = kern_linkat(td, AT_FDCWD, AT_FDCWD, path, to, UIO_SYSSPACE, | error = kern_linkat(td, AT_FDCWD, AT_FDCWD, path, to, UIO_SYSSPACE, | ||||
FOLLOW); | FOLLOW); | ||||
LFREEPATH(path); | LFREEPATH(path); | ||||
LFREEPATH(to); | LFREEPATH(to); | ||||
return (error); | return (error); | ||||
} | } | ||||
#endif | |||||
int | int | ||||
linux_linkat(struct thread *td, struct linux_linkat_args *args) | linux_linkat(struct thread *td, struct linux_linkat_args *args) | ||||
{ | { | ||||
char *path, *to; | char *path, *to; | ||||
int error, olddfd, newdfd, follow; | int error, olddfd, newdfd, follow; | ||||
if (args->flag & ~LINUX_AT_SYMLINK_FOLLOW) | if (args->flag & ~LINUX_AT_SYMLINK_FOLLOW) | ||||
▲ Show 20 Lines • Show All 185 Lines • ▼ Show 20 Lines | linux_oldumount(struct thread *td, struct linux_oldumount_args *args) | ||||
struct linux_umount_args args2; | struct linux_umount_args args2; | ||||
args2.path = args->path; | args2.path = args->path; | ||||
args2.flags = 0; | args2.flags = 0; | ||||
return (linux_umount(td, &args2)); | return (linux_umount(td, &args2)); | ||||
} | } | ||||
#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ | #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ | ||||
#ifdef LINUX_LEGACY_SYSCALLS | |||||
int | int | ||||
linux_umount(struct thread *td, struct linux_umount_args *args) | linux_umount(struct thread *td, struct linux_umount_args *args) | ||||
{ | { | ||||
struct unmount_args bsd; | struct unmount_args bsd; | ||||
bsd.path = args->path; | bsd.path = args->path; | ||||
bsd.flags = args->flags; /* XXX correct? */ | bsd.flags = args->flags; /* XXX correct? */ | ||||
return (sys_unmount(td, &bsd)); | return (sys_unmount(td, &bsd)); | ||||
} | } | ||||
#endif | |||||
/* | /* | ||||
* fcntl family of syscalls | * fcntl family of syscalls | ||||
*/ | */ | ||||
struct l_flock { | struct l_flock { | ||||
l_short l_type; | l_short l_type; | ||||
l_short l_whence; | l_short l_whence; | ||||
▲ Show 20 Lines • Show All 295 Lines • ▼ Show 20 Lines | #endif | ||||
fcntl_args.fd = args->fd; | fcntl_args.fd = args->fd; | ||||
fcntl_args.cmd = args->cmd; | fcntl_args.cmd = args->cmd; | ||||
fcntl_args.arg = args->arg; | fcntl_args.arg = args->arg; | ||||
return (fcntl_common(td, &fcntl_args)); | return (fcntl_common(td, &fcntl_args)); | ||||
} | } | ||||
#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ | #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ | ||||
#ifdef LINUX_LEGACY_SYSCALLS | |||||
int | int | ||||
linux_chown(struct thread *td, struct linux_chown_args *args) | linux_chown(struct thread *td, struct linux_chown_args *args) | ||||
{ | { | ||||
char *path; | char *path; | ||||
int error; | int error; | ||||
LCONVPATHEXIST(td, args->path, &path); | LCONVPATHEXIST(td, args->path, &path); | ||||
#ifdef DEBUG | #ifdef DEBUG | ||||
if (ldebug(chown)) | if (ldebug(chown)) | ||||
printf(ARGS(chown, "%s, %d, %d"), path, args->uid, args->gid); | printf(ARGS(chown, "%s, %d, %d"), path, args->uid, args->gid); | ||||
#endif | #endif | ||||
error = kern_fchownat(td, AT_FDCWD, path, UIO_SYSSPACE, args->uid, | error = kern_fchownat(td, AT_FDCWD, path, UIO_SYSSPACE, args->uid, | ||||
args->gid, 0); | args->gid, 0); | ||||
LFREEPATH(path); | LFREEPATH(path); | ||||
return (error); | return (error); | ||||
} | } | ||||
#endif | |||||
int | int | ||||
linux_fchownat(struct thread *td, struct linux_fchownat_args *args) | linux_fchownat(struct thread *td, struct linux_fchownat_args *args) | ||||
{ | { | ||||
char *path; | char *path; | ||||
int error, dfd, flag; | int error, dfd, flag; | ||||
if (args->flag & ~LINUX_AT_SYMLINK_NOFOLLOW) | if (args->flag & ~LINUX_AT_SYMLINK_NOFOLLOW) | ||||
Show All 10 Lines | #endif | ||||
flag = (args->flag & LINUX_AT_SYMLINK_NOFOLLOW) == 0 ? 0 : | flag = (args->flag & LINUX_AT_SYMLINK_NOFOLLOW) == 0 ? 0 : | ||||
AT_SYMLINK_NOFOLLOW; | AT_SYMLINK_NOFOLLOW; | ||||
error = kern_fchownat(td, dfd, path, UIO_SYSSPACE, args->uid, args->gid, | error = kern_fchownat(td, dfd, path, UIO_SYSSPACE, args->uid, args->gid, | ||||
flag); | flag); | ||||
LFREEPATH(path); | LFREEPATH(path); | ||||
return (error); | return (error); | ||||
} | } | ||||
#ifdef LINUX_LEGACY_SYSCALLS | |||||
int | int | ||||
linux_lchown(struct thread *td, struct linux_lchown_args *args) | linux_lchown(struct thread *td, struct linux_lchown_args *args) | ||||
{ | { | ||||
char *path; | char *path; | ||||
int error; | int error; | ||||
LCONVPATHEXIST(td, args->path, &path); | LCONVPATHEXIST(td, args->path, &path); | ||||
#ifdef DEBUG | #ifdef DEBUG | ||||
if (ldebug(lchown)) | if (ldebug(lchown)) | ||||
printf(ARGS(lchown, "%s, %d, %d"), path, args->uid, args->gid); | printf(ARGS(lchown, "%s, %d, %d"), path, args->uid, args->gid); | ||||
#endif | #endif | ||||
error = kern_fchownat(td, AT_FDCWD, path, UIO_SYSSPACE, args->uid, | error = kern_fchownat(td, AT_FDCWD, path, UIO_SYSSPACE, args->uid, | ||||
args->gid, AT_SYMLINK_NOFOLLOW); | args->gid, AT_SYMLINK_NOFOLLOW); | ||||
LFREEPATH(path); | LFREEPATH(path); | ||||
return (error); | return (error); | ||||
} | } | ||||
#endif | |||||
static int | static int | ||||
convert_fadvice(int advice) | convert_fadvice(int advice) | ||||
{ | { | ||||
switch (advice) { | switch (advice) { | ||||
case LINUX_POSIX_FADV_NORMAL: | case LINUX_POSIX_FADV_NORMAL: | ||||
return (POSIX_FADV_NORMAL); | return (POSIX_FADV_NORMAL); | ||||
case LINUX_POSIX_FADV_RANDOM: | case LINUX_POSIX_FADV_RANDOM: | ||||
Show All 32 Lines | linux_fadvise64_64(struct thread *td, struct linux_fadvise64_64_args *args) | ||||
advice = convert_fadvice(args->advice); | advice = convert_fadvice(args->advice); | ||||
if (advice == -1) | if (advice == -1) | ||||
return (EINVAL); | return (EINVAL); | ||||
return (kern_posix_fadvise(td, args->fd, args->offset, args->len, | return (kern_posix_fadvise(td, args->fd, args->offset, args->len, | ||||
advice)); | advice)); | ||||
} | } | ||||
#endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ | #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ | ||||
#ifdef LINUX_LEGACY_SYSCALLS | |||||
int | int | ||||
linux_pipe(struct thread *td, struct linux_pipe_args *args) | linux_pipe(struct thread *td, struct linux_pipe_args *args) | ||||
{ | { | ||||
int fildes[2]; | int fildes[2]; | ||||
int error; | int error; | ||||
#ifdef DEBUG | #ifdef DEBUG | ||||
if (ldebug(pipe)) | if (ldebug(pipe)) | ||||
printf(ARGS(pipe, "*")); | printf(ARGS(pipe, "*")); | ||||
#endif | #endif | ||||
error = kern_pipe(td, fildes, 0, NULL, NULL); | error = kern_pipe(td, fildes, 0, NULL, NULL); | ||||
if (error != 0) | if (error != 0) | ||||
return (error); | return (error); | ||||
error = copyout(fildes, args->pipefds, sizeof(fildes)); | error = copyout(fildes, args->pipefds, sizeof(fildes)); | ||||
if (error != 0) { | if (error != 0) { | ||||
(void)kern_close(td, fildes[0]); | (void)kern_close(td, fildes[0]); | ||||
(void)kern_close(td, fildes[1]); | (void)kern_close(td, fildes[1]); | ||||
} | } | ||||
return (error); | return (error); | ||||
} | } | ||||
#endif | |||||
int | int | ||||
linux_pipe2(struct thread *td, struct linux_pipe2_args *args) | linux_pipe2(struct thread *td, struct linux_pipe2_args *args) | ||||
{ | { | ||||
int fildes[2]; | int fildes[2]; | ||||
int error, flags; | int error, flags; | ||||
#ifdef DEBUG | #ifdef DEBUG | ||||
▲ Show 20 Lines • Show All 58 Lines • Show Last 20 Lines |