diff options
-rw-r--r-- | libnetfs/file-reparent.c | 41 |
1 files changed, 40 insertions, 1 deletions
diff --git a/libnetfs/file-reparent.c b/libnetfs/file-reparent.c index 832c80ab..095a9232 100644 --- a/libnetfs/file-reparent.c +++ b/libnetfs/file-reparent.c @@ -2,6 +2,8 @@ Copyright (C) 1997 Free Software Foundation + Written by Miles Bader <miles@gnu.ai.mit.edu> + This file is part of the GNU Hurd. The GNU Hurd is free software; you can redistribute it and/or modify @@ -24,5 +26,42 @@ error_t netfs_S_file_reparent (struct protid *cred, mach_port_t parent, mach_port_t *new_file, mach_msg_type_name_t *new_file_type) { - return EOPNOTSUPP; + struct node *node; + struct protid *new_cred; + + if (! cred) + return EOPNOTSUPP; + + node = cred->po->np; + + mutex_lock (&node->lock); + new_cred = + netfs_make_protid (netfs_make_peropen (node, cred->po->openstat, cred->po), + cred->user); + mutex_unlock (&node->lock); + + if (new_cred) + { + /* Remove old shadow root state. */ + if (new_cred->po->shadow_root && new_cred->po->shadow_root != node) + { + mutex_lock (&new_cred->po->shadow_root->lock); + netfs_nput (new_cred->po->shadow_root); + } + if (new_cred->po->shadow_root_parent) + mach_port_deallocate (mach_task_self (), new_cred->po->shadow_root_parent); + + /* And install PARENT instead. */ + new_cred->po->shadow_root = node; + new_cred->po->shadow_root_parent = parent; + + *new_file = ports_get_right (new_cred); + *new_file_type = MACH_MSG_TYPE_MAKE_SEND; + + ports_port_deref (new_cred); + + return 0; + } + else + return errno; } |