6
6
# Summary
7
7
8
8
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.
10
10
11
11
# Motivation
12
12
13
13
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:
17
16
18
17
* Inspecting a file's modification/access times
19
18
* Reading low-level information like that contained in ` libc::stat `
@@ -44,13 +43,91 @@ areas:
44
43
45
44
# Detailed design
46
45
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)
48
124
49
125
Currently the ` Metadata ` structure exposes very few pieces of information about
50
126
a file. Some of this is because the information is not available across all
51
127
platforms, but some of it is also because the standard library does not have the
52
128
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.
54
131
55
132
The following trait hierarchy and new structures will be added to the standard
56
133
library.
@@ -109,7 +186,7 @@ design principles of the standard library.
109
186
110
187
The interesting part about working in a "cross platform" manner here is that the
111
188
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.
113
190
To enable as much ergonomic usage as possible, the ` os::unix ` module will expose
114
191
the * intersection* of metadata available in ` libc::stat ` across all unix
115
192
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
123
200
functionality as possible when programming against "unix in general" while still
124
201
allowing applications to choose to only program against macos, for example.
125
202
126
- ### Fate of ` Metadata::{accesed, modified} `
203
+ #### Fate of ` Metadata::{accesed, modified} `
127
204
128
205
At this time there is no suitable type in the standard library to represent the
129
206
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
135
212
files. This information is all available via the ` MetadataExt ` traits listed
136
213
above.
137
214
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)
139
219
140
220
> ** Note** : this section only describes behavior on unix.
141
221
@@ -391,4 +471,5 @@ impl DirEntry {
391
471
392
472
# Unresolved questions
393
473
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