commit-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[hurd,commited] hurd: Handle "pid" magical lookup retry


From: Samuel Thibault
Subject: [hurd,commited] hurd: Handle "pid" magical lookup retry
Date: Fri, 28 Dec 2018 22:32:44 +0100

From: Justus Winter <address@hidden>

        * hurd/lookup-retry: Include <unistd.h>.
        (__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 <address@hidden>
+
+       * hurd/lookup-retry: Include <unistd.h>.
+       (__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  <address@hidden>
 
        [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 <string.h>
 #include <_itoa.h>
 #include <eloop-threshold.h>
+#include <unistd.h>
 
 /* 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)
-- 
2.19.2




reply via email to

[Prev in Thread] Current Thread [Next in Thread]