mirror of
https://github.com/dart-lang/sdk
synced 2024-09-05 16:41:07 +00:00
[dart:io] Backport semantic changes from the dart:io NNBD migration.
The NNBD migration required making subtle changes to some dart:io semantics in order to provide a better API. This change backports these semantic changes to the unmigrated SDK so any issues can be discovered now instead of blocking the future SDK unfork. The Process class will now throw a StateError if the process is detached upon accessing the stdin, stdout, stderr, and exitCode getters. The Socket class will now throw a SocketException if the socket has been destroyed or upgraded to a secure socket upon setting or getting socket options. Change-Id: I956fd07e713e51ebd479ebbfe4790d8d2fdf0744 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/133989 Commit-Queue: Jonas Termansen <sortie@google.com> Reviewed-by: Lasse R.H. Nielsen <lrn@google.com>
This commit is contained in:
parent
4d32ec8d21
commit
4cd6243d77
10
CHANGELOG.md
10
CHANGELOG.md
|
@ -17,6 +17,16 @@ used (see Issue [39627][]).
|
|||
|
||||
#### `dart:io`
|
||||
|
||||
* The `Process` class will now throw a `StateError` if the process is detached
|
||||
upon accessing the `exitCode` getter. It also now throws when the process is
|
||||
detached without stdio upon accessing the `stdin`, `stdout`, and `stderr`
|
||||
getters. Previously these getters would all return `null`.
|
||||
|
||||
* The `Socket` class will now throw a `SocketException` if the socket has been
|
||||
destroyed or upgraded to a secure socket upon setting or getting socket
|
||||
options. Previously setting a socket options would be ignored and getting a
|
||||
socket option would return `null`.
|
||||
|
||||
### Dart VM
|
||||
|
||||
### Tools
|
||||
|
|
|
@ -534,19 +534,16 @@ class _ProcessImpl extends _ProcessImplNativeWrapper implements Process {
|
|||
_wait(_NativeSocket stdin, _NativeSocket stdout, _NativeSocket stderr,
|
||||
_NativeSocket exitHandler) native "Process_Wait";
|
||||
|
||||
Stream<List<int>> get stdout {
|
||||
return _stdout;
|
||||
}
|
||||
Stream<List<int>> get stdout =>
|
||||
_stdout ?? (throw StateError("Process is detached"));
|
||||
|
||||
Stream<List<int>> get stderr {
|
||||
return _stderr;
|
||||
}
|
||||
Stream<List<int>> get stderr =>
|
||||
_stderr ?? (throw StateError("Process is detached"));
|
||||
|
||||
IOSink get stdin {
|
||||
return _stdin;
|
||||
}
|
||||
IOSink get stdin => _stdin ?? (throw StateError("Process is detached"));
|
||||
|
||||
Future<int> get exitCode => _exitCode != null ? _exitCode.future : null;
|
||||
Future<int> get exitCode =>
|
||||
_exitCode?.future ?? (throw StateError("Process is detached"));
|
||||
|
||||
bool kill([ProcessSignal signal = ProcessSignal.sigterm]) {
|
||||
if (signal is! ProcessSignal) {
|
||||
|
|
|
@ -1779,40 +1779,37 @@ class _Socket extends Stream<Uint8List> implements Socket {
|
|||
}
|
||||
|
||||
bool setOption(SocketOption option, bool enabled) {
|
||||
if (_raw == null) return false;
|
||||
if (_raw == null) throw const SocketException.closed();
|
||||
return _raw.setOption(option, enabled);
|
||||
}
|
||||
|
||||
Uint8List getRawOption(RawSocketOption option) {
|
||||
if (_raw == null) return null;
|
||||
if (_raw == null) throw const SocketException.closed();
|
||||
return _raw.getRawOption(option);
|
||||
}
|
||||
|
||||
void setRawOption(RawSocketOption option) {
|
||||
_raw?.setRawOption(option);
|
||||
if (_raw == null) throw const SocketException.closed();
|
||||
_raw.setRawOption(option);
|
||||
}
|
||||
|
||||
int get port {
|
||||
if (_raw == null) throw const SocketException.closed();
|
||||
;
|
||||
return _raw.port;
|
||||
}
|
||||
|
||||
InternetAddress get address {
|
||||
if (_raw == null) throw const SocketException.closed();
|
||||
;
|
||||
return _raw.address;
|
||||
}
|
||||
|
||||
int get remotePort {
|
||||
if (_raw == null) throw const SocketException.closed();
|
||||
;
|
||||
return _raw.remotePort;
|
||||
}
|
||||
|
||||
InternetAddress get remoteAddress {
|
||||
if (_raw == null) throw const SocketException.closed();
|
||||
;
|
||||
return _raw.remoteAddress;
|
||||
}
|
||||
|
||||
|
|
|
@ -652,21 +652,29 @@ abstract class RawSocket implements Stream<RawSocketEvent> {
|
|||
|
||||
/**
|
||||
* Returns the port used by this socket.
|
||||
*
|
||||
* Throws a [SocketException] if the socket is closed.
|
||||
*/
|
||||
int get port;
|
||||
|
||||
/**
|
||||
* Returns the remote port connected to by this socket.
|
||||
*
|
||||
* Throws a [SocketException] if the socket is closed.
|
||||
*/
|
||||
int get remotePort;
|
||||
|
||||
/**
|
||||
* Returns the [InternetAddress] used to connect this socket.
|
||||
*
|
||||
* Throws a [SocketException] if the socket is closed.
|
||||
*/
|
||||
InternetAddress get address;
|
||||
|
||||
/**
|
||||
* Returns the remote [InternetAddress] connected to by this socket.
|
||||
*
|
||||
* Throws a [SocketException] if the socket is closed.
|
||||
*/
|
||||
InternetAddress get remoteAddress;
|
||||
|
||||
|
@ -791,6 +799,9 @@ abstract class Socket implements Stream<Uint8List>, IOSink {
|
|||
* available options.
|
||||
*
|
||||
* Returns [:true:] if the option was set successfully, false otherwise.
|
||||
*
|
||||
* Throws a [SocketException] if the socket has been destroyed or upgraded to
|
||||
* a secure socket.
|
||||
*/
|
||||
bool setOption(SocketOption option, bool enabled);
|
||||
|
||||
|
@ -800,7 +811,8 @@ abstract class Socket implements Stream<Uint8List>, IOSink {
|
|||
*
|
||||
* Returns the [RawSocketOption.value] on success.
|
||||
*
|
||||
* Throws an [OSError] on failure.
|
||||
* Throws an [OSError] on failure and a [SocketException] if the socket has
|
||||
* been destroyed or upgraded to a secure socket.
|
||||
*/
|
||||
Uint8List getRawOption(RawSocketOption option);
|
||||
|
||||
|
@ -808,27 +820,36 @@ abstract class Socket implements Stream<Uint8List>, IOSink {
|
|||
* Use [setRawOption] to customize the [RawSocket]. See [RawSocketOption] for
|
||||
* available options.
|
||||
*
|
||||
* Throws an [OSError] on failure.
|
||||
* Throws an [OSError] on failure and a [SocketException] if the socket has
|
||||
* been destroyed or upgraded to a secure socket.
|
||||
*/
|
||||
void setRawOption(RawSocketOption option);
|
||||
|
||||
/**
|
||||
* Returns the port used by this socket.
|
||||
*
|
||||
* Throws a [SocketException] if the socket is closed.
|
||||
*/
|
||||
int get port;
|
||||
|
||||
/**
|
||||
* Returns the remote port connected to by this socket.
|
||||
*
|
||||
* Throws a [SocketException] if the socket is closed.
|
||||
*/
|
||||
int get remotePort;
|
||||
|
||||
/**
|
||||
* Returns the [InternetAddress] used to connect this socket.
|
||||
*
|
||||
* Throws a [SocketException] if the socket is closed.
|
||||
*/
|
||||
InternetAddress get address;
|
||||
|
||||
/**
|
||||
* Returns the remote [InternetAddress] connected to by this socket.
|
||||
*
|
||||
* Throws a [SocketException] if the socket is closed.
|
||||
*/
|
||||
InternetAddress get remoteAddress;
|
||||
|
||||
|
|
|
@ -510,7 +510,7 @@ class _ProcessImpl extends _ProcessImplNativeWrapper implements Process {
|
|||
_stdout ?? (throw StateError("Process is detached"));
|
||||
|
||||
Stream<List<int>> get stderr =>
|
||||
_stdout ?? (throw StateError("Process is detached"));
|
||||
_stderr ?? (throw StateError("Process is detached"));
|
||||
|
||||
IOSink get stdin => _stdin ?? (throw StateError("Process is detached"));
|
||||
|
||||
|
|
|
@ -12,8 +12,6 @@ import 'dart:io';
|
|||
import "package:async_helper/async_helper.dart";
|
||||
import "package:expect/expect.dart";
|
||||
|
||||
import "process_test_util.dart";
|
||||
|
||||
void test() {
|
||||
asyncStart();
|
||||
var script =
|
||||
|
@ -27,10 +25,10 @@ void test() {
|
|||
future.then((process) {
|
||||
Expect.isNotNull(process.pid);
|
||||
Expect.isTrue(process.pid is int);
|
||||
Expect.isNull(process.exitCode);
|
||||
Expect.isNull(process.stderr);
|
||||
Expect.isNull(process.stdin);
|
||||
Expect.isNull(process.stdout);
|
||||
Expect.throwsStateError(() => process.exitCode);
|
||||
Expect.throwsStateError(() => process.stderr);
|
||||
Expect.throwsStateError(() => process.stdin);
|
||||
Expect.throwsStateError(() => process.stdout);
|
||||
Expect.isTrue(process.kill());
|
||||
}).whenComplete(() {
|
||||
asyncEnd();
|
||||
|
@ -47,7 +45,7 @@ void testWithStdio() {
|
|||
future.then((process) {
|
||||
Expect.isNotNull(process.pid);
|
||||
Expect.isTrue(process.pid is int);
|
||||
Expect.isNull(process.exitCode);
|
||||
Expect.throwsStateError(() => process.exitCode);
|
||||
var message = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
|
||||
process.stdin.add(message);
|
||||
process.stdin.flush().then((_) => process.stdin.close());
|
||||
|
|
Loading…
Reference in a new issue