PERFORCE change 120925 for review
Roman Divacky
rdivacky at FreeBSD.org
Mon Jun 4 19:05:08 UTC 2007
http://perforce.freebsd.org/chv.cgi?CH=120925
Change 120925 by rdivacky at rdivacky_witten on 2007/06/04 19:04:41
Modify kern_alternate_path() to take dirfd argument as this is
needed for linuxulator. Use it as such for *at syscalls.
Finally those functions work reliably.
Affected files ...
.. //depot/projects/soc2007/rdivacky/linux_at/sys/amd64/linux32/linux32_sysvec.c#3 edit
.. //depot/projects/soc2007/rdivacky/linux_at/sys/compat/linux/linux_file.c#9 edit
.. //depot/projects/soc2007/rdivacky/linux_at/sys/compat/linux/linux_stats.c#8 edit
.. //depot/projects/soc2007/rdivacky/linux_at/sys/compat/linux/linux_uid16.c#2 edit
.. //depot/projects/soc2007/rdivacky/linux_at/sys/compat/linux/linux_util.c#2 edit
.. //depot/projects/soc2007/rdivacky/linux_at/sys/compat/linux/linux_util.h#2 edit
.. //depot/projects/soc2007/rdivacky/linux_at/sys/compat/svr4/svr4_sysvec.c#2 edit
.. //depot/projects/soc2007/rdivacky/linux_at/sys/i386/ibcs2/ibcs2_util.c#2 edit
.. //depot/projects/soc2007/rdivacky/linux_at/sys/i386/linux/linux_sysvec.c#2 edit
.. //depot/projects/soc2007/rdivacky/linux_at/sys/kern/vfs_lookup.c#5 edit
.. //depot/projects/soc2007/rdivacky/linux_at/sys/sys/syscallsubr.h#8 edit
Differences ...
==== //depot/projects/soc2007/rdivacky/linux_at/sys/amd64/linux32/linux32_sysvec.c#3 (text+ko) ====
@@ -43,6 +43,7 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/exec.h>
+#include <sys/fcntl.h>
#include <sys/imgact.h>
#include <sys/imgact_elf.h>
#include <sys/kernel.h>
@@ -787,7 +788,7 @@
*/
if ((error = exec_shell_imgact(imgp)) == 0) {
linux_emul_convpath(FIRST_THREAD_IN_PROC(imgp->proc),
- imgp->interpreter_name, UIO_SYSSPACE, &rpath, 0);
+ imgp->interpreter_name, UIO_SYSSPACE, &rpath, 0, AT_FDCWD);
if (rpath != NULL) {
len = strlen(rpath) + 1;
==== //depot/projects/soc2007/rdivacky/linux_at/sys/compat/linux/linux_file.c#9 (text+ko) ====
@@ -183,33 +183,26 @@
int
linux_openat(struct thread *td, struct linux_openat_args *args)
{
- char *newpath, *path;
- int error, dirfd;
+ char *path;
+ int dfd;
- path = malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
- error = copyinstr(args->filename, path, MAXPATHLEN, NULL);
- if (error) {
- free(path, M_TEMP);
- return (error);
- }
+ if (args->dfd == LINUX_AT_FDCWD)
+ dfd = AT_FDCWD;
+ else
+ dfd = args->dfd;
if (args->flags & LINUX_O_CREAT)
- LCONVPATH_SEG(td, path, &newpath, 1, UIO_SYSSPACE);
+ LCONVPATH_AT(td, args->filename, &path, 1, dfd);
else
- LCONVPATH_SEG(td, path, &newpath, 0, UIO_SYSSPACE);
- free(path, M_TEMP);
+ LCONVPATH_AT(td, args->filename, &path, 0, dfd);
#ifdef DEBUG
if (ldebug(openat))
+#endif
printf(ARGS(openat, "%i, %s, 0x%x, 0x%x"), args->dfd,
- newpath, args->flags, args->mode);
-#endif
- if (args->dfd == LINUX_AT_FDCWD)
- dirfd = AT_FDCWD;
- else
- dirfd = args->dfd;
+ path, args->flags, args->mode);
- return linux_common_open(td, path, args->flags, args->mode, dirfd);
+ return linux_common_open(td, path, args->flags, args->mode, dfd);
}
int
@@ -587,18 +580,18 @@
if (args->mode & ~(F_OK | X_OK | W_OK | R_OK))
return (EINVAL);
- LCONVPATHEXIST(td, args->filename, &path);
+ if (args->dfd == LINUX_AT_FDCWD)
+ dfd = -1;
+ else
+ dfd = args->dfd;
+
+ LCONVPATHEXIST_AT(td, args->filename, &path, dfd);
#ifdef DEBUG
if (ldebug(access))
printf(ARGS(access, "%s, %d"), path, args->mode);
#endif
- if (args->dfd == LINUX_AT_FDCWD)
- dfd = -1;
- else
- dfd = args->dfd;
-
error = kern_accessat(td, path, UIO_SYSSPACE, args->mode, dfd);
LFREEPATH(path);
@@ -639,25 +632,25 @@
if (args->flag & ~LINUX_AT_REMOVEDIR)
return (EINVAL);
- LCONVPATHEXIST(td, args->pathname, &path);
+ if (args->dfd == LINUX_AT_FDCWD)
+ dfd = AT_FDCWD;
+ else
+ dfd = args->dfd;
+
+ LCONVPATHEXIST_AT(td, args->pathname, &path, dfd);
#ifdef DEBUG
if (ldebug(unlinkat))
printf(ARGS(unlinkat, "%s"), path);
#endif
- if (args->dfd == LINUX_AT_FDCWD)
- dfd = AT_FDCWD;
- else
- dfd = args->dfd;
-
if (args->flag & LINUX_AT_REMOVEDIR)
error = kern_rmdirat(td, path, UIO_SYSSPACE, dfd);
else
error = kern_unlinkat(td, path, UIO_SYSSPACE, dfd);
if (error == EPERM)
/* Introduce POSIX noncompliant behaviour of Linux */
- if (kern_stat(td, path, UIO_SYSSPACE, &st) == 0)
+ if (kern_statat(td, path, UIO_SYSSPACE, &st, dfd) == 0)
if (S_ISDIR(st.st_mode))
error = EISDIR;
LFREEPATH(path);
@@ -703,17 +696,17 @@
char *path;
int error, dfd;
- LCONVPATHEXIST(td, args->filename, &path);
+ if (args->dfd == LINUX_AT_FDCWD)
+ dfd = AT_FDCWD;
+ else
+ dfd = args->dfd;
+
+ LCONVPATHEXIST_AT(td, args->filename, &path, dfd);
#ifdef DEBUG
if (ldebug(fchmodat))
printf(ARGS(fchmodat, "%s, %d"), path, args->mode);
#endif
-
- if (args->dfd == LINUX_AT_FDCWD)
- dfd = AT_FDCWD;
- else
- dfd = args->dfd;
error = kern_chmodat(td, path, UIO_SYSSPACE, args->mode, dfd);
LFREEPATH(path);
@@ -761,7 +754,7 @@
LCONVPATHEXIST(td, args->from, &from);
/* Expand LCONVPATHCREATE so that `from' can be freed on errors */
- error = linux_emul_convpath(td, args->to, UIO_USERSPACE, &to, 1);
+ error = linux_emul_convpath(td, args->to, UIO_USERSPACE, &to, 1, AT_FDCWD);
if (to == NULL) {
LFREEPATH(from);
return (error);
@@ -785,7 +778,7 @@
LCONVPATHEXIST(td, args->path, &path);
/* Expand LCONVPATHCREATE so that `path' can be freed on errors */
- error = linux_emul_convpath(td, args->to, UIO_USERSPACE, &to, 1);
+ error = linux_emul_convpath(td, args->to, UIO_USERSPACE, &to, 1, AT_FDCWD);
if (to == NULL) {
LFREEPATH(path);
return (error);
@@ -807,9 +800,14 @@
char *path, *to;
int error, dfd;
- LCONVPATHEXIST(td, args->oldname, &path);
+ if (args->newdfd == LINUX_AT_FDCWD)
+ dfd = AT_FDCWD;
+ else
+ dfd = args->newdfd;
+
+ LCONVPATHEXIST_AT(td, args->oldname, &path, dfd);
/* Expand LCONVPATHCREATE so that `path' can be freed on errors */
- error = linux_emul_convpath(td, args->newname, UIO_USERSPACE, &to, 1);
+ error = linux_emul_convpath(td, args->newname, UIO_USERSPACE, &to, 1, dfd);
if (to == NULL) {
LFREEPATH(path);
return (error);
@@ -819,10 +817,6 @@
if (ldebug(symlinkat))
printf(ARGS(symlinkat, "%s, %s"), path, to);
#endif
- if (args->newdfd == LINUX_AT_FDCWD)
- dfd = AT_FDCWD;
- else
- dfd = args->newdfd;
error = kern_symlinkat(td, path, to, UIO_SYSSPACE, dfd);
LFREEPATH(path);
@@ -855,7 +849,12 @@
char *name;
int error, dfd;
- LCONVPATHEXIST(td, args->path, &name);
+ if (args->dfd == LINUX_AT_FDCWD)
+ dfd = AT_FDCWD;
+ else
+ dfd = args->dfd;
+
+ LCONVPATHEXIST_AT(td, args->path, &name, dfd);
#ifdef DEBUG
if (ldebug(readlinkat))
@@ -863,11 +862,6 @@
args->bufsiz);
#endif
- if (args->dfd == LINUX_AT_FDCWD)
- dfd = AT_FDCWD;
- else
- dfd = args->dfd;
-
error = kern_readlinkat(td, name, UIO_SYSSPACE, args->buf, UIO_USERSPACE,
args->bufsiz, dfd);
LFREEPATH(name);
@@ -914,7 +908,7 @@
LCONVPATHEXIST(td, args->path, &path);
/* Expand LCONVPATHCREATE so that `path' can be freed on errors */
- error = linux_emul_convpath(td, args->to, UIO_USERSPACE, &to, 1);
+ error = linux_emul_convpath(td, args->to, UIO_USERSPACE, &to, 1, AT_FDCWD);
if (to == NULL) {
LFREEPATH(path);
return (error);
@@ -943,9 +937,19 @@
if (args->flags != 0)
return (EINVAL);
- LCONVPATHEXIST(td, args->oldname, &path);
+ if (args->olddfd == LINUX_AT_FDCWD)
+ olddfd = AT_FDCWD;
+ else
+ olddfd = args->olddfd;
+
+ if (args->newdfd == LINUX_AT_FDCWD)
+ newdfd = AT_FDCWD;
+ else
+ newdfd = args->newdfd;
+
+ LCONVPATHEXIST_AT(td, args->oldname, &path, olddfd);
/* Expand LCONVPATHCREATE so that `path' can be freed on errors */
- error = linux_emul_convpath(td, args->newname, UIO_USERSPACE, &to, 1);
+ error = linux_emul_convpath(td, args->newname, UIO_USERSPACE, &to, 1, newdfd);
if (to == NULL) {
LFREEPATH(path);
return (error);
@@ -956,16 +960,7 @@
printf(ARGS(linkat, "%i, %s, %i, %s, %i"), args->olddfd, path,
args->newdfd, to, args->flags);
#endif
- if (args->olddfd == LINUX_AT_FDCWD)
- olddfd = AT_FDCWD;
- else
- olddfd = args->olddfd;
- if (args->newdfd == LINUX_AT_FDCWD)
- newdfd = AT_FDCWD;
- else
- newdfd = args->newdfd;
-
error = kern_linkat(td, path, to, UIO_SYSSPACE, olddfd, newdfd);
LFREEPATH(path);
LFREEPATH(to);
@@ -1446,17 +1441,17 @@
if (args->flag & ~LINUX_AT_SYMLINK_NOFOLLOW)
return (EINVAL);
- LCONVPATHEXIST(td, args->filename, &path);
+ if (args->dfd == LINUX_AT_FDCWD)
+ dfd = AT_FDCWD;
+ else
+ dfd = args->dfd;
+
+ LCONVPATHEXIST_AT(td, args->filename, &path, dfd);
#ifdef DEBUG
if (ldebug(fchownat))
printf(ARGS(fchownat, "%s, %d, %d"), path, args->uid, args->gid);
#endif
-
- if (args->dfd == LINUX_AT_FDCWD)
- dfd = AT_FDCWD;
- else
- dfd = args->dfd;
if (args->flag & LINUX_AT_SYMLINK_NOFOLLOW)
error = kern_lchownat(td, path, UIO_SYSSPACE, args->uid, args->gid, dfd);
==== //depot/projects/soc2007/rdivacky/linux_at/sys/compat/linux/linux_stats.c#8 (text+ko) ====
@@ -608,18 +608,18 @@
if (args->flag & ~LINUX_AT_SYMLINK_NOFOLLOW)
return (EINVAL);
- LCONVPATHEXIST(td, args->pathname, &path);
+ if (args->dfd == LINUX_AT_FDCWD)
+ dfd = AT_FDCWD;
+ else
+ dfd = args->dfd;
+
+ LCONVPATHEXIST_AT(td, args->pathname, &path, dfd);
#ifdef DEBUG
if (ldebug(fstatat64))
printf(ARGS(fstatat64, "%i, %s, %i"), args->dfd, path, args->flag);
#endif
- if (args->dfd == LINUX_AT_FDCWD)
- dfd = AT_FDCWD;
- else
- dfd = args->dfd;
-
if (args->flag & LINUX_AT_SYMLINK_NOFOLLOW)
error = kern_lstatat(td, path, UIO_SYSSPACE, &buf, dfd);
else
==== //depot/projects/soc2007/rdivacky/linux_at/sys/compat/linux/linux_uid16.c#2 (text+ko) ====
@@ -29,6 +29,7 @@
#include "opt_compat.h"
+#include <sys/fcntl.h>
#include <sys/param.h>
#include <sys/lock.h>
#include <sys/malloc.h>
==== //depot/projects/soc2007/rdivacky/linux_at/sys/compat/linux/linux_util.c#2 (text+ko) ====
@@ -36,6 +36,7 @@
#include <sys/param.h>
#include <sys/bus.h>
+#include <sys/fcntl.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/linker_set.h>
@@ -65,16 +66,17 @@
* named file, i.e. we check if the directory it should be in exists.
*/
int
-linux_emul_convpath(td, path, pathseg, pbuf, cflag)
+linux_emul_convpath(td, path, pathseg, pbuf, cflag, dfd)
struct thread *td;
char *path;
enum uio_seg pathseg;
char **pbuf;
int cflag;
+ int dfd;
{
- return (kern_alternate_path(td, linux_emul_path, path, pathseg, pbuf,
- cflag));
+ return kern_alternate_path(td, linux_emul_path, path, pathseg, pbuf,
+ cflag, dfd);
}
void
==== //depot/projects/soc2007/rdivacky/linux_at/sys/compat/linux/linux_util.h#2 (text+ko) ====
@@ -51,22 +51,23 @@
extern const char linux_emul_path[];
-int linux_emul_convpath(struct thread *, char *, enum uio_seg, char **, int);
+int linux_emul_convpath(struct thread *, char *, enum uio_seg, char **, int, int);
-#define LCONVPATH_SEG(td, upath, pathp, i, seg) \
+#define LCONVPATH_AT(td, upath, pathp, i, dfd) \
do { \
int _error; \
\
- _error = linux_emul_convpath(td, upath, seg, \
- pathp, i); \
+ _error = linux_emul_convpath(td, upath, UIO_USERSPACE, \
+ pathp, i, dfd); \
if (*(pathp) == NULL) \
return (_error); \
} while (0)
#define LCONVPATH(td, upath, pathp, i) \
- LCONVPATH_SEG(td, upath, pathp, i, UIO_USERSPACE)
+ LCONVPATH_AT(td, upath, pathp, i, AT_FDCWD)
#define LCONVPATHEXIST(td, upath, pathp) LCONVPATH(td, upath, pathp, 0)
+#define LCONVPATHEXIST_AT(td, upath, pathp, dfd) LCONVPATH_AT(td, upath, pathp, 0, dfd)
#define LCONVPATHCREAT(td, upath, pathp) LCONVPATH(td, upath, pathp, 1)
#define LFREEPATH(path) free(path, M_TEMP)
==== //depot/projects/soc2007/rdivacky/linux_at/sys/compat/svr4/svr4_sysvec.c#2 (text+ko) ====
@@ -44,6 +44,7 @@
#include <sys/sysent.h>
#include <sys/imgact.h>
#include <sys/imgact_elf.h>
+#include <sys/fcntl.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/module.h>
@@ -258,7 +259,7 @@
{
return (kern_alternate_path(td, svr4_emul_path, path, pathseg, pbuf,
- create));
+ create, AT_FDCWD));
}
static int
==== //depot/projects/soc2007/rdivacky/linux_at/sys/i386/ibcs2/ibcs2_util.c#2 (text+ko) ====
@@ -32,6 +32,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/sys/i386/ibcs2/ibcs2_util.c,v 1.19 2005/02/07 22:02:18 jhb Exp $");
+#include <sys/fcntl.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/syscallsubr.h>
@@ -55,5 +56,5 @@
{
return (kern_alternate_path(td, ibcs2_emul_path, path, pathseg, pbuf,
- cflag));
+ cflag, AT_FDCWD));
}
==== //depot/projects/soc2007/rdivacky/linux_at/sys/i386/linux/linux_sysvec.c#2 (text+ko) ====
@@ -32,6 +32,7 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/exec.h>
+#include <sys/fcntl.h>
#include <sys/imgact.h>
#include <sys/imgact_aout.h>
#include <sys/imgact_elf.h>
@@ -775,7 +776,7 @@
*/
if ((error = exec_shell_imgact(imgp)) == 0) {
linux_emul_convpath(FIRST_THREAD_IN_PROC(imgp->proc),
- imgp->interpreter_name, UIO_SYSSPACE, &rpath, 0);
+ imgp->interpreter_name, UIO_SYSSPACE, &rpath, 0, AT_FDCWD);
if (rpath != NULL) {
len = strlen(rpath) + 1;
==== //depot/projects/soc2007/rdivacky/linux_at/sys/kern/vfs_lookup.c#5 (text+ko) ====
@@ -44,6 +44,7 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
+#include <sys/fcntl.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/namei.h>
@@ -1004,12 +1005,13 @@
*/
int
kern_alternate_path(struct thread *td, const char *prefix, char *path,
- enum uio_seg pathseg, char **pathbuf, int create)
+ enum uio_seg pathseg, char **pathbuf, int create, int dirfd)
{
struct nameidata nd, ndroot;
char *ptr, *buf, *cp;
size_t len, sz;
int error;
+ struct vnode *dir_vn;
buf = (char *) malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
*pathbuf = buf;
@@ -1042,6 +1044,18 @@
goto keeporig;
}
+ if (dirfd == AT_FDCWD)
+ dir_vn = NULL;
+ else {
+ /*
+ * we want the original because the "prefix"
+ * is included in the already opened dirfd
+ */
+ bcopy(ptr, buf, len);
+ return (0);
+ }
+
+
/*
* We know that there is a / somewhere in this pathname.
* Search backwards for it, to find the file's parent dir
@@ -1054,13 +1068,13 @@
for (cp = &ptr[len] - 1; *cp != '/'; cp--);
*cp = '\0';
- NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE, UIO_SYSSPACE, buf, td);
+ NDINIT_AT(&nd, LOOKUP, FOLLOW | MPSAFE, UIO_SYSSPACE, buf, td, dir_vn);
error = namei(&nd);
*cp = '/';
if (error != 0)
goto keeporig;
} else {
- NDINIT(&nd, LOOKUP, FOLLOW | MPSAFE, UIO_SYSSPACE, buf, td);
+ NDINIT_AT(&nd, LOOKUP, FOLLOW | MPSAFE, UIO_SYSSPACE, buf, td, dir_vn);
error = namei(&nd);
if (error != 0)
==== //depot/projects/soc2007/rdivacky/linux_at/sys/sys/syscallsubr.h#8 (text+ko) ====
@@ -60,7 +60,7 @@
int kern_adjtime(struct thread *td, struct timeval *delta,
struct timeval *olddelta);
int kern_alternate_path(struct thread *td, const char *prefix, char *path,
- enum uio_seg pathseg, char **pathbuf, int create);
+ enum uio_seg pathseg, char **pathbuf, int create, int dirfd);
int kern_bind(struct thread *td, int fd, struct sockaddr *sa);
int kern_chdir(struct thread *td, char *path, enum uio_seg pathseg);
int kern_chmod(struct thread *td, char *path, enum uio_seg pathseg,
More information about the p4-projects
mailing list