diff options
author | Michael I. Bushnell <mib@gnu.org> | 1994-07-18 20:21:51 +0000 |
---|---|---|
committer | Michael I. Bushnell <mib@gnu.org> | 1994-07-18 20:21:51 +0000 |
commit | e24f6264b3c831b14fc524417c7bb83e4ecf18d9 (patch) | |
tree | cf431ab1bbd71dc9545d5e967290ba8506df7142 /libdiskfs | |
parent | 1a3f7fa138e892754fcb034337815ce110a7a949 (diff) |
Formerly file-inv-trans.c.~2~
Diffstat (limited to 'libdiskfs')
-rw-r--r-- | libdiskfs/file-inv-trans.c | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/libdiskfs/file-inv-trans.c b/libdiskfs/file-inv-trans.c index 4a6752bb..6838a4a6 100644 --- a/libdiskfs/file-inv-trans.c +++ b/libdiskfs/file-inv-trans.c @@ -17,3 +17,77 @@ #include "priv.h" #include "fs_S.h" + +/* Implement fs.defs:file_invoke_translator as described in <hurd/fs.defs>. */ +kern_return_t +diskfs_S_file_invoke_translator (struct protid *cred, + int flags, + retry_type *retry, + char *retry_name, + mach_port_t *retrypt, + mach_msg_type_name_t *retrypttype) +{ + error_t error = 0; + mode_t type; + struct node *np; + + /* This code is very similar (but subtly different) from + dir-pathtrans.c and fsys-getroot.c. A way should be found to + combine them. */ + + if (!cred) + return EOPNOTSUPP; + + flags &= O_HURD; + + np = cred->po->np; + + mutex_lock (&np->lock); + + type = np->dn_stat.st_mode & S_IFMT; + + repeat_transcheck: + /* Ignore O_NOTRANS in the following check */ + if (diskfs_node_translated (np) || np->translator.control != MACH_PORT_NULL) + { + mach_port_t control = np->translator.control; + + if (control == MACH_PORT_NULL) + { + /* This use of _diskfs_dotdot_file is completely and utterly + bogus. XXX */ + if (error = diskfs_start_translator (np, _diskfs_dotdot_file)) + { + mutex_unlock (&np->lock); + return error; + } + control = np->translator.control; + } + + mach_port_mod_refs (mach_task_self (), control, MACH_PORT_RIGHT_SEND, 1); + mutex_unlock (&np->lock); + error = fsys_getroot (childcontrol, cred->uids, cred->nuids, + cred->gids, cred->ngids, flags, retry, + retryname, retrypt); + if (error == MACH_SEND_INVALID_DEST) + { + mutex_lock (&np->lock); + if (np->translator.control == control) + fshelp_translator_drop (&np->translator); + mach_port_deallocate (mach_task_self (), control); + error = 0; + goto repeat_transcheck; + } + + if (!error && *retrypt != MACH_PORT_NULL) + *retrypttype = MACH_MSG_TYPE_MOVE_SEND; + else + *retrypttype = MACH_MSG_TYPE_COPY_SEND; + + return error; + } + + /* Ignore O_NOTRANS here. */ + if (type == S_IFLNK && !(flags & O_NOLINK)) + + |