@@ -62,6 +62,7 @@ follow-up PRs against this RFC.
62
62
* [ Errors]
63
63
* [ Channel adapters]
64
64
* [ stdin, stdout, stderr]
65
+ * [ Printing functions]
65
66
* [ std::env]
66
67
* [ std::fs]
67
68
* [ Free functions]
@@ -72,7 +73,6 @@ follow-up PRs against this RFC.
72
73
* [ TCP]
73
74
* [ UDP]
74
75
* [ Addresses]
75
- * [ std::net] (stub)
76
76
* [ std::process]
77
77
* [ Command]
78
78
* [ Child]
@@ -1155,7 +1155,176 @@ RFC recommends they remain unstable.
1155
1155
#### ` stdin ` , ` stdout ` , ` stderr `
1156
1156
[ stdin, stdout, stderr ] : #stdin-stdout-stderr
1157
1157
1158
- > To be added in a follow-up PR.
1158
+ The current ` stdio ` module will be removed in favor of these constructors in the
1159
+ ` io ` module:
1160
+
1161
+ ``` rust
1162
+ pub fn stdin () -> Stdin ;
1163
+ pub fn stdout () -> Stdout ;
1164
+ pub fn stderr () -> Stderr ;
1165
+ ```
1166
+
1167
+ * ` stdin ` - returns a handle to a ** globally shared** standard input of
1168
+ the process which is buffered as well. Due to the globally shared nature of
1169
+ this handle, all operations on ` Stdin ` directly will acquire a lock internally
1170
+ to ensure access to the shared buffer is synchronized. This implementation
1171
+ detail is also exposed through a ` lock ` method where the handle can be
1172
+ explicitly locked for a period of time so relocking is not necessary.
1173
+
1174
+ The ` Read ` trait will be implemented directly on the returned ` Stdin ` handle
1175
+ but the ` BufRead ` trait will not be (due to synchronization concerns). The
1176
+ locked version of ` Stdin ` (` StdinLock ` ) will provide an implementation of
1177
+ ` BufRead ` .
1178
+
1179
+ The design will largely be the same as is today with the ` old_io ` module.
1180
+
1181
+ ``` rust
1182
+ impl Stdin {
1183
+ fn lock (& self ) -> StdinLock ;
1184
+ fn read_line (& mut self , into : & mut String ) -> io :: Result <()>;
1185
+ fn read_until (& mut self , byte : u8 , into : & mut Vec <u8 >) -> io :: Result <()>;
1186
+ }
1187
+ impl Read for Stdin { ... }
1188
+ impl Read for StdinLock { ... }
1189
+ impl BufRead for StdinLock { ... }
1190
+ ```
1191
+
1192
+ * ` stderr ` - returns a ** non buffered** handle to the standard error output
1193
+ stream for the process. Each call to ` write ` will roughly translate to a
1194
+ system call to output data when written to ` stderr ` . This handle is locked
1195
+ like ` stdin ` to ensure, for example, that calls to ` write_all ` are atomic with
1196
+ respect to one another. There will also be an RAII guard to lock the handle
1197
+ and use the result as an instance of ` Write ` .
1198
+
1199
+ ``` rust
1200
+ impl Stderr {
1201
+ fn lock (& self ) -> StderrLock ;
1202
+ }
1203
+ impl Write for Stderr { ... }
1204
+ impl Write for StderrLock { ... }
1205
+ ```
1206
+
1207
+ * ` stdout ` - returns a ** globally buffered** handle to the standard output of
1208
+ the current process. The amount of buffering can be decided at runtime to
1209
+ allow for different situations such as being attached to a TTY or being
1210
+ redirected to an output file. The ` Write ` trait will be implemented for this
1211
+ handle, and like ` stderr ` it will be possible to lock it and then use the
1212
+ result as an instance of ` Write ` as well.
1213
+
1214
+ ``` rust
1215
+ impl Stdout {
1216
+ fn lock (& self ) -> StdoutLock ;
1217
+ }
1218
+ impl Write for Stdout { ... }
1219
+ impl Write for StdoutLock { ... }
1220
+ ```
1221
+
1222
+ #### Windows and stdio
1223
+ [ Windows stdio ] : #windows-and-stdio
1224
+
1225
+ On Windows, standard input and output handles can work with either arbitrary
1226
+ ` [u8] ` or ` [u16] ` depending on the state at runtime. For example a program
1227
+ attached to the console will work with arbitrary ` [u16] ` , but a program attached
1228
+ to a pipe would work with arbitrary ` [u8] ` .
1229
+
1230
+ To handle this difference, the following behavior will be enforced for the
1231
+ standard primitives listed above:
1232
+
1233
+ * If attached to a pipe then no attempts at encoding or decoding will be done,
1234
+ the data will be ferried through as ` [u8] ` .
1235
+
1236
+ * If attached to a console, then ` stdin ` will attempt to interpret all input as
1237
+ UTF-16, re-encoding into UTF-8 and returning the UTF-8 data instead. This
1238
+ implies that data will be buffered internally to handle partial reads/writes.
1239
+ Invalid UTF-16 will simply be discarded returning an ` io::Error ` explaining
1240
+ why.
1241
+
1242
+ * If attached to a console, then ` stdout ` and ` stderr ` will attempt to interpret
1243
+ input as UTF-8, re-encoding to UTF-16. If the input is not valid UTF-8 then an
1244
+ error will be returned and no data will be written.
1245
+
1246
+ #### Raw stdio
1247
+ [ Raw stdio ] : #raw-stdio
1248
+
1249
+ > ** Note** : This section is intended to be a sketch of possible raw stdio
1250
+ > support, but it is not planned to implement or stabilize this
1251
+ > implementation at this time.
1252
+
1253
+ The above standard input/output handles all involve some form of locking or
1254
+ buffering (or both). This cost is not always wanted, and hence raw variants will
1255
+ be provided. Due to platform differences across unix/windows, the following
1256
+ structure will be supported:
1257
+
1258
+ ``` rust
1259
+ mod os {
1260
+ mod unix {
1261
+ mod stdio {
1262
+ struct Stdio { .. }
1263
+
1264
+ impl Stdio {
1265
+ fn stdout () -> Stdio ;
1266
+ fn stderr () -> Stdio ;
1267
+ fn stdin () -> Stdio ;
1268
+ }
1269
+
1270
+ impl Read for Stdio { ... }
1271
+ impl Write for Stdio { ... }
1272
+ }
1273
+ }
1274
+
1275
+ mod windows {
1276
+ mod stdio {
1277
+ struct Stdio { ... }
1278
+ struct StdioConsole { ... }
1279
+
1280
+ impl Stdio {
1281
+ fn stdout () -> io :: Result <Stdio >;
1282
+ fn stderr () -> io :: Result <Stdio >;
1283
+ fn stdin () -> io :: Result <Stdio >;
1284
+ }
1285
+ // same constructors StdioConsole
1286
+
1287
+ impl Read for Stdio { ... }
1288
+ impl Write for Stdio { ... }
1289
+
1290
+ impl StdioConsole {
1291
+ // returns slice of what was read
1292
+ fn read <'a >(& self , buf : & 'a mut OsString ) -> io :: Result <& 'a OsStr >;
1293
+ // returns remaining part of `buf` to be written
1294
+ fn write <'a >(& self , buf : & 'a OsStr ) -> io :: Result <& 'a OsStr >;
1295
+ }
1296
+ }
1297
+ }
1298
+ }
1299
+ ```
1300
+
1301
+ There are some key differences from today's API:
1302
+
1303
+ * On unix, the API has not changed much except that the handles have been
1304
+ consolidated into one type which implements both ` Read ` and ` Write ` (although
1305
+ writing to stdin is likely to generate an error).
1306
+ * On windows, there are two sets of handles representing the difference between
1307
+ "console mode" and not (e.g. a pipe). When not a console the normal I/O traits
1308
+ are implemented (delegating to ` ReadFile ` and ` WriteFile ` . The console mode
1309
+ operations work with ` OsStr ` , however, to show how they work with UCS-2 under
1310
+ the hood.
1311
+
1312
+ #### Printing functions
1313
+ [ Printing functions ] : #printing-functions
1314
+
1315
+ The current ` print ` , ` println ` , ` print_args ` , and ` println_args ` functions will
1316
+ all be "removed from the public interface" by [ prefixing them with ` __ ` and
1317
+ marking ` #[doc(hidden)] ` ] [ gh22607 ] . These are all implementation details of the
1318
+ ` print! ` and ` println! ` macros and don't need to be exposed in the public
1319
+ interface.
1320
+
1321
+ [ gh22607 ] : https://github.com/rust-lang/rust/issues/22607
1322
+
1323
+ The ` set_stdout ` and ` set_stderr ` functions will be removed with no replacement
1324
+ for now. It's unclear whether these functions should indeed control a thread
1325
+ local handle instead of a global handle as whether they're justified in the
1326
+ first place. It is a backwards-compatible extension to allow this sort of output
1327
+ to be redirected and can be considered if the need arises.
1159
1328
1160
1329
### ` std::env `
1161
1330
[ std::env ] : #stdenv
@@ -1173,7 +1342,8 @@ and the signatures will be updated to follow this RFC's
1173
1342
1174
1343
* ` vars ` (renamed from ` env ` ): yields a vector of ` (OsString, OsString) ` pairs.
1175
1344
* ` var ` (renamed from ` getenv ` ): take a value bounded by ` AsOsStr ` ,
1176
- allowing Rust strings and slices to be ergonomically passed in. Yields an ` Option<OsString> ` .
1345
+ allowing Rust strings and slices to be ergonomically passed in. Yields an
1346
+ ` Option<OsString> ` .
1177
1347
* ` var_string ` : take a value bounded by ` AsOsStr ` , returning `Result<String,
1178
1348
VarError>` where ` VarError` represents a non-unicode ` OsString` or a "not
1179
1349
present" value.
0 commit comments