-
Notifications
You must be signed in to change notification settings - Fork 667
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add chmod, fchmod, fchmodat functions #857
Conversation
CHANGELOG.md
Outdated
@@ -8,6 +8,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). | |||
### Added | |||
|
|||
- Added `alarm`. ([#830](https://github.com/nix-rust/nix/pull/830)) | |||
- Added `chmod`, `fchmod`, `fchmodat`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a link to the PR, as other entries do.
src/sys/stat.rs
Outdated
@@ -122,3 +122,88 @@ pub fn fstatat<P: ?Sized + NixPath>(dirfd: RawFd, pathname: &P, f: AtFlags) -> R | |||
Ok(dst) | |||
} | |||
|
|||
/// The `chmod` function shall change `Mode::S_ISUID`, `Mode::S_ISGID`, `Mode::S_ISVTX`, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The doccomment block must begin with a brief description, < 80 characters, followed by a blank line. And it's not necessary to copy the description from opengroup; nobody is going to check Nix's docs to understand what the underlying system call's compliance requirements are. Just write what a Rust programmer would need to know.
src/sys/stat.rs
Outdated
/// | ||
/// See also [chmod(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/chmod.html). | ||
pub fn chmod<P: ?Sized + NixPath>(path: &P, mode: Mode) -> Result<()> { | ||
let res = try!(path.with_nix_path(|cstr| unsafe { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can replace try!
with ?
. See https://blog.rust-lang.org/2016/11/10/Rust-1.13.html for a description of how it works.
src/sys/stat.rs
Outdated
libc::chmod(cstr.as_ptr(), mode.bits() as mode_t) | ||
})); | ||
|
||
Errno::result(res).map(drop) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefer .map(|_| () )
. I think it's more obvious what you're trying to accomplish.
Done. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please squash your commits when done. Since we use Bors, we can't autosquash on merge.
src/sys/stat.rs
Outdated
/// | ||
/// # References | ||
/// | ||
/// See also [chmod(2)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/chmod.html). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it's going to be in a References block, then you don't need "See also"
@asomers Fixed and squashed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@asomers want to chime in here at all?
src/sys/stat.rs
Outdated
@@ -122,3 +122,48 @@ pub fn fstatat<P: ?Sized + NixPath>(dirfd: RawFd, pathname: &P, f: AtFlags) -> R | |||
Ok(dst) | |||
} | |||
|
|||
/// Change the file permission bits of the file named by the pathname. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change to "Change the file permission bits of a file specified by a path"
src/sys/stat.rs
Outdated
Errno::result(res).map(|_| ()) | ||
} | ||
|
||
/// Change the file permission bits of the file specified by the file descriptor. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"Change the file permission bits of the file specified by the file descriptor." -> "Change the file permission bits of the file specified by a file descriptor"
src/sys/stat.rs
Outdated
mode: Mode, | ||
flag: AtFlags, | ||
) -> Result<()> { | ||
let res = path.with_nix_path(|cstr| unsafe { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function actually has 3 modes:
- Path relative to the cwd of the calling process
- Path relative to the specified directory
- Absolute path
I'd therefore suggest replacing dirfd
and path
with the following:
pub enum PathMode {
RelPath(P),
RelPath(P, dirfd),
AbsPath(P),
}```
Then internally we can do the whole `AT_FDCWD` dance and also `debug_assert!` that those paths are correctly relative or absolute.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's no point in providing both chmod
and fchmodat(PathMode::AbsPath)
; they're identical. Also, I don't think we should force a programmatic distinction between absolute and relative paths, because there are likely to be situations where a Nix consumer doesn't know which type of path it's dealing with, without inspecting it. How about we provide chmod
, fchmod
, and fchmodat
, where the latter asserts that fd
is nonnegative?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
asserts that fd is nonnegative
We can not because AT_FDCWD
is negative integer usually.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm wondering if we can't wrap up these 3 functions and 5 modes into a different object that provides a nicer API than these functions separately? There is definite overlap between these functions, and I don't like the terrible combinatorics of the inputs to fchmodat
. Any ideas here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we shouldn't merge fchmod
and chmod
/fchmodat
because these functions are very different (path vs fd as main argument).
We can get rid of chmod
as it duplicates fchmodat
and leave fchmodat
with the signature:
pub fn fchmodat<P: ?Sized + NixPath>(path: P, mode: Mode, dirfd: Option<RawFd>, nofollow_symlink: bool) -> Result<()>
Here None
in dirfd
substitutes AT_FDCWD
constant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@asomers, @Susurrus The following is a summary of proposed changes:
- Get rid of
chmod
function. - Add
FchmodatFlag
enum instead ofAtFlags
. - Change a signature of
fchmodat
function to:pub fn fchmodat<P: ?Sized + NixPath>(dirfd: Option<RawFd>, path: P, mode: Mode, flag: FchmodatFlag) -> Result<()>
.
Do you have any objections or/and proposals?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that sounds good to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Susurrus Any response?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@asomers ok.
@asomers Done the proposed changes. |
src/sys/stat.rs
Outdated
/// then the mode of the symbolic link is changed. | ||
/// | ||
/// `fchmod(None, path, mode, FchmodatFlags::FollowSymlink)` is identical to | ||
/// a call `libc::chmod(path, mode)`. It's reason why `chmod` is unimplemented |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/It's reason/That's/
src/sys/stat.rs
Outdated
/// | ||
/// `fchmod(None, path, mode, FchmodatFlags::FollowSymlink)` is identical to | ||
/// a call `libc::chmod(path, mode)`. It's reason why `chmod` is unimplemented | ||
/// in `nix` crate. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/in nix
/in the nix
/
test/test_stat.rs
Outdated
let mut mode1 = Mode::empty(); | ||
mode1.insert(Mode::S_IRUSR); | ||
mode1.insert(Mode::S_IWUSR); | ||
fchmodat(Some(dirfd), &filename, mode1, FchmodatFlags::FollowSymlink).unwrap(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here you're supplying an absolute path for filename
. I think you should just supply the relative path, "foo.txt".
@asomers Fixed. |
Thanks, @antage. It all looks good now. bors r+ |
No description provided.