@@ -12,8 +12,6 @@ void _setNonblock(int fd) {
12
12
13
13
flag | = consts.O_NONBLOCK ;
14
14
15
- print ('flag $flag ' );
16
-
17
15
final ret = unix.fcntl3 (fd, consts.F_SETFL , flag);
18
16
if (ret == - 1 ) {
19
17
unix.perror (nullptr);
@@ -28,87 +26,73 @@ class PtyCoreUnix implements PtyCore {
28
26
String ? workingDirectory,
29
27
Map <String , String >? environment,
30
28
}) {
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 > {};
37
30
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' ;
41
34
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' ];
48
36
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
+ }
57
41
}
58
42
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
+ }
63
48
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 ;
68
51
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 ;
72
55
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);
77
58
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);
82
61
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
+ }
87
69
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
+ }
89
77
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++ ;
94
86
}
95
- }
96
87
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 ();
101
91
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);
108
94
}
109
95
110
- unix.execvp (executable.toNativeUtf8 (), argv);
111
-
112
96
throw PtyException ('unreachable' );
113
97
}
114
98
@@ -121,18 +105,17 @@ class PtyCoreUnix implements PtyCore {
121
105
final int _ptm;
122
106
// late final int _pts;
123
107
124
- static const _bufferSize = 4096 ;
108
+ static const _bufferSize = 81920 ;
125
109
final _buffer = calloc <Int8 >(_bufferSize + 1 );
126
110
127
111
@override
128
- String ? readNonBlocking () {
112
+ List < int > ? readNonBlocking () {
129
113
final readlen = unix.read (_ptm, _buffer.cast (), _bufferSize);
130
114
131
- if (readlen == - 1 ) {
115
+ if (readlen <= 0 ) {
132
116
return null ;
133
117
}
134
-
135
- return _buffer.cast <Utf8 >().toDartString (length: readlen);
118
+ return _buffer.cast <Uint8 >().asTypedList (readlen);
136
119
}
137
120
138
121
@override
0 commit comments