comparison gcc/ada/libgnat/g-expect.adb @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents 84e7813d76e9
children
comparison
equal deleted inserted replaced
131:84e7813d76e9 145:1830386684a0
4 -- -- 4 -- --
5 -- G N A T . E X P E C T -- 5 -- G N A T . E X P E C T --
6 -- -- 6 -- --
7 -- B o d y -- 7 -- B o d y --
8 -- -- 8 -- --
9 -- Copyright (C) 2000-2018, AdaCore -- 9 -- Copyright (C) 2000-2019, AdaCore --
10 -- -- 10 -- --
11 -- GNAT is free software; you can redistribute it and/or modify it under -- 11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- -- 12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 3, or (at your option) any later ver- -- 13 -- ware Foundation; either version 3, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- 14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
220 is 220 is
221 Current_Filter : Filter_List; 221 Current_Filter : Filter_List;
222 Next_Filter : Filter_List; 222 Next_Filter : Filter_List;
223 223
224 begin 224 begin
225 if Descriptor.Input_Fd /= Invalid_FD then 225 Close_Input (Descriptor);
226 Close (Descriptor.Input_Fd); 226
227 end if; 227 if Descriptor.Error_Fd /= Descriptor.Output_Fd
228 228 and then Descriptor.Error_Fd /= Invalid_FD
229 if Descriptor.Error_Fd /= Descriptor.Output_Fd then 229 then
230 Close (Descriptor.Error_Fd); 230 Close (Descriptor.Error_Fd);
231 end if; 231 end if;
232 232
233 Close (Descriptor.Output_Fd); 233 if Descriptor.Output_Fd /= Invalid_FD then
234 Close (Descriptor.Output_Fd);
235 end if;
234 236
235 -- ??? Should have timeouts for different signals 237 -- ??? Should have timeouts for different signals
236 238
237 if Descriptor.Pid > 0 then -- see comment in Send_Signal 239 if Descriptor.Pid > 0 then -- see comment in Send_Signal
238 Kill (Descriptor.Pid, Sig_Num => 9, Close => 0); 240 Kill (Descriptor.Pid, Sig_Num => 9, Close => 0);
264 Status : Integer; 266 Status : Integer;
265 pragma Unreferenced (Status); 267 pragma Unreferenced (Status);
266 begin 268 begin
267 Close (Descriptor, Status); 269 Close (Descriptor, Status);
268 end Close; 270 end Close;
271
272 -----------------
273 -- Close_Input --
274 -----------------
275
276 procedure Close_Input (Pid : in out Process_Descriptor) is
277 begin
278 if Pid.Input_Fd /= Invalid_FD then
279 Close (Pid.Input_Fd);
280 end if;
281
282 if Pid.Output_Fd = Pid.Input_Fd then
283 Pid.Output_Fd := Invalid_FD;
284 end if;
285
286 if Pid.Error_Fd = Pid.Input_Fd then
287 Pid.Error_Fd := Invalid_FD;
288 end if;
289
290 Pid.Input_Fd := Invalid_FD;
291 end Close_Input;
269 292
270 ------------ 293 ------------
271 -- Expect -- 294 -- Expect --
272 ------------ 295 ------------
273 296
628 type Integer_Array is array (Fds'Range) of Integer; 651 type Integer_Array is array (Fds'Range) of Integer;
629 Is_Set : aliased Integer_Array; 652 Is_Set : aliased Integer_Array;
630 653
631 begin 654 begin
632 for J in Descriptors'Range loop 655 for J in Descriptors'Range loop
633 if Descriptors (J) /= null then 656 if Descriptors (J) /= null
657 and then Descriptors (J).Output_Fd /= Invalid_FD
658 then
634 Fds (Fds'First + Fds_Count) := Descriptors (J).Output_Fd; 659 Fds (Fds'First + Fds_Count) := Descriptors (J).Output_Fd;
635 Fds_To_Descriptor (Fds'First + Fds_Count) := J; 660 Fds_To_Descriptor (Fds'First + Fds_Count) := J;
636 Fds_Count := Fds_Count + 1; 661 Fds_Count := Fds_Count + 1;
637 662
638 if Descriptors (J).Buffer_Size = 0 then 663 if Descriptors (J).Buffer_Size = 0 then
642 Integer'Max (Buffer_Size, Descriptors (J).Buffer_Size); 667 Integer'Max (Buffer_Size, Descriptors (J).Buffer_Size);
643 end if; 668 end if;
644 end if; 669 end if;
645 end loop; 670 end loop;
646 671
672 if Fds_Count = 0 then
673 -- There are no descriptors to monitor, it means that process died.
674
675 Result := Expect_Process_Died;
676
677 return;
678 end if;
679
647 declare 680 declare
648 Buffer : aliased String (1 .. Buffer_Size); 681 Buffer : aliased String (1 .. Buffer_Size);
649 -- Buffer used for input. This is allocated only once, not for 682 -- Buffer used for input. This is allocated only once, not for
650 -- every iteration of the loop 683 -- every iteration of the loop
651 684
654 687
655 begin 688 begin
656 -- Loop until we match or we have a timeout 689 -- Loop until we match or we have a timeout
657 690
658 loop 691 loop
659 Num_Descriptors := 692 -- Poll may be interrupted on Linux by a signal and need to be
660 Poll (Fds'Address, Fds_Count, Timeout, D'Access, Is_Set'Address); 693 -- repeated. We don't want to check for errno = EINTER, so just
694 -- attempt to call Poll a few times.
695
696 for J in 1 .. 3 loop
697 Num_Descriptors :=
698 Poll
699 (Fds'Address, Fds_Count, Timeout, D'Access, Is_Set'Address);
700
701 exit when Num_Descriptors /= -1;
702 end loop;
661 703
662 case Num_Descriptors is 704 case Num_Descriptors is
663 705
664 -- Error? 706 -- Error?
665 707
666 when -1 => 708 when -1 =>
667 Result := Expect_Internal_Error; 709 Result := Expect_Internal_Error;
668 710
669 if D /= 0 then 711 if D /= 0 then
670 Close (Descriptors (D).Input_Fd); 712 Close_Input (Descriptors (D).all);
671 Descriptors (D).Input_Fd := Invalid_FD;
672 end if; 713 end if;
673 714
674 return; 715 return;
675 716
676 -- Timeout? 717 -- Timeout?
690 731
691 if Buffer_Size = 0 then 732 if Buffer_Size = 0 then
692 Buffer_Size := 4096; 733 Buffer_Size := 4096;
693 end if; 734 end if;
694 735
695 N := Read (Descriptors (D).Output_Fd, Buffer'Address, 736 -- Read may be interrupted on Linux by a signal and
696 Buffer_Size); 737 -- need to be repeated. We don't want to check for
738 -- errno = EINTER, so just attempt to read a few
739 -- times.
740
741 for J in 1 .. 3 loop
742 N := Read (Descriptors (D).Output_Fd,
743 Buffer'Address, Buffer_Size);
744
745 exit when N > 0;
746 end loop;
697 747
698 -- Error or End of file 748 -- Error or End of file
699 749
700 if N <= 0 then 750 if N <= 0 then
701 -- ??? Note that ddd tries again up to three times 751 Close_Input (Descriptors (D).all);
702 -- in that case. See LiterateA.C:174
703
704 Close (Descriptors (D).Input_Fd);
705 Descriptors (D).Input_Fd := Invalid_FD;
706 Result := Expect_Process_Died; 752 Result := Expect_Process_Died;
753
707 return; 754 return;
708 755
709 else 756 else
710 -- If there is no limit to the buffer size 757 -- If there is no limit to the buffer size
711 758
923 970
924 if Input'Length > 0 then 971 if Input'Length > 0 then
925 Send (Process, Input); 972 Send (Process, Input);
926 end if; 973 end if;
927 974
928 Close (Process.Input_Fd); 975 Close_Input (Process);
929 Process.Input_Fd := Invalid_FD;
930 976
931 declare 977 declare
932 Result : Expect_Match; 978 Result : Expect_Match;
933 pragma Unreferenced (Result); 979 pragma Unreferenced (Result);
934 980