Ian Hickson 449f4a6673
License update (#45373)
* Update project.pbxproj files to say Flutter rather than Chromium

Also, the templates now have an empty organization so that we don't cause people to give their apps a Flutter copyright.

* Update the copyright notice checker to require a standard notice on all files

* Update copyrights on Dart files. (This was a mechanical commit.)

* Fix weird license headers on Dart files that deviate from our conventions; relicense Shrine.

Some were already marked "The Flutter Authors", not clear why. Their
dates have been normalized. Some were missing the blank line after the
license. Some were randomly different in trivial ways for no apparent
reason (e.g. missing the trailing period).

* Clean up the copyrights in non-Dart files. (Manual edits.)

Also, make sure templates don't have copyrights.

* Fix some more ORGANIZATIONNAMEs
2019-11-27 15:04:02 -08:00

247 lines
8.5 KiB
Dart

// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/// This file serves as the single point of entry into the `dart:io` APIs
/// within Flutter tools.
///
/// In order to make Flutter tools more testable, we use the `FileSystem` APIs
/// in `package:file` rather than using the `dart:io` file APIs directly (see
/// `file_system.dart`). Doing so allows us to swap out local file system
/// access with mockable (or in-memory) file systems, making our tests hermetic
/// vis-a-vis file system access.
///
/// We also use `package:platform` to provide an abstraction away from the
/// static methods in the `dart:io` `Platform` class (see `platform.dart`). As
/// such, do not export Platform from this file!
///
/// To ensure that all file system and platform API access within Flutter tools
/// goes through the proper APIs, we forbid direct imports of `dart:io` (via a
/// test), forcing all callers to instead import this file, which exports the
/// blessed subset of `dart:io` that is legal to use in Flutter tools.
///
/// Because of the nature of this file, it is important that **platform and file
/// APIs not be exported from `dart:io` in this file**! Moreover, be careful
/// about any additional exports that you add to this file, as doing so will
/// increase the API surface that we have to test in Flutter tools, and the APIs
/// in `dart:io` can sometimes be hard to use in tests.
import 'dart:async';
import 'dart:io' as io show exit, IOSink, Process, ProcessInfo, ProcessSignal,
stderr, stdin, Stdin, StdinException, Stdout, stdout;
import 'package:meta/meta.dart';
import 'context.dart';
import 'platform.dart';
import 'process.dart';
export 'dart:io'
show
BytesBuilder,
CompressionOptions,
// Directory, NO! Use `file_system.dart`
exitCode,
// File, NO! Use `file_system.dart`
// FileSystemEntity, NO! Use `file_system.dart`
gzip,
HandshakeException,
HttpClient,
HttpClientRequest,
HttpClientResponse,
HttpClientResponseCompressionState,
HttpException,
HttpHeaders,
HttpRequest,
HttpResponse,
HttpServer,
HttpStatus,
InternetAddress,
InternetAddressType,
IOException,
IOSink,
// Link NO! Use `file_system.dart`
pid,
// Platform NO! use `platform.dart`
Process,
ProcessException,
// ProcessInfo, NO! use `io.dart`
ProcessResult,
// ProcessSignal NO! Use [ProcessSignal] below.
ProcessStartMode,
// RandomAccessFile NO! Use `file_system.dart`
ServerSocket,
// stderr, NO! Use `io.dart`
// stdin, NO! Use `io.dart`
Stdin,
StdinException,
// stdout, NO! Use `io.dart`
Stdout,
Socket,
SocketException,
systemEncoding,
WebSocket,
WebSocketException,
WebSocketTransformer;
/// Exits the process with the given [exitCode].
typedef ExitFunction = void Function(int exitCode);
const ExitFunction _defaultExitFunction = io.exit;
ExitFunction _exitFunction = _defaultExitFunction;
/// Exits the process.
///
/// This is analogous to the `exit` function in `dart:io`, except that this
/// function may be set to a testing-friendly value by calling
/// [setExitFunctionForTests] (and then restored to its default implementation
/// with [restoreExitFunction]). The default implementation delegates to
/// `dart:io`.
ExitFunction get exit => _exitFunction;
/// Sets the [exit] function to a function that throws an exception rather
/// than exiting the process; this is intended for testing purposes.
@visibleForTesting
void setExitFunctionForTests([ ExitFunction exitFunction ]) {
_exitFunction = exitFunction ?? (int exitCode) {
throw ProcessExit(exitCode, immediate: true);
};
}
/// Restores the [exit] function to the `dart:io` implementation.
@visibleForTesting
void restoreExitFunction() {
_exitFunction = _defaultExitFunction;
}
/// A portable version of [io.ProcessSignal].
///
/// Listening on signals that don't exist on the current platform is just a
/// no-op. This is in contrast to [io.ProcessSignal], where listening to
/// non-existent signals throws an exception.
///
/// This class does NOT implement io.ProcessSignal, because that class uses
/// private fields. This means it cannot be used with, e.g., [Process.killPid].
/// Alternative implementations of the relevant methods that take
/// [ProcessSignal] instances are available on this class (e.g. "send").
class ProcessSignal {
@visibleForTesting
const ProcessSignal(this._delegate);
static const ProcessSignal SIGWINCH = _PosixProcessSignal._(io.ProcessSignal.sigwinch);
static const ProcessSignal SIGTERM = _PosixProcessSignal._(io.ProcessSignal.sigterm);
static const ProcessSignal SIGUSR1 = _PosixProcessSignal._(io.ProcessSignal.sigusr1);
static const ProcessSignal SIGUSR2 = _PosixProcessSignal._(io.ProcessSignal.sigusr2);
static const ProcessSignal SIGINT = ProcessSignal(io.ProcessSignal.sigint);
static const ProcessSignal SIGKILL = ProcessSignal(io.ProcessSignal.sigkill);
final io.ProcessSignal _delegate;
Stream<ProcessSignal> watch() {
return _delegate.watch().map<ProcessSignal>((io.ProcessSignal signal) => this);
}
/// Sends the signal to the given process (identified by pid).
///
/// Returns true if the signal was delivered, false otherwise.
///
/// On Windows, this can only be used with [ProcessSignal.SIGTERM], which
/// terminates the process.
///
/// This is implemented by sending the signal using [Process.killPid].
bool send(int pid) {
assert(!platform.isWindows || this == ProcessSignal.SIGTERM);
return io.Process.killPid(pid, _delegate);
}
@override
String toString() => _delegate.toString();
}
/// A [ProcessSignal] that is only available on Posix platforms.
///
/// Listening to a [_PosixProcessSignal] is a no-op on Windows.
class _PosixProcessSignal extends ProcessSignal {
const _PosixProcessSignal._(io.ProcessSignal wrappedSignal) : super(wrappedSignal);
@override
Stream<ProcessSignal> watch() {
if (platform.isWindows) {
return const Stream<ProcessSignal>.empty();
}
return super.watch();
}
}
class Stdio {
const Stdio();
Stream<List<int>> get stdin => io.stdin;
io.Stdout get stdout => io.stdout;
io.IOSink get stderr => io.stderr;
bool get hasTerminal => io.stdout.hasTerminal;
static bool _stdinHasTerminal;
/// Determines whether there is a terminal attached.
///
/// [io.Stdin.hasTerminal] only covers a subset of cases. In this check the
/// echoMode is toggled on and off to catch cases where the tool running in
/// a docker container thinks there is an attached terminal. This can cause
/// runtime errors such as "inappropriate ioctl for device" if not handled.
bool get stdinHasTerminal {
if (_stdinHasTerminal != null) {
return _stdinHasTerminal;
}
if (stdin is! io.Stdin) {
return _stdinHasTerminal = false;
}
final io.Stdin ioStdin = stdin as io.Stdin;
if (!ioStdin.hasTerminal) {
return _stdinHasTerminal = false;
}
try {
final bool currentEchoMode = ioStdin.echoMode;
ioStdin.echoMode = !currentEchoMode;
ioStdin.echoMode = currentEchoMode;
} on io.StdinException {
return _stdinHasTerminal = false;
}
return _stdinHasTerminal = true;
}
int get terminalColumns => hasTerminal ? io.stdout.terminalColumns : null;
int get terminalLines => hasTerminal ? io.stdout.terminalLines : null;
bool get supportsAnsiEscapes => hasTerminal && io.stdout.supportsAnsiEscapes;
}
Stdio get stdio => context.get<Stdio>() ?? const Stdio();
io.Stdout get stdout => stdio.stdout;
Stream<List<int>> get stdin => stdio.stdin;
io.IOSink get stderr => stdio.stderr;
bool get stdinHasTerminal => stdio.stdinHasTerminal;
/// An overridable version of io.ProcessInfo.
abstract class ProcessInfo {
factory ProcessInfo() => _DefaultProcessInfo();
static ProcessInfo get instance => context.get<ProcessInfo>();
int get currentRss;
int get maxRss;
}
ProcessInfo get processInfo => ProcessInfo.instance;
/// The default implementation of [ProcessInfo], which uses [io.ProcessInfo].
class _DefaultProcessInfo implements ProcessInfo {
@override
int get currentRss => io.ProcessInfo.currentRss;
@override
int get maxRss => io.ProcessInfo.maxRss;
}