13
13
import java .io .InputStream ;
14
14
import java .lang .foreign .*;
15
15
import java .lang .invoke .MethodHandle ;
16
+ import java .lang .invoke .MethodHandles ;
17
+ import java .lang .invoke .MethodType ;
16
18
import java .lang .invoke .VarHandle ;
17
19
import java .nio .file .Files ;
18
20
import java .nio .file .Path ;
33
35
import org .jline .terminal .spi .TerminalProvider ;
34
36
import org .jline .utils .OSUtils ;
35
37
36
- @ SuppressWarnings ("preview " )
38
+ @ SuppressWarnings ("restricted " )
37
39
class CLibrary {
38
40
39
41
private static final Logger logger = Logger .getLogger ("org.jline" );
@@ -51,8 +53,8 @@ static class winsize {
51
53
ValueLayout .JAVA_SHORT .withName ("ws_col" ),
52
54
ValueLayout .JAVA_SHORT ,
53
55
ValueLayout .JAVA_SHORT );
54
- ws_row = LAYOUT . varHandle ( MemoryLayout .PathElement .groupElement ("ws_row" ));
55
- ws_col = LAYOUT . varHandle ( MemoryLayout .PathElement .groupElement ("ws_col" ));
56
+ ws_row = FfmTerminalProvider . lookupVarHandle ( LAYOUT , MemoryLayout .PathElement .groupElement ("ws_row" ));
57
+ ws_col = FfmTerminalProvider . lookupVarHandle ( LAYOUT , MemoryLayout .PathElement .groupElement ("ws_col" ));
56
58
}
57
59
58
60
private final java .lang .foreign .MemorySegment seg ;
@@ -97,24 +99,59 @@ static class termios {
97
99
private static final VarHandle c_oflag ;
98
100
private static final VarHandle c_cflag ;
99
101
private static final VarHandle c_lflag ;
102
+ private static final long c_cc_offset ;
100
103
private static final VarHandle c_ispeed ;
101
104
private static final VarHandle c_ospeed ;
102
105
103
106
static {
104
- LAYOUT = MemoryLayout .structLayout (
105
- ValueLayout .JAVA_LONG .withName ("c_iflag" ),
106
- ValueLayout .JAVA_LONG .withName ("c_oflag" ),
107
- ValueLayout .JAVA_LONG .withName ("c_cflag" ),
108
- ValueLayout .JAVA_LONG .withName ("c_lflag" ),
109
- MemoryLayout .sequenceLayout (32 , ValueLayout .JAVA_BYTE ).withName ("c_cc" ),
110
- ValueLayout .JAVA_LONG .withName ("c_ispeed" ),
111
- ValueLayout .JAVA_LONG .withName ("c_ospeed" ));
112
- c_iflag = LAYOUT .varHandle (MemoryLayout .PathElement .groupElement ("c_iflag" ));
113
- c_oflag = LAYOUT .varHandle (MemoryLayout .PathElement .groupElement ("c_oflag" ));
114
- c_cflag = LAYOUT .varHandle (MemoryLayout .PathElement .groupElement ("c_cflag" ));
115
- c_lflag = LAYOUT .varHandle (MemoryLayout .PathElement .groupElement ("c_lflag" ));
116
- c_ispeed = LAYOUT .varHandle (MemoryLayout .PathElement .groupElement ("c_ispeed" ));
117
- c_ospeed = LAYOUT .varHandle (MemoryLayout .PathElement .groupElement ("c_ospeed" ));
107
+ if (OSUtils .IS_OSX ) {
108
+ LAYOUT = MemoryLayout .structLayout (
109
+ ValueLayout .JAVA_LONG .withName ("c_iflag" ),
110
+ ValueLayout .JAVA_LONG .withName ("c_oflag" ),
111
+ ValueLayout .JAVA_LONG .withName ("c_cflag" ),
112
+ ValueLayout .JAVA_LONG .withName ("c_lflag" ),
113
+ MemoryLayout .sequenceLayout (32 , ValueLayout .JAVA_BYTE ).withName ("c_cc" ),
114
+ ValueLayout .JAVA_LONG .withName ("c_ispeed" ),
115
+ ValueLayout .JAVA_LONG .withName ("c_ospeed" ));
116
+ } else if (OSUtils .IS_LINUX ) {
117
+ LAYOUT = MemoryLayout .structLayout (
118
+ ValueLayout .JAVA_INT .withName ("c_iflag" ),
119
+ ValueLayout .JAVA_INT .withName ("c_oflag" ),
120
+ ValueLayout .JAVA_INT .withName ("c_cflag" ),
121
+ ValueLayout .JAVA_INT .withName ("c_lflag" ),
122
+ ValueLayout .JAVA_BYTE .withName ("c_line" ),
123
+ MemoryLayout .sequenceLayout (32 , ValueLayout .JAVA_BYTE ).withName ("c_cc" ),
124
+ MemoryLayout .paddingLayout (3 ),
125
+ ValueLayout .JAVA_INT .withName ("c_ispeed" ),
126
+ ValueLayout .JAVA_INT .withName ("c_ospeed" ));
127
+ } else {
128
+ throw new IllegalStateException ("Unsupported system!" );
129
+ }
130
+ c_iflag = adjust2LinuxHandle (
131
+ FfmTerminalProvider .lookupVarHandle (LAYOUT , MemoryLayout .PathElement .groupElement ("c_iflag" )));
132
+ c_oflag = adjust2LinuxHandle (
133
+ FfmTerminalProvider .lookupVarHandle (LAYOUT , MemoryLayout .PathElement .groupElement ("c_oflag" )));
134
+ c_cflag = adjust2LinuxHandle (
135
+ FfmTerminalProvider .lookupVarHandle (LAYOUT , MemoryLayout .PathElement .groupElement ("c_cflag" )));
136
+ c_lflag = adjust2LinuxHandle (
137
+ FfmTerminalProvider .lookupVarHandle (LAYOUT , MemoryLayout .PathElement .groupElement ("c_lflag" )));
138
+ c_cc_offset = LAYOUT .byteOffset (MemoryLayout .PathElement .groupElement ("c_cc" ));
139
+ c_ispeed = adjust2LinuxHandle (
140
+ FfmTerminalProvider .lookupVarHandle (LAYOUT , MemoryLayout .PathElement .groupElement ("c_ispeed" )));
141
+ c_ospeed = adjust2LinuxHandle (
142
+ FfmTerminalProvider .lookupVarHandle (LAYOUT , MemoryLayout .PathElement .groupElement ("c_ospeed" )));
143
+ }
144
+
145
+ private static VarHandle adjust2LinuxHandle (VarHandle v ) {
146
+ if (OSUtils .IS_LINUX ) {
147
+ MethodHandle id = MethodHandles .identity (int .class );
148
+ v = MethodHandles .filterValue (
149
+ v ,
150
+ MethodHandles .explicitCastArguments (id , MethodType .methodType (int .class , long .class )),
151
+ MethodHandles .explicitCastArguments (id , MethodType .methodType (long .class , int .class )));
152
+ }
153
+
154
+ return v ;
118
155
}
119
156
120
157
private final java .lang .foreign .MemorySegment seg ;
@@ -211,14 +248,18 @@ static class termios {
211
248
c_cc [VINTR ] = (byte ) t .getControlChar (Attributes .ControlChar .VINTR );
212
249
c_cc [VQUIT ] = (byte ) t .getControlChar (Attributes .ControlChar .VQUIT );
213
250
c_cc [VSUSP ] = (byte ) t .getControlChar (Attributes .ControlChar .VSUSP );
214
- c_cc [VDSUSP ] = (byte ) t .getControlChar (Attributes .ControlChar .VDSUSP );
251
+ if (VDSUSP != (-1 )) {
252
+ c_cc [VDSUSP ] = (byte ) t .getControlChar (Attributes .ControlChar .VDSUSP );
253
+ }
215
254
c_cc [VSTART ] = (byte ) t .getControlChar (Attributes .ControlChar .VSTART );
216
255
c_cc [VSTOP ] = (byte ) t .getControlChar (Attributes .ControlChar .VSTOP );
217
256
c_cc [VLNEXT ] = (byte ) t .getControlChar (Attributes .ControlChar .VLNEXT );
218
257
c_cc [VDISCARD ] = (byte ) t .getControlChar (Attributes .ControlChar .VDISCARD );
219
258
c_cc [VMIN ] = (byte ) t .getControlChar (Attributes .ControlChar .VMIN );
220
259
c_cc [VTIME ] = (byte ) t .getControlChar (Attributes .ControlChar .VTIME );
221
- c_cc [VSTATUS ] = (byte ) t .getControlChar (Attributes .ControlChar .VSTATUS );
260
+ if (VSTATUS != (-1 )) {
261
+ c_cc [VSTATUS ] = (byte ) t .getControlChar (Attributes .ControlChar .VSTATUS );
262
+ }
222
263
c_cc ().copyFrom (java .lang .foreign .MemorySegment .ofArray (c_cc ));
223
264
}
224
265
@@ -259,7 +300,7 @@ void c_lflag(long f) {
259
300
}
260
301
261
302
java .lang .foreign .MemorySegment c_cc () {
262
- return seg .asSlice (32 , 20 );
303
+ return seg .asSlice (c_cc_offset , 20 );
263
304
}
264
305
265
306
long c_ispeed () {
@@ -377,14 +418,18 @@ public Attributes asAttributes() {
377
418
cc .put (Attributes .ControlChar .VINTR , (int ) c_cc [VINTR ]);
378
419
cc .put (Attributes .ControlChar .VQUIT , (int ) c_cc [VQUIT ]);
379
420
cc .put (Attributes .ControlChar .VSUSP , (int ) c_cc [VSUSP ]);
380
- cc .put (Attributes .ControlChar .VDSUSP , (int ) c_cc [VDSUSP ]);
421
+ if (VDSUSP != (-1 )) {
422
+ cc .put (Attributes .ControlChar .VDSUSP , (int ) c_cc [VDSUSP ]);
423
+ }
381
424
cc .put (Attributes .ControlChar .VSTART , (int ) c_cc [VSTART ]);
382
425
cc .put (Attributes .ControlChar .VSTOP , (int ) c_cc [VSTOP ]);
383
426
cc .put (Attributes .ControlChar .VLNEXT , (int ) c_cc [VLNEXT ]);
384
427
cc .put (Attributes .ControlChar .VDISCARD , (int ) c_cc [VDISCARD ]);
385
428
cc .put (Attributes .ControlChar .VMIN , (int ) c_cc [VMIN ]);
386
429
cc .put (Attributes .ControlChar .VTIME , (int ) c_cc [VTIME ]);
387
- cc .put (Attributes .ControlChar .VSTATUS , (int ) c_cc [VSTATUS ]);
430
+ if (VSTATUS != (-1 )) {
431
+ cc .put (Attributes .ControlChar .VSTATUS , (int ) c_cc [VSTATUS ]);
432
+ }
388
433
// Return
389
434
return attr ;
390
435
}
@@ -630,19 +675,19 @@ static Pty openpty(TerminalProvider provider, Attributes attr, Size size) {
630
675
private static final int VWERASE ;
631
676
private static final int VKILL ;
632
677
private static final int VREPRINT ;
633
- private static int VERASE2 ;
678
+ private static final int VERASE2 ;
634
679
private static final int VINTR ;
635
680
private static final int VQUIT ;
636
681
private static final int VSUSP ;
637
- private static int VDSUSP ;
682
+ private static final int VDSUSP ;
638
683
private static final int VSTART ;
639
684
private static final int VSTOP ;
640
685
private static final int VLNEXT ;
641
686
private static final int VDISCARD ;
642
687
private static final int VMIN ;
643
- private static int VSWTC ;
688
+ private static final int VSWTC ;
644
689
private static final int VTIME ;
645
- private static int VSTATUS ;
690
+ private static final int VSTATUS ;
646
691
647
692
private static final int IGNBRK ;
648
693
private static final int BRKINT ;
@@ -784,6 +829,9 @@ static Pty openpty(TerminalProvider provider, Attributes attr, Size size) {
784
829
VWERASE = 14 ;
785
830
VLNEXT = 15 ;
786
831
VEOL2 = 16 ;
832
+ VERASE2 = -1 ;
833
+ VDSUSP = -1 ;
834
+ VSTATUS = -1 ;
787
835
788
836
IGNBRK = 0x0000001 ;
789
837
BRKINT = 0x0000002 ;
@@ -906,6 +954,9 @@ static Pty openpty(TerminalProvider provider, Attributes attr, Size size) {
906
954
VWERASE = 14 ;
907
955
VLNEXT = 15 ;
908
956
VEOL2 = 16 ;
957
+ VERASE2 = -1 ;
958
+ VDSUSP = -1 ;
959
+ VSTATUS = -1 ;
909
960
910
961
IGNBRK = 0x0000001 ;
911
962
BRKINT = 0x0000002 ;
@@ -1026,6 +1077,8 @@ static Pty openpty(TerminalProvider provider, Attributes attr, Size size) {
1026
1077
VMIN = 16 ;
1027
1078
VTIME = 17 ;
1028
1079
VSTATUS = 18 ;
1080
+ VERASE2 = -1 ;
1081
+ VSWTC = -1 ;
1029
1082
1030
1083
IGNBRK = 0x00000001 ;
1031
1084
BRKINT = 0x00000002 ;
@@ -1119,6 +1172,7 @@ static Pty openpty(TerminalProvider provider, Attributes attr, Size size) {
1119
1172
VMIN = 16 ;
1120
1173
VTIME = 17 ;
1121
1174
VSTATUS = 18 ;
1175
+ VSWTC = -1 ;
1122
1176
1123
1177
IGNBRK = 0x0000001 ;
1124
1178
BRKINT = 0x0000002 ;
0 commit comments