From 065957a3704fd4d900a9d82cbee3c5006ed4d9c9 Mon Sep 17 00:00:00 2001 From: Justus Winter <4winter@informatik.uni-hamburg.de> Date: Fri, 28 Dec 2018 22:31:01 +0100 Subject: hurd: Handle "pid" magical lookup retry * hurd/lookup-retry: Include . (__hurd_file_name_lookup_retry): Keep a ref on last result in `lastdir'. Release it on return. Handle "pid" magical lookup retry. --- ChangeLog | 6 +++++ hurd/lookup-retry.c | 78 ++++++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 71 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index 63ceb48de6..a2170167c7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2018-12-28 Justus Winter <4winter@informatik.uni-hamburg.de> + + * hurd/lookup-retry: Include . + (__hurd_file_name_lookup_retry): Keep a ref on last result in `lastdir'. + Release it on return. Handle "pid" magical lookup retry. + 2018-12-28 Rafal Luzynski [BZ #10496] diff --git a/hurd/lookup-retry.c b/hurd/lookup-retry.c index b596848624..53cacdab15 100644 --- a/hurd/lookup-retry.c +++ b/hurd/lookup-retry.c @@ -25,6 +25,7 @@ #include #include <_itoa.h> #include +#include /* Translate the error from dir_lookup into the error the user sees. */ static inline error_t @@ -59,6 +60,7 @@ __hurd_file_name_lookup_retry (error_t (*use_init_port) error_t err; char *file_name; int nloops; + file_t lastdir = MACH_PORT_NULL; error_t lookup_op (file_t startdir) { @@ -107,14 +109,15 @@ __hurd_file_name_lookup_retry (error_t (*use_init_port) { case FS_RETRY_REAUTH: if (err = reauthenticate (*result)) - return err; + goto out; /* Fall through. */ case FS_RETRY_NORMAL: if (nloops++ >= __eloop_threshold ()) { __mach_port_deallocate (__mach_task_self (), *result); - return ELOOP; + err = ELOOP; + goto out; } /* An empty RETRYNAME indicates we have the final port. */ @@ -180,7 +183,7 @@ __hurd_file_name_lookup_retry (error_t (*use_init_port) if (err) __mach_port_deallocate (__mach_task_self (), *result); - return err; + goto out; } startdir = *result; @@ -195,7 +198,10 @@ __hurd_file_name_lookup_retry (error_t (*use_init_port) if (*result != MACH_PORT_NULL) __mach_port_deallocate (__mach_task_self (), *result); if (nloops++ >= __eloop_threshold ()) - return ELOOP; + { + err = ELOOP; + goto out; + } file_name = &retryname[1]; break; @@ -214,7 +220,8 @@ __hurd_file_name_lookup_retry (error_t (*use_init_port) (*end != '/' && *end != '\0')) { errno = save; - return ENOENT; + err = ENOENT; + goto out; } if (! get_dtable_port) err = EGRATUITOUS; @@ -232,9 +239,12 @@ __hurd_file_name_lookup_retry (error_t (*use_init_port) } errno = save; if (err) - return err; + goto out; if (*end == '\0') - return 0; + { + err = 0; + goto out; + } else { /* Do a normal retry on the remaining components. */ @@ -261,9 +271,12 @@ __hurd_file_name_lookup_retry (error_t (*use_init_port) if (err = __host_info (__mach_host_self (), HOST_BASIC_INFO, (integer_t *) &hostinfo, &hostinfocnt)) - return err; + goto out; if (hostinfocnt != HOST_BASIC_INFO_COUNT) - return EGRATUITOUS; + { + err = EGRATUITOUS; + goto out; + } p = _itoa (hostinfo.cpu_subtype, &retryname[8], 10, 0); *--p = '/'; p = _itoa (hostinfo.cpu_type, &retryname[8], 10, 0); @@ -299,10 +312,11 @@ __hurd_file_name_lookup_retry (error_t (*use_init_port) } case '\0': - return opentty (result); + err = opentty (result); + goto out; case '/': if (err = opentty (&startdir)) - return err; + goto out; strcpy (retryname, &retryname[4]); break; default: @@ -312,14 +326,48 @@ __hurd_file_name_lookup_retry (error_t (*use_init_port) goto bad_magic; break; + case 'p': + if (retryname[1] == 'i' && retryname[2] == 'd' && + (retryname[3] == '/' || retryname[3] == 0)) + { + char *p, buf[1024]; /* XXX */ + size_t len; + p = _itoa (__getpid (), &buf[sizeof buf], 10, 0); + len = &buf[sizeof buf] - p; + memcpy (buf, p, len); + strcpy (buf + len, &retryname[3]); + strcpy (retryname, buf); + + /* Do a normal retry on the remaining components. */ + __mach_port_mod_refs (__mach_task_self (), lastdir, + MACH_PORT_RIGHT_SEND, 1); + startdir = lastdir; + file_name = retryname; + } + else + goto bad_magic; + break; + default: bad_magic: - return EGRATUITOUS; + err = EGRATUITOUS; + goto out; } break; default: - return EGRATUITOUS; + err = EGRATUITOUS; + goto out; + } + + if (MACH_PORT_VALID (*result) && *result != lastdir) + { + if (MACH_PORT_VALID (lastdir)) + __mach_port_deallocate (__mach_task_self (), lastdir); + + lastdir = *result; + __mach_port_mod_refs (__mach_task_self (), lastdir, + MACH_PORT_RIGHT_SEND, 1); } if (startdir != MACH_PORT_NULL) @@ -332,6 +380,10 @@ __hurd_file_name_lookup_retry (error_t (*use_init_port) err = (*use_init_port) (dirport, &lookup_op); } while (! err); +out: + if (MACH_PORT_VALID (lastdir)) + __mach_port_deallocate (__mach_task_self (), lastdir); + return err; } weak_alias (__hurd_file_name_lookup_retry, hurd_file_name_lookup_retry) -- cgit 1.4.1