summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authored <ed@FreeBSD.org>2011-11-19 07:19:37 +0000
committered <ed@FreeBSD.org>2011-11-19 07:19:37 +0000
commit98496492d6c3c48d2e394d6ba846b0d07cc82364 (patch)
tree8641800079e709e832b6280443d6ef6d6122c7ac
parent914a7cfed10dc2338122d41333d3f6004194492c (diff)
downloadFreeBSD-src-98496492d6c3c48d2e394d6ba846b0d07cc82364.zip
FreeBSD-src-98496492d6c3c48d2e394d6ba846b0d07cc82364.tar.gz
Make the Linux *at() calls a bit more complete.
Properly support: - AT_EACCESS for faccessat(), - AT_SYMLINK_FOLLOW for linkat().
-rw-r--r--sys/amd64/linux32/syscalls.master4
-rw-r--r--sys/compat/linux/linux_file.c28
-rw-r--r--sys/compat/linux/linux_file.h2
-rw-r--r--sys/i386/linux/syscalls.master4
4 files changed, 20 insertions, 18 deletions
diff --git a/sys/amd64/linux32/syscalls.master b/sys/amd64/linux32/syscalls.master
index 1658b4e..1c09084 100644
--- a/sys/amd64/linux32/syscalls.master
+++ b/sys/amd64/linux32/syscalls.master
@@ -483,14 +483,14 @@
302 AUE_RENAMEAT STD { int linux_renameat(l_int olddfd, const char *oldname, \
l_int newdfd, const char *newname); }
303 AUE_LINKAT STD { int linux_linkat(l_int olddfd, const char *oldname, \
- l_int newdfd, const char *newname, l_int flags); }
+ l_int newdfd, const char *newname, l_int flag); }
304 AUE_SYMLINKAT STD { int linux_symlinkat(const char *oldname, l_int newdfd, \
const char *newname); }
305 AUE_READLINKAT STD { int linux_readlinkat(l_int dfd, const char *path, \
char *buf, l_int bufsiz); }
306 AUE_FCHMODAT STD { int linux_fchmodat(l_int dfd, const char *filename, \
l_mode_t mode); }
-307 AUE_FACCESSAT STD { int linux_faccessat(l_int dfd, const char *filename, l_int amode); }
+307 AUE_FACCESSAT STD { int linux_faccessat(l_int dfd, const char *filename, l_int amode, int flag); }
308 AUE_NULL STD { int linux_pselect6(void); }
309 AUE_NULL STD { int linux_ppoll(void); }
310 AUE_NULL STD { int linux_unshare(void); }
diff --git a/sys/compat/linux/linux_file.c b/sys/compat/linux/linux_file.c
index 97e4e04..ffa2282 100644
--- a/sys/compat/linux/linux_file.c
+++ b/sys/compat/linux/linux_file.c
@@ -584,8 +584,10 @@ int
linux_faccessat(struct thread *td, struct linux_faccessat_args *args)
{
char *path;
- int error, dfd;
+ int error, dfd, flag;
+ if (args->flag & ~LINUX_AT_EACCESS)
+ return (EINVAL);
/* linux convention */
if (args->amode & ~(F_OK | X_OK | W_OK | R_OK))
return (EINVAL);
@@ -598,8 +600,8 @@ linux_faccessat(struct thread *td, struct linux_faccessat_args *args)
printf(ARGS(access, "%s, %d"), path, args->amode);
#endif
- error = kern_accessat(td, dfd, path, UIO_SYSSPACE, 0 /* XXX */,
- args->amode);
+ flag = (args->flag & LINUX_AT_EACCESS) == 0 ? 0 : AT_EACCESS;
+ error = kern_accessat(td, dfd, path, UIO_SYSSPACE, flag, args->amode);
LFREEPATH(path);
return (error);
@@ -982,13 +984,9 @@ int
linux_linkat(struct thread *td, struct linux_linkat_args *args)
{
char *path, *to;
- int error, olddfd, newdfd;
+ int error, olddfd, newdfd, follow;
- /*
- * They really introduced flags argument which is forbidden to
- * use.
- */
- if (args->flags != 0)
+ if (args->flag & ~LINUX_AT_SYMLINK_FOLLOW)
return (EINVAL);
olddfd = (args->olddfd == LINUX_AT_FDCWD) ? AT_FDCWD : args->olddfd;
@@ -1004,10 +1002,12 @@ linux_linkat(struct thread *td, struct linux_linkat_args *args)
#ifdef DEBUG
if (ldebug(linkat))
printf(ARGS(linkat, "%i, %s, %i, %s, %i"), args->olddfd, path,
- args->newdfd, to, args->flags);
+ args->newdfd, to, args->flag);
#endif
- error = kern_linkat(td, olddfd, newdfd, path, to, UIO_SYSSPACE, FOLLOW);
+ follow = (args->flag & LINUX_AT_SYMLINK_FOLLOW) == 0 ? NOFOLLOW :
+ FOLLOW;
+ error = kern_linkat(td, olddfd, newdfd, path, to, UIO_SYSSPACE, follow);
LFREEPATH(path);
LFREEPATH(to);
return (error);
@@ -1493,7 +1493,7 @@ int
linux_fchownat(struct thread *td, struct linux_fchownat_args *args)
{
char *path;
- int error, dfd, follow;
+ int error, dfd, flag;
if (args->flag & ~LINUX_AT_SYMLINK_NOFOLLOW)
return (EINVAL);
@@ -1506,10 +1506,10 @@ linux_fchownat(struct thread *td, struct linux_fchownat_args *args)
printf(ARGS(fchownat, "%s, %d, %d"), path, args->uid, args->gid);
#endif
- follow = (args->flag & LINUX_AT_SYMLINK_NOFOLLOW) == 0 ? 0 :
+ flag = (args->flag & LINUX_AT_SYMLINK_NOFOLLOW) == 0 ? 0 :
AT_SYMLINK_NOFOLLOW;
error = kern_fchownat(td, dfd, path, UIO_SYSSPACE, args->uid, args->gid,
- follow);
+ flag);
LFREEPATH(path);
return (error);
}
diff --git a/sys/compat/linux/linux_file.h b/sys/compat/linux/linux_file.h
index e229cb6..d0d95ac 100644
--- a/sys/compat/linux/linux_file.h
+++ b/sys/compat/linux/linux_file.h
@@ -31,6 +31,8 @@
#define LINUX_AT_FDCWD -100
#define LINUX_AT_SYMLINK_NOFOLLOW 0x100
+#define LINUX_AT_EACCESS 0x200
#define LINUX_AT_REMOVEDIR 0x200
+#define LINUX_AT_SYMLINK_FOLLOW 0x400
#endif /* !_LINUX_FILE_H_ */
diff --git a/sys/i386/linux/syscalls.master b/sys/i386/linux/syscalls.master
index 2cf4942..7e7965f 100644
--- a/sys/i386/linux/syscalls.master
+++ b/sys/i386/linux/syscalls.master
@@ -493,14 +493,14 @@
302 AUE_RENAMEAT STD { int linux_renameat(l_int olddfd, const char *oldname, \
l_int newdfd, const char *newname); }
303 AUE_LINKAT STD { int linux_linkat(l_int olddfd, const char *oldname, \
- l_int newdfd, const char *newname, l_int flags); }
+ l_int newdfd, const char *newname, l_int flag); }
304 AUE_SYMLINKAT STD { int linux_symlinkat(const char *oldname, l_int newdfd, \
const char *newname); }
305 AUE_READLINKAT STD { int linux_readlinkat(l_int dfd, const char *path, \
char *buf, l_int bufsiz); }
306 AUE_FCHMODAT STD { int linux_fchmodat(l_int dfd, const char *filename, \
l_mode_t mode); }
-307 AUE_FACCESSAT STD { int linux_faccessat(l_int dfd, const char *filename, l_int amode); }
+307 AUE_FACCESSAT STD { int linux_faccessat(l_int dfd, const char *filename, l_int amode, l_int flag); }
308 AUE_NULL STD { int linux_pselect6(void); }
309 AUE_NULL STD { int linux_ppoll(void); }
310 AUE_NULL STD { int linux_unshare(void); }
OpenPOWER on IntegriCloud