Mercurial > hg > CbC > CbC_gcc
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 |