2023-11-29 10:39:24 -05:00
|
|
|
---
|
|
|
|
minutes: 30
|
|
|
|
---
|
|
|
|
|
2022-12-21 16:36:30 +01:00
|
|
|
# Safe FFI Wrapper
|
|
|
|
|
|
|
|
Rust has great support for calling functions through a _foreign function
|
2023-01-17 17:29:40 +00:00
|
|
|
interface_ (FFI). We will use this to build a safe wrapper for the `libc`
|
2023-10-03 15:03:30 +01:00
|
|
|
functions you would use from C to read the names of files in a directory.
|
2022-12-21 16:36:30 +01:00
|
|
|
|
|
|
|
You will want to consult the manual pages:
|
|
|
|
|
2023-12-31 00:15:07 +01:00
|
|
|
- [`opendir(3)`](https://man7.org/linux/man-pages/man3/opendir.3.html)
|
|
|
|
- [`readdir(3)`](https://man7.org/linux/man-pages/man3/readdir.3.html)
|
|
|
|
- [`closedir(3)`](https://man7.org/linux/man-pages/man3/closedir.3.html)
|
2022-12-21 16:36:30 +01:00
|
|
|
|
2023-04-27 14:45:15 -07:00
|
|
|
You will also want to browse the [`std::ffi`] module. There you find a number of
|
|
|
|
string types which you need for the exercise:
|
|
|
|
|
|
|
|
| Types | Encoding | Use |
|
2023-12-31 00:15:07 +01:00
|
|
|
| -------------------------- | -------------- | ------------------------------ |
|
2023-04-27 14:45:15 -07:00
|
|
|
| [`str`] and [`String`] | UTF-8 | Text processing in Rust |
|
|
|
|
| [`CStr`] and [`CString`] | NUL-terminated | Communicating with C functions |
|
|
|
|
| [`OsStr`] and [`OsString`] | OS-specific | Communicating with the OS |
|
|
|
|
|
|
|
|
You will convert between all these types:
|
|
|
|
|
|
|
|
- `&str` to `CString`: you need to allocate space for a trailing `\0` character,
|
|
|
|
- `CString` to `*const i8`: you need a pointer to call C functions,
|
2023-12-31 00:15:07 +01:00
|
|
|
- `*const i8` to `&CStr`: you need something which can find the trailing `\0`
|
|
|
|
character,
|
|
|
|
- `&CStr` to `&[u8]`: a slice of bytes is the universal interface for "some
|
|
|
|
unknown data",
|
2023-04-28 01:00:07 -07:00
|
|
|
- `&[u8]` to `&OsStr`: `&OsStr` is a step towards `OsString`, use
|
2023-12-31 00:15:07 +01:00
|
|
|
[`OsStrExt`](https://doc.rust-lang.org/std/os/unix/ffi/trait.OsStrExt.html) to
|
|
|
|
create it,
|
|
|
|
- `&OsStr` to `OsString`: you need to clone the data in `&OsStr` to be able to
|
|
|
|
return it and call `readdir` again.
|
2023-04-27 14:45:15 -07:00
|
|
|
|
|
|
|
The [Nomicon] also has a very useful chapter about FFI.
|
2022-12-21 16:36:30 +01:00
|
|
|
|
|
|
|
[`std::ffi`]: https://doc.rust-lang.org/std/ffi/
|
2023-04-27 14:45:15 -07:00
|
|
|
[`str`]: https://doc.rust-lang.org/std/primitive.str.html
|
|
|
|
[`String`]: https://doc.rust-lang.org/std/string/struct.String.html
|
2022-12-21 16:36:30 +01:00
|
|
|
[`CStr`]: https://doc.rust-lang.org/std/ffi/struct.CStr.html
|
|
|
|
[`CString`]: https://doc.rust-lang.org/std/ffi/struct.CString.html
|
2023-04-27 14:45:15 -07:00
|
|
|
[`OsStr`]: https://doc.rust-lang.org/std/ffi/struct.OsStr.html
|
|
|
|
[`OsString`]: https://doc.rust-lang.org/std/ffi/struct.OsString.html
|
2022-12-21 16:36:30 +01:00
|
|
|
[Nomicon]: https://doc.rust-lang.org/nomicon/ffi.html
|
|
|
|
|
|
|
|
Copy the code below to <https://play.rust-lang.org/> and fill in the missing
|
|
|
|
functions and methods:
|
|
|
|
|
|
|
|
```rust,should_panic
|
|
|
|
// TODO: remove this when you're done with your implementation.
|
|
|
|
#![allow(unused_imports, unused_variables, dead_code)]
|
|
|
|
|
2023-11-29 10:39:24 -05:00
|
|
|
{{#include exercise.rs:ffi}}
|
2022-12-21 16:36:30 +01:00
|
|
|
|
2023-11-29 10:39:24 -05:00
|
|
|
{{#include exercise.rs:DirectoryIterator}}
|
2022-12-21 16:36:30 +01:00
|
|
|
unimplemented!()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-29 10:39:24 -05:00
|
|
|
{{#include exercise.rs:Iterator}}
|
2022-12-21 16:36:30 +01:00
|
|
|
unimplemented!()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-29 10:39:24 -05:00
|
|
|
{{#include exercise.rs:Drop}}
|
2022-12-21 16:36:30 +01:00
|
|
|
unimplemented!()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-29 10:39:24 -05:00
|
|
|
{{#include exercise.rs:main}}
|
2022-12-21 16:36:30 +01:00
|
|
|
```
|