diff options
author | Michael I. Bushnell <mib@gnu.org> | 1994-03-25 21:56:24 +0000 |
---|---|---|
committer | Michael I. Bushnell <mib@gnu.org> | 1994-03-25 21:56:24 +0000 |
commit | d78ed471b94e34c2547cd2ecd64ec4870c84d99a (patch) | |
tree | a68acc4fde6a100473648d58baa455e9cc5447c0 | |
parent | 0b1627d2ea983966429e3eaa2f50d252a5df54a3 (diff) |
Formerly file-set-trans.c.~5~
-rw-r--r-- | libdiskfs/file-set-trans.c | 146 |
1 files changed, 76 insertions, 70 deletions
diff --git a/libdiskfs/file-set-trans.c b/libdiskfs/file-set-trans.c index 6ea1d6e0..cebfdb1c 100644 --- a/libdiskfs/file-set-trans.c +++ b/libdiskfs/file-set-trans.c @@ -19,13 +19,6 @@ #include "fs_S.h" #include <hurd/paths.h> -/* XXX need to reimplement transnamelen parameter, and implement Roland's - suggestion: - For S_IFMT shorcuts, don't read the device number out of the file! - TRANSNAME should be "ifmt\0minor\0major\0", where IFMT is - _HURD_{CHR,BLK}DEV and MAJOR, MINOR can be parsed with strtol (,,0) - (allowing octal or hex with 0 or 0x). */ - /* Implement file_set_translator as described in <hurd/fs.defs>. */ error_t diskfs_S_file_set_translator (struct protid *cred, @@ -41,9 +34,12 @@ diskfs_S_file_set_translator (struct protid *cred, if (!cred) return EOPNOTSUPP; + if (!transnamelen && existing == MACH_PORT_NULL) + return 0; + np = cred->po->np; - if (!transname[transnamelen - 1]) + if (transnamelen && !transname[transnamelen - 1]) return EINVAL; mutex_lock (&np->lock); @@ -64,88 +60,98 @@ diskfs_S_file_set_translator (struct protid *cred, diskfs_destroy_translator (np, killtrans_flags); } - if ((flags & FS_TRANS_EXCL) && diskfs_node_translated (np)) + if ((flags & FS_TRANS_EXCL) && transname && diskfs_node_translated (np)) { mutex_unlock (&np->lock); return EBUSY; } - /* Handle the short-circuited translators */ - if (!(flags & FS_TRANS_FORCE)) + if (transnamelen) { - mode_t newmode = 0; - - if (diskfs_shortcut_symlink && !strcmp (transname, _HURD_SYMLINK)) - newmode = S_IFLNK; - if (diskfs_shortcut_chrdev && !(strcmp (transname, _HURD_CHRDEV))) - newmode = S_IFCHR; - else if (diskfs_shortcut_blkdev && !strcmp (transname, _HURD_BLKDEV)) - newmode = S_IFBLK; - else if (diskfs_shortcut_fifo && !strcmp (transname, _HURD_FIFO)) - newmode = S_IFIFO; - else if (diskfs_shortcut_ifsock && !strcmp (transname, _HURD_IFSOCK)) - newmode = S_IFSOCK; - - if (newmode) + if (!(flags & FS_TRANS_FORCE)) { - if (S_ISDIR (np->dn_stat.st_mode)) - { - /* We can't allow this, because if the mode of the directory - changes, the links will be lost. Perhaps it might be - allowed for empty directories, but that's too much of a - pain. */ - mutex_unlock (&np->lock); - return EISDIR; - } - if (newmode == S_IFBLK || newmode == S_IFCHR) + /* Handle the short-circuited translators */ + mode_t newmode = 0; + + if (diskfs_shortcut_symlink && !strcmp (transname, _HURD_SYMLINK)) + newmode = S_IFLNK; + if (diskfs_shortcut_chrdev && !(strcmp (transname, _HURD_CHRDEV))) + newmode = S_IFCHR; + else if (diskfs_shortcut_blkdev && !strcmp (transname, _HURD_BLKDEV)) + newmode = S_IFBLK; + else if (diskfs_shortcut_fifo && !strcmp (transname, _HURD_FIFO)) + newmode = S_IFIFO; + else if (diskfs_shortcut_ifsock && !strcmp (transname, _HURD_IFSOCK)) + newmode = S_IFSOCK; + + if (newmode) { - /* Find the device number from the arguments - of the translator. */ - int major, minor; - char *arg; - - arg = transname + strlen (transname) + 1; - assert (arg <= transname + transnamelen); - if (arg == transname + transnamelen) + if (S_ISDIR (np->dn_stat.st_mode)) { + /* We can't allow this, because if the mode of the directory + changes, the links will be lost. Perhaps it might be + allowed for empty directories, but that's too much of a + pain. */ mutex_unlock (&np->lock); - return EINVAL; + return EISDIR; } - major = strtol (arg, 0, 0); - - arg = arg + strlen (arg) + 1; - assert (arg < transname + transnamelen); - if (arg == transname + transnamelen) + if (newmode == S_IFBLK || newmode == S_IFCHR) { - mutex_unlock (&np->lock); - return EINVAL; - } - minor = strtol (arg, 0, 0); + /* Find the device number from the arguments + of the translator. */ + int major, minor; + char *arg; - np->dn_stat.st_rdev = ((major & 0x377) << 8) | (minor & 0x377); - } + arg = transname + strlen (transname) + 1; + assert (arg <= transname + transnamelen); + if (arg == transname + transnamelen) + { + mutex_unlock (&np->lock); + return EINVAL; + } + major = strtol (arg, 0, 0); - diskfs_truncate (np, 0); - if (newmode == S_IFLNK) - { - char *arg = transname + strlen (transname) + 1; - assert (arg <= transname + transnamelen); - if (arg == transname + transnamelen) + arg = arg + strlen (arg) + 1; + assert (arg < transname + transnamelen); + if (arg == transname + transnamelen) + { + mutex_unlock (&np->lock); + return EINVAL; + } + minor = strtol (arg, 0, 0); + + np->dn_stat.st_rdev = (((major & 0x377) << 8) + | (minor & 0x377)); + } + + diskfs_truncate (np, 0); + if (newmode == S_IFLNK) { - mutex_unlock (&np->lock); - return EINVAL; + char *arg = transname + strlen (transname) + 1; + assert (arg <= transname + transnamelen); + if (arg == transname + transnamelen) + { + mutex_unlock (&np->lock); + return EINVAL; + } + /* Store the argument in the file as the + target of the link */ + diskfs_node_rdwr (np, arg, 0, strlen (arg), 1, cred, 0); } - /* Store the argument in the file as the target of the link */ - diskfs_node_rdwr (np, arg, 0, strlen (arg), 1, cred, 0); + np->dn_stat.st_mode = (np->dn_stat.st_mode & ~S_IFMT) | newmode; + diskfs_node_update (np, 1); + mutex_unlock (&np->lock); + return 0; } - np->dn_stat.st_mode = (np->dn_stat.st_mode & ~S_IFMT) | newmode; - diskfs_node_update (np, 1); - mutex_unlock (&np->lock); - return 0; } + error = diskfs_set_translator (np, transname, transnamelen, cred); } - error = diskfs_set_translator (np, transname, transnamelen, cred); + if (existing != MACH_PORT_NULL) + { + np->translator.control = existing; + np->translator.starting = 0; + } mutex_unlock (&np->lock); return error; } |