]> git.lizzy.rs Git - rust.git/commitdiff
Change std::io::FilePermission to a typesafe representation
authorAaron Turon <aturon@mozilla.com>
Fri, 2 May 2014 17:56:26 +0000 (10:56 -0700)
committerAaron Turon <aturon@mozilla.com>
Mon, 5 May 2014 22:24:36 +0000 (15:24 -0700)
This patch changes `std::io::FilePermissions` from an exposed `u32`
representation to a typesafe representation (that only allows valid
flag combinations) using the `std::bitflags`, thus ensuring a greater
degree of safety on the Rust side.

Despite the change to the type, most code should continue to work
as-is, sincde the new type provides bit operations in the style of C
flags. To get at the underlying integer representation, use the `bits`
method; to (unsafely) convert to `FilePermissions`, use
`FilePermissions::from_bits`.

Closes #6085.

[breaking-change]

src/libnative/io/file_unix.rs
src/libnative/io/file_win32.rs
src/librustuv/file.rs
src/librustuv/uvio.rs
src/libstd/io/fs.rs
src/libstd/io/mod.rs

index 7c19eb54326245a7369d1aae8ff230576a04afa2..94ca602784112e31d487bf00d9bf6a61b9c0865a 100644 (file)
@@ -335,7 +335,7 @@ pub fn open(path: &CString, fm: io::FileMode, fa: io::FileAccess)
 
 pub fn mkdir(p: &CString, mode: io::FilePermission) -> IoResult<()> {
     super::mkerr_libc(retry(|| unsafe {
-        libc::mkdir(p.with_ref(|p| p), mode as libc::mode_t)
+        libc::mkdir(p.with_ref(|p| p), mode.bits() as libc::mode_t)
     }))
 }
 
@@ -392,7 +392,7 @@ pub fn rename(old: &CString, new: &CString) -> IoResult<()> {
 
 pub fn chmod(p: &CString, mode: io::FilePermission) -> IoResult<()> {
     super::mkerr_libc(retry(|| unsafe {
-        libc::chmod(p.with_ref(|p| p), mode as libc::mode_t)
+        libc::chmod(p.with_ref(|p| p), mode.bits() as libc::mode_t)
     }))
 }
 
@@ -470,7 +470,9 @@ fn gen(_stat: &libc::stat) -> u64 { 0 }
         path: Path::new(path),
         size: stat.st_size as u64,
         kind: kind,
-        perm: (stat.st_mode) as io::FilePermission & io::AllPermissions,
+        perm: unsafe {
+            io::FilePermission::from_bits(stat.st_mode as u32) & io::AllPermissions
+        },
         created: mktime(stat.st_ctime as u64, stat.st_ctime_nsec as u64),
         modified: mktime(stat.st_mtime as u64, stat.st_mtime_nsec as u64),
         accessed: mktime(stat.st_atime as u64, stat.st_atime_nsec as u64),
index 88ba6dcbc7e58a5513df022028eb9cfe826f40f2..945a1f0d612357e4fa48f914179532fbbefe68f6 100644 (file)
@@ -391,7 +391,7 @@ pub fn rename(old: &CString, new: &CString) -> IoResult<()> {
 
 pub fn chmod(p: &CString, mode: io::FilePermission) -> IoResult<()> {
     super::mkerr_libc(as_utf16_p(p.as_str().unwrap(), |p| unsafe {
-        libc::wchmod(p, mode as libc::c_int)
+        libc::wchmod(p, mode.bits() as libc::c_int)
     }))
 }
 
@@ -470,7 +470,9 @@ fn mkstat(stat: &libc::stat, path: &CString) -> io::FileStat {
         path: Path::new(path),
         size: stat.st_size as u64,
         kind: kind,
-        perm: (stat.st_mode) as io::FilePermission & io::AllPermissions,
+        perm: unsafe {
+          io::FilePermission::from_bits(stat.st_mode as u32)  & io::AllPermissions
+        },
         created: stat.st_ctime as u64,
         modified: stat.st_mtime as u64,
         accessed: stat.st_atime as u64,
index 665d418ab2ab6e0fd1c718f7d990afbc1fb971d6..1df68b5cf5c72352f46bfc134c0209ccaccbec75 100644 (file)
@@ -283,7 +283,9 @@ fn to_msec(stat: uvll::uv_timespec_t) -> u64 {
             path: path,
             size: stat.st_size as u64,
             kind: kind,
-            perm: (stat.st_mode as io::FilePermission) & io::AllPermissions,
+            perm: unsafe {
+                io::FilePermission::from_bits(stat.st_mode as u32) & io::AllPermissions
+            },
             created: to_msec(stat.st_birthtim),
             modified: to_msec(stat.st_mtim),
             accessed: to_msec(stat.st_atim),
index 80c09cc24d60c27db010d892d7b7dd626a56143b..999c5ec4e33f2441290702572b2617f7a5d50371 100644 (file)
@@ -224,7 +224,7 @@ fn fs_stat(&mut self, path: &CString) -> Result<FileStat, IoError> {
     }
     fn fs_mkdir(&mut self, path: &CString,
                 perm: io::FilePermission) -> Result<(), IoError> {
-        let r = FsRequest::mkdir(&self.loop_, path, perm as c_int);
+        let r = FsRequest::mkdir(&self.loop_, path, perm.bits() as c_int);
         r.map_err(uv_error_to_io_error)
     }
     fn fs_rmdir(&mut self, path: &CString) -> Result<(), IoError> {
@@ -237,7 +237,7 @@ fn fs_rename(&mut self, path: &CString, to: &CString) -> Result<(), IoError> {
     }
     fn fs_chmod(&mut self, path: &CString,
                 perm: io::FilePermission) -> Result<(), IoError> {
-        let r = FsRequest::chmod(&self.loop_, path, perm as c_int);
+        let r = FsRequest::chmod(&self.loop_, path, perm.bits() as c_int);
         r.map_err(uv_error_to_io_error)
     }
     fn fs_readdir(&mut self, path: &CString, flags: c_int)
index cd304250b19281a8ea4e917317d1870ebc8ddd33..6d48b9eee3517f9889b9081dbeea2c417c8f0d94 100644 (file)
@@ -1119,7 +1119,7 @@ pub fn tmpdir() -> TempDir {
         check!(File::create(&input));
         check!(chmod(&input, io::UserRead));
         check!(copy(&input, &out));
-        assert!(check!(out.stat()).perm & io::UserWrite == 0);
+        assert!(!check!(out.stat()).perm.intersects(io::UserWrite));
 
         check!(chmod(&input, io::UserFile));
         check!(chmod(&out, io::UserFile));
@@ -1193,9 +1193,9 @@ pub fn tmpdir() -> TempDir {
         let file = tmpdir.join("in.txt");
 
         check!(File::create(&file));
-        assert!(check!(stat(&file)).perm & io::UserWrite == io::UserWrite);
+        assert!(check!(stat(&file)).perm.contains(io::UserWrite));
         check!(chmod(&file, io::UserRead));
-        assert!(check!(stat(&file)).perm & io::UserWrite == 0);
+        assert!(!check!(stat(&file)).perm.contains(io::UserWrite));
 
         match chmod(&tmpdir.join("foo"), io::UserRWX) {
             Ok(..) => fail!("wanted a failure"),
index d948738ac564a413ae14d1e392ef1821e8589b35..ff276d0202818b7be01169ea1ce4dc27302942e2 100644 (file)
@@ -224,6 +224,7 @@ fn file_product(p: &Path) -> IoResult<u32> {
 use int;
 use iter::Iterator;
 use libc;
+use ops::{BitOr, BitAnd, Sub};
 use os;
 use option::{Option, Some, None};
 use path::Path;
@@ -1558,36 +1559,40 @@ pub struct UnstableFileStat {
     pub gen: u64,
 }
 
-/// A set of permissions for a file or directory is represented by a set of
-/// flags which are or'd together.
-pub type FilePermission = u32;
-
-// Each permission bit
-pub static UserRead: FilePermission     = 0x100;
-pub static UserWrite: FilePermission    = 0x080;
-pub static UserExecute: FilePermission  = 0x040;
-pub static GroupRead: FilePermission    = 0x020;
-pub static GroupWrite: FilePermission   = 0x010;
-pub static GroupExecute: FilePermission = 0x008;
-pub static OtherRead: FilePermission    = 0x004;
-pub static OtherWrite: FilePermission   = 0x002;
-pub static OtherExecute: FilePermission = 0x001;
-
-// Common combinations of these bits
-pub static UserRWX: FilePermission  = UserRead | UserWrite | UserExecute;
-pub static GroupRWX: FilePermission = GroupRead | GroupWrite | GroupExecute;
-pub static OtherRWX: FilePermission = OtherRead | OtherWrite | OtherExecute;
-
-/// A set of permissions for user owned files, this is equivalent to 0644 on
-/// unix-like systems.
-pub static UserFile: FilePermission = UserRead | UserWrite | GroupRead | OtherRead;
-/// A set of permissions for user owned directories, this is equivalent to 0755
-/// on unix-like systems.
-pub static UserDir: FilePermission = UserRWX | GroupRead | GroupExecute |
-                                     OtherRead | OtherExecute;
-/// A set of permissions for user owned executables, this is equivalent to 0755
-/// on unix-like systems.
-pub static UserExec: FilePermission = UserDir;
-
-/// A mask for all possible permission bits
-pub static AllPermissions: FilePermission = 0x1ff;
+bitflags!(
+    #[doc="A set of permissions for a file or directory is represented
+by a set of flags which are or'd together."]
+    #[deriving(Hash)]
+    #[deriving(Show)]
+    flags FilePermission: u32 {
+        static UserRead     = 0o400,
+        static UserWrite    = 0o200,
+        static UserExecute  = 0o100,
+        static GroupRead    = 0o040,
+        static GroupWrite   = 0o020,
+        static GroupExecute = 0o010,
+        static OtherRead    = 0o004,
+        static OtherWrite   = 0o002,
+        static OtherExecute = 0o001,
+
+        static UserRWX  = UserRead.bits | UserWrite.bits | UserExecute.bits,
+        static GroupRWX = GroupRead.bits | GroupWrite.bits | GroupExecute.bits,
+        static OtherRWX = OtherRead.bits | OtherWrite.bits | OtherExecute.bits,
+
+        #[doc="Permissions for user owned files, equivalent to 0644 on
+unix-like systems."]
+        static UserFile = UserRead.bits | UserWrite.bits | GroupRead.bits | OtherRead.bits,
+
+        #[doc="Permissions for user owned directories, equivalent to 0755 on
+unix-like systems."]
+        static UserDir  = UserRWX.bits | GroupRead.bits | GroupExecute.bits |
+                   OtherRead.bits | OtherExecute.bits,
+
+        #[doc="Permissions for user owned executables, equivalent to 0755
+on unix-like systems."]
+        static UserExec = UserDir.bits,
+
+        #[doc="All possible permissions enabled."]
+        static AllPermissions = UserRWX.bits | GroupRWX.bits | OtherRWX.bits
+    }
+)