Track the relative path used to obtain a file handle in the struct peropen.
* libnetfs/netfs.h (struct peropen): New field path. * libnetfs/make-peropen.c (netfs_make_peropen): Initialize path. * libnetfs/release-peropen.c (netfs_release_peropen): Free path. * libnetfs/fsys-getroot.c (netfs_S_fsys_getroot): Initialize path. * libnetfs/dir-lookup.c (netfs_S_dir_lookup): Preserve the path. --- libnetfs/dir-lookup.c | 26 +++++++++++++++++++++++++- libnetfs/fsys-getroot.c | 6 +++++- libnetfs/make-peropen.c | 8 ++++++++ libnetfs/netfs.h | 2 ++ libnetfs/release-peropen.c | 1 + 5 files changed, 41 insertions(+), 2 deletions(-) diff --git a/libnetfs/dir-lookup.c b/libnetfs/dir-lookup.c index f1b6438..10ea2d0 100644 --- a/libnetfs/dir-lookup.c +++ b/libnetfs/dir-lookup.c @@ -1,5 +1,6 @@ /* - Copyright (C) 1995,96,97,98,99,2000,01,02 Free Software Foundation, Inc. + Copyright (C) 1995,96,97,98,99,2000,01,02,13 + Free Software Foundation, Inc. Written by Michael I. Bushnell, p/BSG. This file is part of the GNU Hurd. @@ -46,6 +47,7 @@ netfs_S_dir_lookup (struct protid *diruser, int nsymlinks = 0; struct node *dnp, *np; char *nextname; + char *relpath; error_t error; struct protid *newpi; struct iouser *user; @@ -60,6 +62,11 @@ netfs_S_dir_lookup (struct protid *diruser, while (*filename == '/') filename++; + /* Preserve the path relative to diruser->po->path. */ + relpath = strdup (filename); + if (! relpath) + return ENOMEM; + *retry_port_type = MACH_MSG_TYPE_MAKE_SEND; *do_retry = FS_RETRY_NORMAL; *retry_name = '\0'; @@ -390,6 +397,22 @@ netfs_S_dir_lookup (struct protid *diruser, goto out; } + free (newpi->po->path); + if (diruser->po->path == NULL) + { + /* diruser is the root directory. */ + newpi->po->path = relpath; + relpath = NULL; /* Do not free relpath. */ + } + else + { + newpi->po->path = NULL; + asprintf (&newpi->po->path, "%s/%s", diruser->po->path, relpath); + } + + if (! newpi->po->path) + error = errno; + *retry_port = ports_get_right (newpi); ports_port_deref (newpi); @@ -398,5 +421,6 @@ netfs_S_dir_lookup (struct protid *diruser, netfs_nput (np); if (dnp) netfs_nrele (dnp); + free (relpath); return error; } diff --git a/libnetfs/fsys-getroot.c b/libnetfs/fsys-getroot.c index a1dd5e5..0d80111 100644 --- a/libnetfs/fsys-getroot.c +++ b/libnetfs/fsys-getroot.c @@ -43,7 +43,11 @@ netfs_S_fsys_getroot (mach_port_t cntl, error_t err; struct protid *newpi; mode_t type; - struct peropen peropen_context = { root_parent: dotdot }; + struct peropen peropen_context = + { + root_parent: dotdot, + path: NULL, + }; if (!pt) return EOPNOTSUPP; diff --git a/libnetfs/make-peropen.c b/libnetfs/make-peropen.c index 92f58da..733bfdc 100644 --- a/libnetfs/make-peropen.c +++ b/libnetfs/make-peropen.c @@ -31,6 +31,7 @@ netfs_make_peropen (struct node *np, int flags, struct peropen *context) po->refcnt = 0; po->openstat = flags; po->np = np; + po->path = NULL; if (context) { @@ -47,6 +48,13 @@ netfs_make_peropen (struct node *np, int flags, struct peropen *context) if (po->shadow_root_parent != MACH_PORT_NULL) mach_port_mod_refs (mach_task_self (), po->shadow_root_parent, MACH_PORT_RIGHT_SEND, 1); + + if (context->path) + { + po->path = strdup (context->path); + if (! po->path) + return ENOMEM; + } } netfs_nref (np); diff --git a/libnetfs/netfs.h b/libnetfs/netfs.h index d1ebed0..2b9454a 100644 --- a/libnetfs/netfs.h +++ b/libnetfs/netfs.h @@ -63,6 +63,8 @@ struct peropen mach_port_t shadow_root_parent; /* If in a shadow tree, its root node in this translator. */ struct node *shadow_root; + + char *path; }; /* A unique one of these exists for each node currently in use. */ diff --git a/libnetfs/release-peropen.c b/libnetfs/release-peropen.c index 3e65099..d4d3574 100644 --- a/libnetfs/release-peropen.c +++ b/libnetfs/release-peropen.c @@ -41,6 +41,7 @@ netfs_release_peropen (struct peropen *po) netfs_nput (po->np); + free (po->path); free (po); } } -- 1.7.10.4