Skip to content

Commit b3d1ad6

Browse files
committed
Add vision for std::os, a few other tweaks
1 parent f3153e6 commit b3d1ad6

File tree

1 file changed

+91
-10
lines changed

1 file changed

+91
-10
lines changed

text/0000-io-fs-2.1.md

+91-10
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,13 @@
66
# Summary
77

88
Expand the scope of the `std::fs` module by enhancing existing functionality,
9-
exposing lower level representations, and adding a few more new functions.
9+
exposing lower-level representations, and adding a few new functions.
1010

1111
# Motivation
1212

1313
The current `std::fs` module serves many of the basic needs of interacting with
14-
a filesystem, but it falls short of binding a good bit more of useful
15-
functionality. For example, none of these operations are possible in stable Rust
16-
today:
14+
a filesystem, but is missing a lot of useful functionality. For example, none of
15+
these operations are possible in stable Rust today:
1716

1817
* Inspecting a file's modification/access times
1918
* Reading low-level information like that contained in `libc::stat`
@@ -44,13 +43,91 @@ areas:
4443

4544
# Detailed design
4645

47-
## Lowering `Metadata`
46+
## Lowering APIs
47+
48+
### The vision for the `os` module
49+
50+
One of the principles of [IO reform][io-reform-vision] was to:
51+
52+
> Provide hooks for integrating with low-level and/or platform-specific APIs.
53+
54+
The original RFC went into some amount of detail for how this would look, in
55+
particular by use of the `os` module. Part of the goal of this RFC is to flesh
56+
out that vision in more detail.
57+
58+
Ultimately, the organization of `os` is planned to look something like the
59+
following:
60+
61+
```
62+
os
63+
unix applicable to all cfg(unix) platforms; high- and low-level APIs
64+
io extensions to std::io
65+
fs extensions to std::fs
66+
net extensions to std::net
67+
env extensions to std::env
68+
process extensions to std::process
69+
...
70+
linux applicable to linux only
71+
io, fs, net, env, process, ...
72+
macos ...
73+
windows ...
74+
```
75+
76+
APIs whose behavior is platform-specific are provided only within the `std::os`
77+
hierarchy, making it easy to audit for usage of such APIs. Organizing the
78+
platform modules internally in the same way as `std` makes it easy to find
79+
relevant extensions when working with `std`.
80+
81+
It is emphatically *not* the goal of the `std::os::*` modules to provide
82+
bindings to *all* system APIs for each platform; this work is left to external
83+
crates. The goals are rather to:
84+
85+
1. Facilitate interop between abstract types like `File` that `std` provides and
86+
the underlying system. This is done via "lowering": extension traits like
87+
[`AsRawFd`][AsRawFd] allow you to extract low-level, platform-specific
88+
representations out of `std` types like `File` and `TcpStream`.
89+
90+
2. Provide high-level but platform-specific APIs that feel like those in the
91+
rest of `std`. Just as with the rest of `std`, the goal here is not to
92+
include all possible functionality, but rather the most commonly-used or
93+
fundamental.
94+
95+
Lowering makes it possible for external crates to provide APIs that work
96+
"seamlessly" with `std` abstractions. For example, a crate for Linux might
97+
provide an `epoll` facility that can work directly with `std::fs::File` and
98+
`std::net::TcpStream` values, completely hiding the internal use of file
99+
descriptors. Eventually, such a crate could even be merged into `std::os::unix`,
100+
with minimal disruption -- there is little distinction between `std` and other
101+
crates in this regard.
102+
103+
Concretely, lowering has two ingredients:
104+
105+
1. Introducing one or more "raw" types that are generally direct aliases for C
106+
types.
107+
108+
2. Providing an extension trait that makes it possible to extract a raw type
109+
from a `std` type. In some cases, it's possible to go the other way around as
110+
well. The conversion can be by reference or by value, where the latter is
111+
used mainly to avoid the destructor associated with a `std` type (e.g. to
112+
extract a file descriptor from a `File` and eliminate the `File` object,
113+
without closing the file).
114+
115+
While we do not seek to exhaustively bind types or APIs from the underlying
116+
system, it *is* a goal to provide lowering operations for every high-level type
117+
to a system-level data type, whenever applicable. This RFC proposes several such
118+
lowerings that are currently missing from `std::fs`.
119+
120+
[io-reform-vision]: https://github.com/rust-lang/rfcs/blob/master/text/0517-io-os-reform.md#vision-for-io
121+
[AsRawFd]: http://static.rust-lang.org/doc/master/std/os/unix/io/trait.AsRawFd.html
122+
123+
### Lowering `Metadata` (all platforms)
48124

49125
Currently the `Metadata` structure exposes very few pieces of information about
50126
a file. Some of this is because the information is not available across all
51127
platforms, but some of it is also because the standard library does not have the
52128
appropriate abstraction to return at this time (e.g. time stamps). The raw
53-
contents of `Metadata`, however, should be accessible no matter what.
129+
contents of `Metadata` (a `stat` on Unix), however, should be accessible via
130+
lowering no matter what.
54131

55132
The following trait hierarchy and new structures will be added to the standard
56133
library.
@@ -109,7 +186,7 @@ design principles of the standard library.
109186

110187
The interesting part about working in a "cross platform" manner here is that the
111188
makeup of `libc::stat` on unix platforms can vary quite a bit between platforms.
112-
For example not some platforms have a `st_birthtim` field while others do not.
189+
For example some platforms have a `st_birthtim` field while others do not.
113190
To enable as much ergonomic usage as possible, the `os::unix` module will expose
114191
the *intersection* of metadata available in `libc::stat` across all unix
115192
platforms. The information is still exposed in a raw fashion (in terms of the
@@ -123,7 +200,7 @@ One of the major goals of the `os::unix::fs` design is to enable as much
123200
functionality as possible when programming against "unix in general" while still
124201
allowing applications to choose to only program against macos, for example.
125202

126-
### Fate of `Metadata::{accesed, modified}`
203+
#### Fate of `Metadata::{accesed, modified}`
127204

128205
At this time there is no suitable type in the standard library to represent the
129206
return type of these two functions. The type would either have to be some form
@@ -135,7 +212,10 @@ requiring platform-specific code to access the modification/access time of
135212
files. This information is all available via the `MetadataExt` traits listed
136213
above.
137214

138-
## Lowering and setting `Permissions`
215+
Eventually, once a `std` type for cross-platform timestamps is available, these
216+
methods will be re-instated as returning that type.
217+
218+
### Lowering and setting `Permissions` (Unix)
139219

140220
> **Note**: this section only describes behavior on unix.
141221
@@ -391,4 +471,5 @@ impl DirEntry {
391471

392472
# Unresolved questions
393473

394-
None yet.
474+
* What is the ultimate role of crates like `liblibc`, and how do we draw the
475+
line between them and `std::os` definitions?

0 commit comments

Comments
 (0)