commit-hurd
[Top][All Lists]
Advanced

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

[hurd,commited] Hurd: Implement chdir support in posix_spawn


From: Samuel Thibault
Subject: [hurd,commited] Hurd: Implement chdir support in posix_spawn
Date: Sat, 10 Nov 2018 11:59:14 +0100

This fixes build-many-glibcs.py on i686-gnu.

Thanks Florian Weimer for the initial version.

* sysdeps/mach/hurd/spawni.c (__spawni): Add ccwdir port. Test and use
it, free it if needed.
(reauthenticate): Test and use ccwdir.
(child_init_port): In non-resetids case, test and use ccwdir.
(child_chdir): New nested function to set ccwdir.
---
 ChangeLog                  |  8 ++++
 sysdeps/mach/hurd/spawni.c | 87 +++++++++++++++++++++++++++++++++-----
 2 files changed, 85 insertions(+), 10 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index e43fd3e987..0b7752345b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2018-11-10  Samuel Thibault  <address@hidden>
+
+       * sysdeps/mach/hurd/spawni.c (__spawni): Add ccwdir port. Test and use
+       it, free it if needed.
+       (reauthenticate): Test and use ccwdir.
+       (child_init_port): In non-resetids case, test and use ccwdir.
+       (child_chdir): New nested function to set ccwdir.
+
 2018-11-09  Martin Sebor  <address@hidden>
 
        * include/libc-symbols.h (__attribute_copy__): Define macro unless
diff --git a/sysdeps/mach/hurd/spawni.c b/sysdeps/mach/hurd/spawni.c
index 9351c13e56..4fd0cdd520 100644
--- a/sysdeps/mach/hurd/spawni.c
+++ b/sysdeps/mach/hurd/spawni.c
@@ -113,6 +113,9 @@ __spawni (pid_t *pid, const char *file,
   struct hurd_userlink *ulink_dtable = NULL;
   struct hurd_sigstate *ss;
 
+  /* Child current working dir */
+  file_t ccwdir = MACH_PORT_NULL;
+
   /* For POSIX_SPAWN_RESETIDS, this reauthenticates our root/current
      directory ports with the new AUTH port.  */
   file_t rcrdir = MACH_PORT_NULL, rcwdir = MACH_PORT_NULL;
@@ -123,16 +126,25 @@ __spawni (pid_t *pid, const char *file,
       if (*result != MACH_PORT_NULL)
        return 0;
       ref = __mach_reply_port ();
-      err = HURD_PORT_USE
-       (&_hurd_ports[which],
-        ({
-          err = __io_reauthenticate (port, ref, MACH_MSG_TYPE_MAKE_SEND);
-          if (!err)
-            err = __auth_user_authenticate (auth,
-                                            ref, MACH_MSG_TYPE_MAKE_SEND,
-                                            result);
-          err;
-        }));
+      if (which == INIT_PORT_CWDIR && ccwdir != MACH_PORT_NULL)
+       {
+         err = __io_reauthenticate (ccwdir, ref, MACH_MSG_TYPE_MAKE_SEND);
+         if (!err)
+           err = __auth_user_authenticate (auth,
+                                           ref, MACH_MSG_TYPE_MAKE_SEND,
+                                           result);
+       }
+      else
+       err = HURD_PORT_USE
+         (&_hurd_ports[which],
+          ({
+            err = __io_reauthenticate (port, ref, MACH_MSG_TYPE_MAKE_SEND);
+            if (!err)
+              err = __auth_user_authenticate (auth,
+                                              ref, MACH_MSG_TYPE_MAKE_SEND,
+                                              result);
+            err;
+          }));
       __mach_port_destroy (__mach_task_self (), ref);
       return err;
     }
@@ -177,6 +189,14 @@ __spawni (pid_t *pid, const char *file,
            return (reauthenticate (INIT_PORT_CWDIR, &rcwdir)
                    ?: (*operate) (rcwdir));
          }
+      else
+       switch (which)
+         {
+         case INIT_PORT_CWDIR:
+           if (ccwdir != MACH_PORT_NULL)
+             return (*operate) (ccwdir);
+           break;
+         }
       assert (which != INIT_PORT_PROC);
       return _hurd_ports_use (which, operate);
     }
@@ -205,6 +225,40 @@ __spawni (pid_t *pid, const char *file,
       return __hurd_file_name_lookup (&child_init_port, &child_fd, 0,
                                      file, oflag, mode, result);
     }
+  auto error_t child_chdir (const char *name)
+    {
+      file_t new_ccwdir;
+
+      /* Append trailing "/." to directory name to force ENOTDIR if
+        it's not a directory and EACCES if we don't have search
+        permission.  */
+      len = strlen (name);
+      const char *lookup = name;
+      if (len >= 2 && name[len - 2] == '/' && name[len - 1] == '.')
+       lookup = name;
+      else if (len == 0)
+       /* Special-case empty file name according to POSIX.  */
+       return __hurd_fail (ENOENT);
+      else
+       {
+         char *n = alloca (len + 3);
+         memcpy (n, name, len);
+         n[len] = '/';
+         n[len + 1] = '.';
+         n[len + 2] = '\0';
+         lookup = n;
+       }
+
+      error_t err = child_lookup (lookup, 0, 0, &new_ccwdir);
+      if (!err)
+       {
+         if (ccwdir != MACH_PORT_NULL)
+           __mach_port_deallocate (__mach_task_self (), ccwdir);
+         ccwdir = new_ccwdir;
+       }
+
+      return err;
+    }
 
 
   /* Do this once.  */
@@ -485,6 +539,10 @@ __spawni (pid_t *pid, const char *file,
              dtable_cells[fd] = NULL;
              break;
            }
+
+         case spawn_do_chdir:
+           err = child_chdir (action->action.chdir_action.path);
+           break;
          }
 
        if (err)
@@ -708,6 +766,11 @@ __spawni (pid_t *pid, const char *file,
                ports[i] = rcwdir;
                continue;
              }
+           if (ccwdir != MACH_PORT_NULL)
+             {
+               ports[i] = ccwdir;
+               continue;
+             }
            break;
          }
        ports[i] = _hurd_port_get (&_hurd_ports[i], &ulink_ports[i]);
@@ -748,6 +811,8 @@ __spawni (pid_t *pid, const char *file,
          case INIT_PORT_CWDIR:
            if (flags & POSIX_SPAWN_RESETIDS)
              continue;
+           if (ccwdir != MACH_PORT_NULL)
+             continue;
            break;
          }
        _hurd_port_free (&_hurd_ports[i], &ulink_ports[i], ports[i]);
@@ -773,6 +838,8 @@ __spawni (pid_t *pid, const char *file,
     }
   __mach_port_deallocate (__mach_task_self (), auth);
   __mach_port_deallocate (__mach_task_self (), proc);
+  if (ccwdir != MACH_PORT_NULL)
+    __mach_port_deallocate (__mach_task_self (), ccwdir);
   if (rcrdir != MACH_PORT_NULL)
     __mach_port_deallocate (__mach_task_self (), rcrdir);
   if (rcwdir != MACH_PORT_NULL)
-- 
2.19.1




reply via email to

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