11
11
import java .math .BigInteger ;
12
12
import java .math .RoundingMode ;
13
13
import java .nio .ByteBuffer ;
14
- import java .nio .channels .SocketChannel ;
15
14
import java .nio .charset .Charset ;
16
15
import java .nio .file .DirectoryStream ;
17
16
import java .nio .file .Files ;
43
42
import org .perl6 .nqp .io .IIOSeekable ;
44
43
import org .perl6 .nqp .io .IIOSyncReadable ;
45
44
import org .perl6 .nqp .io .IIOSyncWritable ;
45
+ import org .perl6 .nqp .io .ProcessHandle ;
46
+ import org .perl6 .nqp .io .ServerSocketHandle ;
46
47
import org .perl6 .nqp .io .SocketHandle ;
47
48
import org .perl6 .nqp .io .StandardReadHandle ;
48
49
import org .perl6 .nqp .io .StandardWriteHandle ;
@@ -281,21 +282,59 @@ public static SixModelObject openasync(String path, String mode, ThreadContext t
281
282
return h ;
282
283
}
283
284
284
- public static SixModelObject socket (ThreadContext tc ) {
285
+ public static SixModelObject socket (long listener , ThreadContext tc ) {
285
286
SixModelObject IOType = tc .curFrame .codeRef .staticInfo .compUnit .hllConfig .ioType ;
286
287
IOHandleInstance h = (IOHandleInstance )IOType .st .REPR .allocate (tc , IOType .st );
287
- h .handle = new SocketHandle (tc );
288
+ if (listener == 0 ) {
289
+ h .handle = new SocketHandle (tc );
290
+ } else if (listener > 0 ) {
291
+ h .handle = new ServerSocketHandle (tc );
292
+ } else {
293
+ ExceptionHandling .dieInternal (tc ,
294
+ "Socket handle does not support a negative listener value" );
295
+ }
288
296
return h ;
289
297
}
290
298
291
299
public static SixModelObject connect (SixModelObject obj , String host , long port , ThreadContext tc ) {
292
300
IOHandleInstance h = (IOHandleInstance )obj ;
293
301
if (h .handle instanceof SocketHandle ) {
294
302
((SocketHandle )h .handle ).connect (tc , host , (int ) port );
303
+ } else {
304
+ ExceptionHandling .dieInternal (tc ,
305
+ "This handle does not support connect" );
306
+ }
307
+ return obj ;
308
+ }
309
+
310
+ public static SixModelObject bindsock (SixModelObject obj , String host , long port , ThreadContext tc ) {
311
+ IOHandleInstance h = (IOHandleInstance )obj ;
312
+ if (h .handle instanceof ServerSocketHandle ) {
313
+ ((ServerSocketHandle )h .handle ).bind (tc , host , (int ) port );
314
+ } else {
315
+ ExceptionHandling .dieInternal (tc ,
316
+ "This handle does not support bind" );
295
317
}
296
318
return obj ;
297
319
}
298
320
321
+ public static SixModelObject accept (SixModelObject obj , ThreadContext tc ) {
322
+ IOHandleInstance listener = (IOHandleInstance )obj ;
323
+ if (listener .handle instanceof ServerSocketHandle ) {
324
+ SocketHandle handle = ((ServerSocketHandle )listener .handle ).accept (tc );
325
+ if (handle != null ) {
326
+ SixModelObject IOType = tc .curFrame .codeRef .staticInfo .compUnit .hllConfig .ioType ;
327
+ IOHandleInstance h = (IOHandleInstance )IOType .st .REPR .allocate (tc , IOType .st );
328
+ h .handle = handle ;
329
+ return h ;
330
+ }
331
+ } else {
332
+ ExceptionHandling .dieInternal (tc ,
333
+ "This handle does not support accept" );
334
+ }
335
+ return null ;
336
+ }
337
+
299
338
public static long filereadable (String path , ThreadContext tc ) {
300
339
Path path_o ;
301
340
long res ;
@@ -714,29 +753,80 @@ public static long link(String before, String after, ThreadContext tc) {
714
753
}
715
754
return 0 ;
716
755
}
756
+
757
+ public static SixModelObject openpipe (String cmd , String dir , SixModelObject envObj , ThreadContext tc ) {
758
+ Map <String , String > env = new HashMap <String , String >();
759
+ SixModelObject iter = iter (envObj , tc );
760
+ while (istrue (iter , tc ) != 0 ) {
761
+ SixModelObject kv = iter .shift_boxed (tc );
762
+ String key = iterkey_s (kv , tc );
763
+ String value = unbox_s (iterval (kv , tc ), tc );
764
+ env .put (key , value );
765
+ }
766
+
767
+ SixModelObject IOType = tc .curFrame .codeRef .staticInfo .compUnit .hllConfig .ioType ;
768
+ IOHandleInstance h = (IOHandleInstance )IOType .st .REPR .allocate (tc , IOType .st );
769
+ h .handle = new ProcessHandle (tc , cmd , dir , env );
770
+ return h ;
771
+ }
772
+
717
773
718
774
// To be removed once shell3 is adopted
719
775
public static long shell1 (String cmd , ThreadContext tc ) {
720
776
return shell3 (cmd , cwd (), getenvhash (tc ), tc );
721
777
}
722
778
723
779
public static long shell3 (String cmd , String dir , SixModelObject envObj , ThreadContext tc ) {
780
+ Map <String , String > env = new HashMap <String , String >();
781
+ SixModelObject iter = iter (envObj , tc );
782
+ while (istrue (iter , tc ) != 0 ) {
783
+ SixModelObject kv = iter .shift_boxed (tc );
784
+ String key = iterkey_s (kv , tc );
785
+ String value = unbox_s (iterval (kv , tc ), tc );
786
+ env .put (key , value );
787
+ }
788
+
789
+ List <String > args = new ArrayList <String >();
790
+
791
+ String os = System .getProperty ("os.name" ).toLowerCase ();
792
+ if (os .indexOf ("win" ) >= 0 ) {
793
+ args .add ("cmd" );
794
+ args .add ("/c" );
795
+ args .add (cmd .replace ('/' , '\\' ));
796
+ } else {
797
+ args .add ("sh" );
798
+ args .add ("-c" );
799
+ args .add (cmd );
800
+ }
801
+
802
+ return spawn (args , dir , env );
803
+ }
804
+
805
+ public static long spawn (SixModelObject argsObj , String dir , SixModelObject envObj , ThreadContext tc ) {
806
+ List <String > args = new ArrayList <String >();
807
+ SixModelObject argIter = iter (argsObj , tc );
808
+ while (istrue (argIter , tc ) != 0 ) {
809
+ SixModelObject v = argIter .shift_boxed (tc );
810
+ String arg = v .get_str (tc );
811
+ args .add (arg );
812
+ }
813
+
814
+ Map <String , String > env = new HashMap <String , String >();
815
+ SixModelObject iter = iter (envObj , tc );
816
+ while (istrue (iter , tc ) != 0 ) {
817
+ SixModelObject kv = iter .shift_boxed (tc );
818
+ String key = iterkey_s (kv , tc );
819
+ String value = unbox_s (iterval (kv , tc ), tc );
820
+ env .put (key , value );
821
+ }
822
+
823
+ return spawn (args , dir , env );
824
+ }
825
+
826
+ private static long spawn (List <String > args , String dir , Map <String , String > env ) {
724
827
long retval = 255 ;
725
828
try {
726
- Map <String , String > env = new HashMap <String , String >();
727
-
728
- SixModelObject iter = iter (envObj , tc );
729
- while (istrue (iter , tc ) != 0 ) {
730
- SixModelObject kv = iter .shift_boxed (tc );
731
- String key = iterkey_s (kv , tc );
732
- String value = unbox_s (iterval (kv , tc ), tc );
733
- env .put (key , value );
734
- }
735
-
736
- String os = System .getProperty ("os.name" ).toLowerCase ();
737
- ProcessBuilder pb = os .indexOf ("win" ) >= 0
738
- ? new ProcessBuilder ("cmd" , "/c" , cmd .replace ('/' , '\\' ))
739
- : new ProcessBuilder ("sh" , "-c" , cmd );
829
+ ProcessBuilder pb = new ProcessBuilder (args );
740
830
pb .directory (new File (dir ));
741
831
742
832
// Clear the JVM inherited environment and use provided only
@@ -745,13 +835,21 @@ public static long shell3(String cmd, String dir, SixModelObject envObj, ThreadC
745
835
pbEnv .putAll (env );
746
836
747
837
Process proc = pb .inheritIO ().start ();
748
- proc .waitFor ();
838
+
839
+ boolean finished = false ;
840
+ do {
841
+ try {
842
+ proc .waitFor ();
843
+ finished = true ;
844
+ } catch (InterruptedException e ) {
845
+ }
846
+ } while (!finished );
847
+
749
848
retval = proc .exitValue ();
750
849
}
751
850
catch (IOException e ) {
752
851
}
753
- catch (InterruptedException e ) {
754
- }
852
+
755
853
/* Return exit code left shifted by 8 for POSIX emulation. */
756
854
return retval << 8 ;
757
855
}
0 commit comments