ashell_1.3.0_8d2540e0/library/source/shell-commands.ads

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
private
with
     Ada.Containers.Indefinite_Vectors,
     Ada.Containers.Indefinite_Holders;


package Shell.Commands
--
-- For task safe 'Run' commands and pipelines,        see the 'Safe'   child package.
-- For commands and pipelines run from a single task, see the 'Unsafe' child package.
--
is
   type Command is abstract tagged private;

   Command_Error : exception;


   function  Image     (The_Command : in Command)       return String;
   function  Name      (The_Command : in Command)       return String;
   function  Arguments (The_Command : in Command)       return String;
   function  Failed    (The_Command : in Command'Class) return Boolean;


   -------------------
   --- Command Results
   --

   type Command_Results (Output_Size : Data_Offset;
                         Error_Size  : Data_Offset) is private;

   function  Results_Of (The_Command : in out Command'Class)   return Command_Results;
   function  Output_Of  (The_Results : in     Command_Results) return Data;
   function  Errors_Of  (The_Results : in     Command_Results) return Data;


   ---------
   --- Start ~ Commands return before the process completes.
   --

   procedure Start (The_Command   : in out Command;
                    Input         : in     Data    := No_Data;
                    Accepts_Input : in     Boolean := False;
                    Pipeline      : in     Boolean := False);

   procedure Send  (To    : in Command;
                    Input : in Data) is abstract;


   -------
   --- Run - Commands block until process completes.
   --

   procedure Run (The_Command  : in out Command;
                  Input        : in     Data    := No_Data;
                  Raise_Error  : in     Boolean := False) is abstract;

   function  Run (The_Command  : in out Command'Class;
                  Input        : in     Data    := No_Data;
                  Raise_Error  : in     Boolean := False) return Command_Results;


   type State is (Not_Started,
                  Running,
                  Paused,
                  Normal_Exit,
                  Failed_Exit,
                  Killed);

   function  Status         (The_Command : in out Command) return State;

   procedure Wait_On        (The_Command : in out Command)                is abstract;
   function  Has_Terminated (The_Command : in out Command) return Boolean is abstract;
   function  Normal_Exit    (The_Command : in     Command) return Boolean is abstract;

   procedure Kill      (The_Command : in out Command);
   procedure Interrupt (The_Command : in out Command) is abstract;
   procedure Pause     (The_Command : in out Command);
   procedure Resume    (The_Command : in out Command);



private

   type Count        is new Natural;
   type Count_Access is access all Count;

   subtype Data_Index   is Data_Offset range 1 .. Data_Offset'Last;
   package Data_Vectors is new Ada.Containers.Indefinite_Vectors (Data_Index, Data);
   subtype Data_Vector  is Data_Vectors.Vector;

   -----------
   --- Command
   --
   type Command is abstract new Ada.Finalization.Controlled with
      record
         Name       : Unbounded_String;
         Arguments  : String_Vector;
         Copy_Count : Count_Access;

         Output     : Data_Vector;
         Errors     : Data_Vector;

         Status     : State := Not_Started;
      end record;

   overriding
   procedure Adjust   (The_Command : in out Command);

   overriding
   procedure Finalize (The_Command : in out Command);

   procedure Define   (The_Command :    out Command;   Command_Line : in String);

   procedure Gather_Results (The_Command : in out Command) is null;


   -------------------
   --- Command_Results
   --
   type Command_Results (Output_Size : Data_Offset;
                         Error_Size  : Data_Offset) is
      record
         Output  : Data (1 .. Output_Size);
         Errors  : Data (1 ..  Error_Size);
      end record;


   --------------------
   --- String Utilities
   --
   function To_String_Array  (Strings  : in String_Vector) return String_Array;
   function To_Command_Lines (Pipeline : in String)        return String_Array;
   --
   -- Split a pipeline into separate command strings.


   -----------------------
   -- Spawn Server Support
   --

   type Command_Id is new Positive;

   Null_Id : constant Command_Id := Command_Id'Last;

   function Hash (Id : in Command_Id) return Ada.Containers.Hash_Type;


   package Data_Holders is new Ada.Containers.Indefinite_Holders (Element_Type => Data);
   subtype Data_Holder  is     Data_Holders.Holder;


   ------------------
   --- Server Actions
   --
   type Server_Action_Kind is (Nil,
                               New_Command, New_Pipeline, New_Input,
                               Kill, Interrupt, Pause, Resume, Stop,
                               Shutdown);

   type Server_Action (Kind : Server_Action_Kind := Nil) is
      record
         Id : Command_Id := Null_Id;

         case Kind
         is
         when New_Command =>
            Command_Line  : Unbounded_String;
            Command_Input : Data_Holder;
            Accepts_Input : Boolean;

         when New_Pipeline =>
            Pipeline       : Unbounded_String;
            Pipeline_Input : Data_Holder;

         when New_Input =>
            Data : Data_Holder;

         when Nil | Kill | Interrupt | Pause | Resume | Stop | Shutdown =>
            null;
         end case;
      end record;


   ------------------
   --- Client Actions
   --
   type Client_Action_Kind is (New_Outputs, Command_Done, Server_Done);

   type Client_Action (Kind : Client_Action_Kind) is
      record
         Id : Command_Id := Null_Id;

         case Kind
         is
            when New_Outputs =>
               Output : Data_Holder;
               Errors : Data_Holder;

            when Command_Done =>
               Normal_Exit : Boolean;

            when Server_Done =>
               null;
         end case;
      end record;



   --- Ensure mutual exclusion of 'Safe' and 'Unsafe' commands.
   --

     Safe_Commands_Are_Withed : Boolean := False;
   UnSafe_Commands_Are_Withed : Boolean := False;

   Halt_Spawn_Client : access procedure;     -- Used during elaboration of safe and unsafe command packages
                                             -- to allow elaboration of the unsafe commands package to stop
                                             -- safe commands 'Spawn_Client' task, if neccessary.


end Shell.Commands;