Mercurial > hg > CbC > CbC_gcc
diff 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 |
line wrap: on
line diff
--- a/gcc/ada/libgnat/g-expect.adb Thu Oct 25 07:37:49 2018 +0900 +++ b/gcc/ada/libgnat/g-expect.adb Thu Feb 13 11:34:05 2020 +0900 @@ -6,7 +6,7 @@ -- -- -- B o d y -- -- -- --- Copyright (C) 2000-2018, AdaCore -- +-- Copyright (C) 2000-2019, AdaCore -- -- -- -- GNAT is free software; you can redistribute it and/or modify it under -- -- terms of the GNU General Public License as published by the Free Soft- -- @@ -222,15 +222,17 @@ 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 @@ -267,6 +269,27 @@ 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 -- ------------ @@ -630,7 +653,9 @@ begin for J in Descriptors'Range loop - if Descriptors (J) /= null then + if Descriptors (J) /= null + and then Descriptors (J).Output_Fd /= Invalid_FD + then Fds (Fds'First + Fds_Count) := Descriptors (J).Output_Fd; Fds_To_Descriptor (Fds'First + Fds_Count) := J; Fds_Count := Fds_Count + 1; @@ -644,6 +669,14 @@ end if; end loop; + if Fds_Count = 0 then + -- There are no descriptors to monitor, it means that process died. + + Result := Expect_Process_Died; + + return; + end if; + declare Buffer : aliased String (1 .. Buffer_Size); -- Buffer used for input. This is allocated only once, not for @@ -656,8 +689,17 @@ -- Loop until we match or we have a timeout loop - Num_Descriptors := - Poll (Fds'Address, Fds_Count, Timeout, D'Access, Is_Set'Address); + -- Poll may be interrupted on Linux by a signal and need to be + -- repeated. We don't want to check for errno = EINTER, so just + -- attempt to call Poll a few times. + + for J in 1 .. 3 loop + Num_Descriptors := + Poll + (Fds'Address, Fds_Count, Timeout, D'Access, Is_Set'Address); + + exit when Num_Descriptors /= -1; + end loop; case Num_Descriptors is @@ -667,8 +709,7 @@ 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; @@ -692,18 +733,24 @@ Buffer_Size := 4096; end if; - N := Read (Descriptors (D).Output_Fd, Buffer'Address, - Buffer_Size); + -- Read may be interrupted on Linux by a signal and + -- need to be repeated. We don't want to check for + -- errno = EINTER, so just attempt to read a few + -- times. + + for J in 1 .. 3 loop + N := Read (Descriptors (D).Output_Fd, + Buffer'Address, Buffer_Size); + + exit when N > 0; + end loop; -- Error or End of file if N <= 0 then - -- ??? Note that ddd tries again up to three times - -- in that case. See LiterateA.C:174 + Close_Input (Descriptors (D).all); + Result := Expect_Process_Died; - Close (Descriptors (D).Input_Fd); - Descriptors (D).Input_Fd := Invalid_FD; - Result := Expect_Process_Died; return; else @@ -925,8 +972,7 @@ Send (Process, Input); end if; - Close (Process.Input_Fd); - Process.Input_Fd := Invalid_FD; + Close_Input (Process); declare Result : Expect_Match;