Unix.StdIO.Mod 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. MODULE StdIO; (** AUTHOR gf; PURPOSE "Unix standard IO and argument channels *)
  2. (* Commands.Context for programs running outside Aos *)
  3. IMPORT S := SYSTEM, Modules, Commands, Streams,Pipes , Unix;
  4. CONST
  5. AddrSize = SIZEOF( ADDRESS );
  6. TYPE
  7. String=POINTER TO ARRAY OF CHAR;
  8. VAR
  9. env-: Commands.Context;
  10. stdInDecoupler: Pipes.ReadDecoupler;
  11. PROCEDURE Args(): String;
  12. VAR size, pos: SIZE; i,j: LONGINT; str: String;
  13. argc: LONGINT;
  14. argv {UNTRACED}: POINTER {UNSAFE} TO ARRAY OF POINTER {UNSAFE,UNTRACED} TO ARRAY OF CHAR;
  15. BEGIN
  16. argc := Unix.argc;
  17. argv := Unix.argv;
  18. pos := 0;
  19. FOR i := 0 TO argc-1 DO
  20. j := 0;
  21. WHILE argv[i,j] # 0X DO
  22. INC(pos); INC(j);
  23. END;
  24. INC(pos);
  25. END;
  26. size := pos + 1;
  27. NEW(str, size);
  28. pos := 0;
  29. FOR i := 0 TO argc-1 DO
  30. j := 0;
  31. WHILE argv[i,j] # 0X DO
  32. str[pos] := argv[i,j];
  33. INC(pos); INC(j);
  34. END;
  35. str[pos] := " ";
  36. INC(pos);
  37. END;
  38. str[pos] := 0X;
  39. RETURN str;
  40. END Args;
  41. PROCEDURE ReceiveStdin( VAR data: ARRAY OF CHAR; ofs, size, min: LONGINT; VAR len, res: LONGINT );
  42. VAR ures: HUGEINT; i, err: LONGINT;
  43. BEGIN
  44. len := 0;
  45. REPEAT
  46. ures := Unix.read( 0, ADDRESSOF( data[ofs] ), size );
  47. IF ures > 0 THEN
  48. INC( ofs, LONGINT(ures) ); DEC( size, LONGINT(ures) ); INC( len, LONGINT(ures) )
  49. END;
  50. IF ures < 0 THEN err := Unix.errno() END;
  51. UNTIL (len >= min) OR ((ures <= 0) & (err # Unix.EINTR) & (err # 0));
  52. IF len >= min THEN res := Streams.Ok ELSE res := Streams.EOF END;
  53. END ReceiveStdin;
  54. PROCEDURE SendStdout( CONST data: ARRAY OF CHAR; ofs, len: LONGINT; prop: BOOLEAN; VAR res: LONGINT );
  55. VAR ignore: SIZE;
  56. BEGIN
  57. ignore := Unix.write( 1, ADDRESSOF( data[ofs] ), len ); res := Streams.Ok
  58. END SendStdout;
  59. PROCEDURE SendErrout( CONST data: ARRAY OF CHAR; ofs, len: LONGINT; prop: BOOLEAN; VAR res: LONGINT );
  60. VAR ignore: SIZE;
  61. BEGIN
  62. ignore := Unix.write( 2, ADDRESSOF( data[ofs] ), len ); res := Streams.Ok
  63. END SendErrout;
  64. PROCEDURE Cleanup;
  65. BEGIN
  66. env.error.Update;
  67. env.out.Update
  68. END Cleanup;
  69. PROCEDURE Setup;
  70. VAR
  71. arg: Streams.StringReader;
  72. stdin: Streams.Reader;
  73. stdout: Streams.Writer;
  74. errout: Streams.Writer;
  75. str: String;
  76. BEGIN
  77. str := Args();
  78. NEW( arg, LEN(str) ); arg.Set(str^);
  79. NEW(stdInDecoupler, ReceiveStdin);
  80. NEW( stdin, stdInDecoupler.Receive, 1024 );
  81. NEW( stdout, SendStdout, 1024 );
  82. NEW( errout, SendErrout, 512 );
  83. NEW( env, stdin, arg, stdout, errout, NIL );
  84. Modules.InstallTermHandler( Cleanup )
  85. END Setup
  86. BEGIN
  87. Setup
  88. END StdIO.