mirror of
https://github.com/AdaCore/spawn.git
synced 2026-02-12 13:09:41 -08:00
Report async IO errors by Glib implementation.
This commit is contained in:
@@ -76,7 +76,28 @@ package body Spawn.Channels is
|
||||
with Convention => C;
|
||||
-- Common code to start (continue) watching of the IO channel.
|
||||
|
||||
procedure On_Close_Channels (Self : Channels);
|
||||
procedure Channel_Error (Self : Channels);
|
||||
-- Executed on IO channel failure to report postponed Finished signal.
|
||||
|
||||
-------------------
|
||||
-- Channel_Error --
|
||||
-------------------
|
||||
|
||||
procedure Channel_Error (Self : Channels) is
|
||||
begin
|
||||
if Self.Process.Pending_Finish then
|
||||
-- Check whether all IO operations are done, then emit Finished
|
||||
-- callback.
|
||||
|
||||
if not Is_Active (Self) then
|
||||
Self.Process.Pending_Finish := False;
|
||||
Self.Process.Status := Not_Running;
|
||||
|
||||
Self.Process.Emit_Finished
|
||||
(Self.Process.Exit_Status, Self.Process.Exit_Code);
|
||||
end if;
|
||||
end if;
|
||||
end Channel_Error;
|
||||
|
||||
-----------------------------
|
||||
-- Close_Child_Descriptors --
|
||||
@@ -113,28 +134,12 @@ package body Spawn.Channels is
|
||||
|
||||
function Is_Active (Self : Channels) return Boolean is
|
||||
begin
|
||||
return Self.Stdout_Event /= Glib.Main.No_Source_Id
|
||||
or Self.Stderr_Event /= Glib.Main.No_Source_Id;
|
||||
return
|
||||
Self.Stdin_Event /= Glib.Main.No_Source_Id
|
||||
or Self.Stdout_Event /= Glib.Main.No_Source_Id
|
||||
or Self.Stderr_Event /= Glib.Main.No_Source_Id;
|
||||
end Is_Active;
|
||||
|
||||
-----------------------
|
||||
-- On_Close_Channels --
|
||||
-----------------------
|
||||
|
||||
procedure On_Close_Channels (Self : Channels) is
|
||||
begin
|
||||
if Self.Process.Pending_Finish then
|
||||
Self.Process.Pending_Finish := False;
|
||||
Self.Process.Status := Not_Running;
|
||||
|
||||
Self.Process.Emit_Finished
|
||||
(Self.Process.Exit_Status, Self.Process.Exit_Code);
|
||||
end if;
|
||||
exception
|
||||
when others =>
|
||||
null;
|
||||
end On_Close_Channels;
|
||||
|
||||
---------------------
|
||||
-- On_Stderr_Event --
|
||||
---------------------
|
||||
@@ -149,26 +154,29 @@ package body Spawn.Channels is
|
||||
Self : Channels renames data.Self.Channels;
|
||||
|
||||
begin
|
||||
if (condition and Glib.IOChannel.G_Io_In) /= 0 then
|
||||
Self.Stderr_Lock := @ - 1;
|
||||
Self.Stderr_Lock := @ - 1;
|
||||
|
||||
if (condition and Glib.IOChannel.G_Io_In) /= 0 then
|
||||
Self.Process.Emit_Stderr_Available;
|
||||
|
||||
if Self.Stderr_Lock = 0 then
|
||||
Self.Stderr_Event := Glib.Main.No_Source_Id;
|
||||
end if;
|
||||
elsif (condition and Glib.IOChannel.G_Io_Hup) /= 0
|
||||
or (condition and Glib.IOChannel.G_Io_Err) /= 0
|
||||
then
|
||||
Self.Process.Emit_Standard_Error_Stream_Error
|
||||
("GIOChannel IO error");
|
||||
end if;
|
||||
|
||||
if (condition and Glib.IOChannel.G_Io_Hup) /= 0 then
|
||||
Self.Stderr_Lock := 0;
|
||||
if Self.Stderr_Lock = 0 then
|
||||
Self.Stderr_Event := Glib.Main.No_Source_Id;
|
||||
|
||||
if Self.Stdout_Event = Glib.Main.No_Source_Id then
|
||||
On_Close_Channels (Self);
|
||||
end if;
|
||||
end if;
|
||||
|
||||
return Self.Stderr_Lock;
|
||||
if (condition and Glib.IOChannel.G_Io_Hup) /= 0
|
||||
or (condition and Glib.IOChannel.G_Io_Err) /= 0
|
||||
then
|
||||
Channel_Error (Self);
|
||||
end if;
|
||||
|
||||
return Self.Stdout_Lock;
|
||||
end On_Stderr_Event;
|
||||
|
||||
--------------------
|
||||
@@ -181,19 +189,32 @@ package body Spawn.Channels is
|
||||
data : access Internal.Process_Reference) return Glib.Gboolean
|
||||
is
|
||||
pragma Unreferenced (source);
|
||||
pragma Unreferenced (condition);
|
||||
|
||||
Self : Channels renames data.Self.Channels;
|
||||
|
||||
begin
|
||||
Self.Stdin_Lock := @ - 1;
|
||||
|
||||
Self.Process.Emit_Stdin_Available;
|
||||
if (condition and Glib.IOChannel.G_Io_Out) /= 0 then
|
||||
Self.Process.Emit_Stdin_Available;
|
||||
|
||||
elsif (condition and Glib.IOChannel.G_Io_Hup) /= 0
|
||||
or (condition and Glib.IOChannel.G_Io_Err) /= 0
|
||||
then
|
||||
Self.Process.Emit_Standard_Error_Stream_Error
|
||||
("GIOChannel IO error");
|
||||
end if;
|
||||
|
||||
if Self.Stdin_Lock = 0 then
|
||||
Self.Stdin_Event := Glib.Main.No_Source_Id;
|
||||
end if;
|
||||
|
||||
if (condition and Glib.IOChannel.G_Io_Hup) /= 0
|
||||
or (condition and Glib.IOChannel.G_Io_Err) /= 0
|
||||
then
|
||||
Channel_Error (Self);
|
||||
end if;
|
||||
|
||||
return Self.Stdin_Lock;
|
||||
end On_Stdin_Event;
|
||||
|
||||
@@ -211,23 +232,26 @@ package body Spawn.Channels is
|
||||
Self : Channels renames data.Self.Channels;
|
||||
|
||||
begin
|
||||
if (condition and Glib.IOChannel.G_Io_In) /= 0 then
|
||||
Self.Stdout_Lock := @ - 1;
|
||||
Self.Stdout_Lock := @ - 1;
|
||||
|
||||
if (condition and Glib.IOChannel.G_Io_In) /= 0 then
|
||||
Self.Process.Emit_Stdout_Available;
|
||||
|
||||
if Self.Stdout_Lock = 0 then
|
||||
Self.Stdout_Event := Glib.Main.No_Source_Id;
|
||||
end if;
|
||||
elsif (condition and Glib.IOChannel.G_Io_Hup) /= 0
|
||||
or (condition and Glib.IOChannel.G_Io_Err) /= 0
|
||||
then
|
||||
Self.Process.Emit_Standard_Output_Stream_Error
|
||||
("GIOChannel IO error");
|
||||
end if;
|
||||
|
||||
if (condition and Glib.IOChannel.G_Io_Hup) /= 0 then
|
||||
Self.Stdout_Lock := 0;
|
||||
if Self.Stdout_Lock = 0 then
|
||||
Self.Stdout_Event := Glib.Main.No_Source_Id;
|
||||
end if;
|
||||
|
||||
if Self.Stderr_Event = Glib.Main.No_Source_Id then
|
||||
On_Close_Channels (Self);
|
||||
end if;
|
||||
if (condition and Glib.IOChannel.G_Io_Hup) /= 0
|
||||
or (condition and Glib.IOChannel.G_Io_Err) /= 0
|
||||
then
|
||||
Channel_Error (Self);
|
||||
end if;
|
||||
|
||||
return Self.Stdout_Lock;
|
||||
@@ -757,7 +781,9 @@ package body Spawn.Channels is
|
||||
(Self.Stderr_Parent,
|
||||
Self.Stderr_Event,
|
||||
Self.Stderr_Lock,
|
||||
Glib.IOChannel.G_Io_In + Glib.IOChannel.G_Io_Hup,
|
||||
Glib.IOChannel.G_Io_In
|
||||
+ Glib.IOChannel.G_Io_Hup
|
||||
+ Glib.IOChannel.G_Io_Err,
|
||||
On_Stderr_Event'Access,
|
||||
Self.Process.Reference'Unchecked_Access);
|
||||
end if;
|
||||
@@ -773,7 +799,9 @@ package body Spawn.Channels is
|
||||
(Self.Stdin_Parent,
|
||||
Self.Stdin_Event,
|
||||
Self.Stdin_Lock,
|
||||
Glib.IOChannel.G_Io_Out,
|
||||
Glib.IOChannel.G_Io_Out
|
||||
+ Glib.IOChannel.G_Io_Hup
|
||||
+ Glib.IOChannel.G_Io_Err,
|
||||
On_Stdin_Event'Access,
|
||||
Self.Process.Reference'Unchecked_Access);
|
||||
end Start_Stdin_Watch;
|
||||
@@ -788,7 +816,9 @@ package body Spawn.Channels is
|
||||
(Self.Stdout_Parent,
|
||||
Self.Stdout_Event,
|
||||
Self.Stdout_Lock,
|
||||
Glib.IOChannel.G_Io_In + Glib.IOChannel.G_Io_Hup,
|
||||
Glib.IOChannel.G_Io_In
|
||||
+ Glib.IOChannel.G_Io_Hup
|
||||
+ Glib.IOChannel.G_Io_Err,
|
||||
On_Stdout_Event'Access,
|
||||
Self.Process.Reference'Unchecked_Access);
|
||||
end Start_Stdout_Watch;
|
||||
|
||||
@@ -71,16 +71,25 @@ private
|
||||
Stdin_Child : Glib.Gint := -1;
|
||||
Stdin_Event : Glib.Main.G_Source_Id := Glib.Main.No_Source_Id;
|
||||
Stdin_Lock : Glib.Gboolean := 0;
|
||||
-- Lock of the Stdin_Event field. Lock is managed as counter
|
||||
-- to prevent reset of the Stdin_Event field by the nested IO
|
||||
-- operation on the channel.
|
||||
|
||||
Stdout_Parent : Glib.IOChannel.Giochannel := null;
|
||||
Stdout_Child : Glib.Gint := -1;
|
||||
Stdout_Event : Glib.Main.G_Source_Id := Glib.Main.No_Source_Id;
|
||||
Stdout_Lock : Glib.Gboolean := 0;
|
||||
-- Lock of the Stdout_Event field. Lock is managed as counter
|
||||
-- to prevent reset of the Stdout_Event field by the nested IO
|
||||
-- operation on the channel.
|
||||
|
||||
Stderr_Parent : Glib.IOChannel.Giochannel := null;
|
||||
Stderr_Child : Glib.Gint := -1;
|
||||
Stderr_Event : Glib.Main.G_Source_Id := Glib.Main.No_Source_Id;
|
||||
Stderr_Lock : Glib.Gboolean := 0;
|
||||
-- Lock of the Stderr_Event field. Lock is managed as counter
|
||||
-- to prevent reset of the Stderr_Event field by the nested IO
|
||||
-- operation on the channel.
|
||||
|
||||
PTY_Slave : Glib.Gint := -1;
|
||||
end record;
|
||||
|
||||
Reference in New Issue
Block a user