+2019-09-17 Vadim Godunko <godunko@adacore.com>
+
+ * libgnat/g-expect.ads, libgnat/g-expect.adb (Close_Input): New
+ subprogram.
+ (Get_Command_Output): Call Close_Input to close input stream.
+ (Expect_Internal): Likewise.
+ (Close): Likewise.
+ * libgnat/g-exptty.adb (Close): Likewise.
+
2019-09-17 Piotr Trojanek <trojanek@adacore.com>
* sem_util.ads, sem_util.adb (Is_Attribute_Old): New utility
Next_Filter : Filter_List;
begin
- if Descriptor.Input_Fd /= Invalid_FD then
- Close (Descriptor.Input_Fd);
- end if;
+ Close_Input (Descriptor);
- if Descriptor.Error_Fd /= Descriptor.Output_Fd then
+ if Descriptor.Error_Fd /= Descriptor.Output_Fd
+ and then Descriptor.Error_Fd /= Invalid_FD
+ then
Close (Descriptor.Error_Fd);
end if;
- Close (Descriptor.Output_Fd);
+ if Descriptor.Output_Fd /= Invalid_FD then
+ Close (Descriptor.Output_Fd);
+ end if;
-- ??? Should have timeouts for different signals
Close (Descriptor, Status);
end Close;
+ -----------------
+ -- Close_Input --
+ -----------------
+
+ procedure Close_Input (Pid : in out Process_Descriptor) is
+ begin
+ if Pid.Input_Fd /= Invalid_FD then
+ Close (Pid.Input_Fd);
+ end if;
+
+ if Pid.Output_Fd = Pid.Input_Fd then
+ Pid.Output_Fd := Invalid_FD;
+ end if;
+
+ if Pid.Error_Fd = Pid.Input_Fd then
+ Pid.Error_Fd := Invalid_FD;
+ end if;
+
+ Pid.Input_Fd := Invalid_FD;
+ end Close_Input;
+
------------
-- Expect --
------------
Result := Expect_Internal_Error;
if D /= 0 then
- Close (Descriptors (D).Input_Fd);
- Descriptors (D).Input_Fd := Invalid_FD;
+ Close_Input (Descriptors (D).all);
end if;
return;
-- Error or End of file
if N <= 0 then
- Close (Descriptors (D).Input_Fd);
- Descriptors (D).Input_Fd := Invalid_FD;
+ Close_Input (Descriptors (D).all);
Result := Expect_Process_Died;
+
return;
else
Send (Process, Input);
end if;
- Close (Process.Input_Fd);
- Process.Input_Fd := Invalid_FD;
+ Close_Input (Process);
declare
Result : Expect_Match;
-- spawns the child process (based on Cmd). On systems that support fork,
-- this procedure is executed inside the newly created process.
+ procedure Close_Input (Pid : in out Process_Descriptor);
+ -- Closes input file descriptor. Set Input_Fd to Invalid_Fd as well as
+ -- Output_Fd and Error_Fd when they share same file descriptor.
+
type Process_Descriptor is tagged record
Pid : aliased Process_Id := Invalid_Pid;
Input_Fd : GNAT.OS_Lib.File_Descriptor := GNAT.OS_Lib.Invalid_FD;
-- signal, so this needs to be done while the file descriptors are
-- still open (it used to be after the closes and that was wrong).
- if Descriptor.Input_Fd /= Invalid_FD then
- Close (Descriptor.Input_Fd);
- end if;
+ Close_Input (Descriptor);
if Descriptor.Error_Fd /= Descriptor.Output_Fd
and then Descriptor.Error_Fd /= Invalid_FD
+2019-09-17 Vadim Godunko <godunko@adacore.com>
+
+ * gnat.dg/expect3.adb: New testcase.
+
2019-09-17 Ed Schonberg <schonberg@adacore.com>
* gnat.dg/predicate13.adb, gnat.dg/predicate13.ads: New
--- /dev/null
+-- { dg-do run }
+
+with Ada.Text_IO;
+
+with GNAT.Expect.TTY;
+with GNAT.OS_Lib;
+
+procedure Expect3 is
+ Pid : GNAT.Expect.TTY.TTY_Process_Descriptor;
+ Args : GNAT.OS_Lib.Argument_List (1 .. 0);
+ Result : GNAT.Expect.Expect_Match;
+
+begin
+ Pid.Non_Blocking_Spawn ("true", Args);
+
+ begin
+ Pid.Expect (Result, ".*");
+
+ raise Program_Error;
+
+ exception
+ when GNAT.Expect.Process_Died =>
+ declare
+ File : Ada.Text_IO.File_Type;
+
+ begin
+ Ada.Text_IO.Create (File);
+ Pid.Close;
+ Ada.Text_IO.Put_Line (File, "Test of write operation");
+ Ada.Text_IO.Close (File);
+ end;
+ end;
+end Expect3;
\ No newline at end of file