Skip to content

Commit d8365a8

Browse files
authored
Merge pull request #1 from TerminalStudio/master
Update Fork.
2 parents a850658 + 47f2712 commit d8365a8

12 files changed

+292
-236
lines changed

.github/workflows/dart.yml

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
name: Dart
2+
3+
on:
4+
push:
5+
branches: [ master ]
6+
pull_request:
7+
branches: [ master ]
8+
9+
jobs:
10+
test:
11+
runs-on: ${{ matrix.os }}
12+
strategy:
13+
matrix:
14+
os: [ubuntu-latest, macos-latest, windows-latest]
15+
# sdk: [stable, beta, dev, 2.10.3, 2.12.0-29.10.beta]
16+
sdk: [stable, dev]
17+
18+
steps:
19+
- uses: actions/checkout@v2
20+
- uses: dart-lang/setup-dart@v1
21+
with:
22+
sdk: ${{ matrix.sdk }}
23+
24+
- name: Print Dart SDK version
25+
run: dart --version
26+
27+
- name: Install dependencies
28+
run: dart pub get
29+
30+
# Uncomment this step to verify the use of 'dart format' on each commit.
31+
# - name: Verify formatting
32+
# run: dart format --output=none --set-exit-if-changed .
33+
34+
# Consider passing '--fatal-infos' for slightly stricter analysis.
35+
- name: Analyze project source
36+
run: dart analyze
37+
38+
# Your project will need to have tests in test/ and a dependency on
39+
# package:test for this step to succeed. Note that Flutter projects will
40+
# want to change this to 'flutter test'.
41+
- name: Run tests
42+
run: dart test

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 0.2.0-pre
2+
3+
- Using forkpty to set up the pty connection [#2](https://github.com/TerminalStudio/pty/pull/2), thanks [@devmil](https://github.com/devmil)
4+
15
## 0.1.1
26

37
- Fix pid reference

README.md

+9-6
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,24 @@
11
# pty
22

33
<p>
4-
<img alt="GitHub repo size" src="https://img.shields.io/github/repo-size/TerminalStudio/pty">
5-
<img alt="GitHub issues" src="https://img.shields.io/github/issues-raw/TerminalStudio/pty">
6-
<img alt="GitHub pull requests" src="https://img.shields.io/github/issues-pr/TerminalStudio/pty">
4+
<img alt="GitHub repo size" src="https://img.shields.io/github/repo-size/TerminalStudio/pty">
5+
<img alt="GitHub issues" src="https://img.shields.io/github/issues-raw/TerminalStudio/pty">
6+
<img alt="GitHub pull requests" src="https://img.shields.io/github/issues-pr/TerminalStudio/pty">
77
</p>
88

99
Pty for Dart and Flutter. Provides the ability to create processes with pseudo terminal file descriptors.
1010

1111
## Status
1212

13+
[![test](https://github.com/TerminalStudio/pty/actions/workflows/dart.yml/badge.svg)](https://github.com/TerminalStudio/pty/actions/workflows/dart.yml)
14+
15+
1316
| **Platform** | **JIT(Debug)** | **AOT(Release)** |
1417
| ------------- | :------------: | :--------------: |
15-
| **Windows** | Crash | Passed |
16-
| **Linux x64** | Passed | Passed |
18+
| **Windows** | Crash | Works |
19+
| **Linux x64** | Works | Works |
1720
| **Linux x86** | Not tested | Not tested |
18-
| **macOS** | Passed | Passed |
21+
| **macOS** | Works | Works |
1922

2023
## Usage
2124

lib/src/impl/unix.dart

+54-71
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@ void _setNonblock(int fd) {
1212

1313
flag |= consts.O_NONBLOCK;
1414

15-
print('flag $flag');
16-
1715
final ret = unix.fcntl3(fd, consts.F_SETFL, flag);
1816
if (ret == -1) {
1917
unix.perror(nullptr);
@@ -28,87 +26,73 @@ class PtyCoreUnix implements PtyCore {
2826
String? workingDirectory,
2927
Map<String, String>? environment,
3028
}) {
31-
final dev = '/dev/ptmx'.toNativeUtf8();
32-
final ptm = unix.open(dev, consts.O_RDWR | consts.O_CLOEXEC);
33-
34-
if (unix.grantpt(ptm) != 0) {
35-
throw PtyException('grantpt failed.');
36-
}
29+
var effectiveEnv = <String, String>{};
3730

38-
if (unix.unlockpt(ptm) != 0) {
39-
throw PtyException('unlockpt failed.');
40-
}
31+
effectiveEnv['TERM'] = 'xterm-256color';
32+
// Without this, tools like "vi" produce sequences that are not UTF-8 friendly
33+
effectiveEnv['LANG'] = 'en_US.UTF-8';
4134

42-
final tios = calloc<termios>();
43-
unix.tcgetattr(ptm, tios);
44-
tios.ref.c_iflag |= consts.IUTF8;
45-
tios.ref.c_iflag &= ~(consts.IXON | consts.IXOFF);
46-
unix.tcsetattr(ptm, consts.TCSANOW, tios);
47-
calloc.free(tios);
35+
var envValuesToCopy = ['LOGNAME', 'USER', 'DISPLAY', 'LC_TYPE', 'HOME'];
4836

49-
final pid = unix.fork();
50-
if (pid < 0) {
51-
throw PtyException('fork failed.');
52-
} else if (pid > 0) {
53-
// call setsid() to make parent process become session leader.
54-
unix.setsid();
55-
_setNonblock(ptm);
56-
return PtyCoreUnix._(pid, ptm);
37+
for (var entry in Platform.environment.entries) {
38+
if (envValuesToCopy.contains(entry.key)) {
39+
effectiveEnv[entry.key] = entry.value;
40+
}
5741
}
5842

59-
// final signalsToUnblock = allocate<Uint64>();
60-
// unistd.sigfillset(signalsToUnblock);
61-
// unistd.sigprocmask(SIG_UNBLOCK, signalsToUnblock, nullptr);
62-
// unistd.close(_ptm);
43+
if (environment != null) {
44+
for (var entry in environment.entries) {
45+
effectiveEnv[entry.key] = entry.value;
46+
}
47+
}
6348

64-
// open slave side of the pty
65-
final devname = unix.ptsname(ptm);
66-
final pts = unix.open(devname, consts.O_RDWR);
67-
unix.close(ptm);
49+
final pPtm = calloc<Int32>();
50+
pPtm.value = -1;
6851

69-
if (pts < 0) {
70-
throw PtyException('open pts failed.');
71-
}
52+
final sz = calloc<winsize>();
53+
sz.ref.ws_col = 80;
54+
sz.ref.ws_row = 20;
7255

73-
// redirect stdin
74-
if (unix.dup2(pts, 0) == -1) {
75-
throw PtyException('fdup2(pts, 0) ailed.');
76-
}
56+
final pid = unix.forkpty(pPtm, nullptr, nullptr, sz);
57+
calloc.free(sz);
7758

78-
// redirect stdout
79-
if (unix.dup2(pts, 1) == -1) {
80-
throw PtyException('fdup2(pts, 1) ailed.');
81-
}
59+
var ptm = pPtm.value;
60+
calloc.free(pPtm);
8261

83-
// redirect stderr
84-
if (unix.dup2(pts, 2) == -1) {
85-
throw PtyException('fdup2(pts, 2) ailed.');
86-
}
62+
if (pid < 0) {
63+
throw PtyException('fork failed.');
64+
} else if (pid == 0) {
65+
// set working directory
66+
if (workingDirectory != null) {
67+
unix.chdir(workingDirectory.toNativeUtf8());
68+
}
8769

88-
unix.close(pts);
70+
// build argv
71+
final argv = calloc<Pointer<Utf8>>(arguments.length + 2);
72+
argv.elementAt(0).value = executable.toNativeUtf8();
73+
argv.elementAt(arguments.length + 1).value = nullptr;
74+
for (var i = 0; i < arguments.length; i++) {
75+
argv.elementAt(i + 1).value = arguments[i].toNativeUtf8();
76+
}
8977

90-
// set working environment variables
91-
if (environment != null) {
92-
for (var env in environment.entries) {
93-
unix.setenv(env.key.toNativeUtf8(), env.value.toNativeUtf8(), 1);
78+
//build env
79+
final env = calloc<Pointer<Utf8>>(effectiveEnv.length + 1);
80+
env.elementAt(effectiveEnv.length).value = nullptr;
81+
var cnt = 0;
82+
for (var entry in effectiveEnv.entries) {
83+
final envVal = '${entry.key}=${entry.value}';
84+
env.elementAt(cnt).value = envVal.toNativeUtf8();
85+
cnt++;
9486
}
95-
}
9687

97-
// set working directory
98-
if (workingDirectory != null) {
99-
unix.chdir(workingDirectory.toNativeUtf8());
100-
}
88+
unix.execve(executable.toNativeUtf8(), argv, env);
89+
} else {
90+
unix.setsid();
10191

102-
// build argv
103-
final argv = calloc<Pointer<Utf8>>(arguments.length + 2);
104-
argv.elementAt(0).value = executable.toNativeUtf8();
105-
argv.elementAt(arguments.length + 1).value = nullptr;
106-
for (var i = 0; i < arguments.length; i++) {
107-
argv.elementAt(i + 1).value = arguments[i].toNativeUtf8();
92+
_setNonblock(ptm);
93+
return PtyCoreUnix._(pid, ptm);
10894
}
10995

110-
unix.execvp(executable.toNativeUtf8(), argv);
111-
11296
throw PtyException('unreachable');
11397
}
11498

@@ -121,18 +105,17 @@ class PtyCoreUnix implements PtyCore {
121105
final int _ptm;
122106
// late final int _pts;
123107

124-
static const _bufferSize = 4096;
108+
static const _bufferSize = 81920;
125109
final _buffer = calloc<Int8>(_bufferSize + 1);
126110

127111
@override
128-
String? readNonBlocking() {
112+
List<int>? readNonBlocking() {
129113
final readlen = unix.read(_ptm, _buffer.cast(), _bufferSize);
130114

131-
if (readlen == -1) {
115+
if (readlen <= 0) {
132116
return null;
133117
}
134-
135-
return _buffer.cast<Utf8>().toDartString(length: readlen);
118+
return _buffer.cast<Uint8>().asTypedList(readlen);
136119
}
137120

138121
@override

0 commit comments

Comments
 (0)