Comments (12)
I have tested this by creating multiple Inotify
instances and matching the WatchDescriptors
they generate.
assert_eq!(wd_from_inotify1, wd_from_inotify2);
passes when the contained c_int
is the same for both WatchDescriptors
s. This should not be the case.
While the Eq
trait does seem useful within the scope of an Inotify
instance, the potential to match across instances can break things.
I don't think removing the Eq
trait is the right way to address this issue. Perhaps it makes more sense for the Inotify
struct to generate an identifier unique to itself. This can be passed to generated WatchDescriptor
s as a field. This would retain the usability of the Eq
trait within the scope of the parent Inotify
, and protect against matching WatchDescriptor
s between instances of Inotify
from inotify-rs.
I think the most straight-forward way to address this would be to add the inotify instance's file descriptor to WatchDescriptor
. That would do nothing to solve #61, but at least the Eq
implementation would be working correctly.
from inotify-rs.
Yes, that does seem to be the most practical way of fixing the Eq
implementation. I've implemented a field of type RawFd
in the WatchDescriptor
struct in my working tree.
I'll do a PR once I've figured out what can be done about #61. My tree doesn't build at the moment.
from inotify-rs.
If you make a pull request for adding the RawFd
, I'd definitely accept it. Yes, eventually we want a complete solution that also solves #61, but I suspect that will require more thinking and therefore more time. Until then, fixing the Eq
issue in a simple way will be very welcome.
from inotify-rs.
Adding the RawFd
field to WatchDescriptor
introduces another issue: Inotify[1] itself doesn't associate watch descriptors and events with a particular Inotify instance.
From the Inotify source (accessed from here):
pad_name_len = round_event_name_len(fsn_event);
inotify_event.len = pad_name_len;
inotify_event.mask = inotify_mask_to_arg(fsn_event->mask);
inotify_event.wd = event->wd;
inotify_event.cookie = event->sync_cookie;
Implementing a mechanism to prevent WatchDescriptors
from being shared between Inotify
[2] instances (by adding a RawFd
field to the WatchDescriptor
struct) is possible, but it requires changes to inotify-rs such that the Inotify
and Event
structs will need to handle checking WatchDescriptor
instances for RawFd
. For instance, the add_watch
method would then need to return a WatchDescriptor
with a RawFd field assigned self.0
,
match wd {
-1 => Err(io::Error::last_os_error()),
_ => Ok(WatchDescriptor(wd, self.0)),
}
and the rm_watch
method would need to check this against the RawFd field of the parent Inotify
instance. This adds extraneous functionality to the library over and above the scope of the original Inotify library, since Inotify doesn't include information about the originating Inotify instance with watch descriptors.
This is a major change that affects how the library handles events and watch descriptors, and would also be a breaking change.
[1]Inotify denotes the inotify.c library
[2]Inotify
denotes the Inotify struct in inotify-rs and is formatted as inline code to make it distinct from Inotify above
from inotify-rs.
This is a major change that affects how the library handles events and watch descriptors, and would also be a breaking change.
I think the additional overhead on top of inotify is warranted in this case. I believe it is reasonable to expect an idiomatic Rust wrapper to prevent misuse of the underlying API, as far as that is practical.
Breaking changes are acceptable at this stage. That's why the library is still at an 0.x version.
from inotify-rs.
from inotify-rs.
I'm don't understand what the benefit of this would be. Why give the user a key to refer to the WatchDescriptor
instead of just giving them the WatchDescriptor
directly? What is the purpose of the HashMap
?
from inotify-rs.
I'm sorry about that momentary lapse of reason. Turns out I was doing something very wrong.
I'm making a PR for this bugfix.
from inotify-rs.
I believe this should be closed.
from inotify-rs.
I think this should stay open. While #67 addressed the main defect, I thought of another case where the Eq
implementation could be wrong: If the inotify file descriptor is being reused, and an old WatchDescriptor
is still around.
Usually, this shouldn't be a problem. You can just create one Inotify
instance and use that forever. However, people might use the library differently (see #68, where a user talks about one Inotify
instance per watched directory). A long-running process that watches many directories and opens/closes many files might run into this bug sooner or later.
I have an idea on how to address this (warning, pure idea, not tested in any way): Convert the fd
in Inotify
from a RawFd
to a Rc<RawFd>
. Convert fd
in WatchDescriptor
to a Weak<RawFd>
that points to the same RawFd
. Methods that handle WatchDescriptor
would still need to compare the two RawFd
s, however, by accessing the WatchDescriptors
's RawFd
through the Weak
pointer, they would make sure the original RawFd
was never dropped.
I think this would also solve other issues mentioned in #61. However, it would come with additional cost, most notably one heap allocation per Inotify
instance. This sounds acceptable to me, but maybe we should ask the notify developers for feedback before merging anything like this. On the other hand, no one ever complained about the heap-allocated buffer in Inotify
when that was still a thing.
from inotify-rs.
I did a bit of research. It seems that Linux immediately re-assigns the numbers from closed file descriptors. I've tested with this piece of code:
let inotify_1 = Inotify::init().unwrap();
print!("{}\n", inotify_1.as_raw_fd());
inotify_1.close().unwrap();
let inotify_2 = Inotify::init().unwrap();
print!("{}\n", inotify_2.as_raw_fd());
It prints the same number twice.
This makes it somewhat likely to run into this issue, when handling multiple Inotify
instances. Knowing that, I think the overhead of the solution I outlined above is clearly worth it (altough I still haven't looked at the solution any closer, so I don't know if it will work out).
from inotify-rs.
Related Issues (20)
- Consider addressing buffer alignment in a more robust way HOT 2
- `Inotify::event_stream` is error-prone HOT 2
- Add separate API for adding/removing watches
- Implement ToOwned for `Event<&'a OsStr>` HOT 9
- Consider using cargo clippy in test workflows HOT 1
- Consider increasing the buffer size for the stream example HOT 2
- Using Inotify::read_events in async context HOT 3
- Is it possible to get full path from Event? HOT 3
- Update minimum supported Rust version HOT 1
- duplicate event reports HOT 9
- Async runtime agnostic. HOT 2
- Bump MSRV to at least 1.56 HOT 1
- documentation for `Inotify::watches` is broken in 0.10.1 HOT 4
- Invalid argument when trying to monitor /dev/snd HOT 2
- Update dependency `bitflags` to v2? HOT 3
- docs.rs links from inotify to inotify_sys are broken HOT 4
- Fail CI build on doc warnings
- Example in API reference is broken HOT 7
- Recursive Directory Watching HOT 1
- Release with updated dependencies? HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from inotify-rs.