Skip to content
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

Merged
merged 1 commit into from
Mar 24, 2018
Merged

Add chmod, fchmod, fchmodat functions #857

merged 1 commit into from
Mar 24, 2018

Conversation

antage
Copy link
Contributor

@antage antage commented Feb 5, 2018

No description provided.

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`.
Copy link
Member

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`,
Copy link
Member

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 {
Copy link
Member

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)
Copy link
Member

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.

@antage
Copy link
Contributor Author

antage commented Feb 6, 2018

Done.

Copy link
Member

@asomers asomers left a 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).
Copy link
Member

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"

@antage
Copy link
Contributor Author

antage commented Feb 10, 2018

@asomers Fixed and squashed.

Copy link
Contributor

@Susurrus Susurrus left a 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.
Copy link
Contributor

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.
Copy link
Contributor

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 {
Copy link
Contributor

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.

Copy link
Member

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?

Copy link
Contributor Author

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.

Copy link
Contributor

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?

Copy link
Contributor Author

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.

Copy link
Contributor Author

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:

  1. Get rid of chmod function.
  2. Add FchmodatFlag enum instead of AtFlags.
  3. 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?

Copy link
Member

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.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Susurrus Any response?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@antage @Susurrus is AFK. Go ahead and make the changes we discussed, then I can approve the PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@asomers ok.

@antage
Copy link
Contributor Author

antage commented Mar 23, 2018

@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
Copy link
Member

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.
Copy link
Member

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/

let mut mode1 = Mode::empty();
mode1.insert(Mode::S_IRUSR);
mode1.insert(Mode::S_IWUSR);
fchmodat(Some(dirfd), &filename, mode1, FchmodatFlags::FollowSymlink).unwrap();
Copy link
Member

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".

@antage
Copy link
Contributor Author

antage commented Mar 23, 2018

@asomers Fixed.

@asomers
Copy link
Member

asomers commented Mar 24, 2018

Thanks, @antage. It all looks good now.

bors r+

bors bot added a commit that referenced this pull request Mar 24, 2018
857: Add chmod, fchmod, fchmodat functions r=asomers a=antage
@bors
Copy link
Contributor

bors bot commented Mar 24, 2018

@bors bors bot merged commit d315804 into nix-rust:master Mar 24, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants