Unix.StdIO.Mod 2.2 KB

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