Spawning Processes in Ada

Here’s the translation of the Go code to Ada, formatted in Markdown suitable for Hugo:

Our first example demonstrates how to spawn external processes in Ada. Here’s the full source code:

with Ada.Text_IO;
with Ada.Calendar;
with Ada.Strings.Unbounded;
with GNAT.OS_Lib;

procedure Spawn_Processes is
   use Ada.Text_IO;
   use Ada.Strings.Unbounded;

   function Execute_Command (Command : String) return String is
      Args    : GNAT.OS_Lib.Argument_List_Access :=
                  GNAT.OS_Lib.Argument_String_To_List (Command);
      Success : Boolean;
      Output  : Ada.Strings.Unbounded.Unbounded_String;
   begin
      GNAT.OS_Lib.Spawn (Program_Name => Args (Args'First).all,
                         Args         => Args (Args'First + 1 .. Args'Last),
                         Output       => Output,
                         Success      => Success);
      GNAT.OS_Lib.Free (Args);
      if not Success then
         return "Command execution failed";
      end if;
      return To_String (Output);
   end Execute_Command;

begin
   -- Simple command execution
   Put_Line ("> date");
   Put_Line (Execute_Command ("date"));

   -- Command with error handling
   declare
      Output : constant String := Execute_Command ("date -x");
   begin
      if Output = "Command execution failed" then
         Put_Line ("Failed executing: date -x");
      else
         Put_Line (Output);
      end if;
   end;

   -- Piping data to a command
   Put_Line ("> grep hello");
   declare
      Grep_Command : constant String := "echo 'hello grep\ngoodbye grep' | grep hello";
      Output       : constant String := Execute_Command (Grep_Command);
   begin
      Put_Line (Output);
   end;

   -- Executing a more complex command
   Put_Line ("> ls -a -l -h");
   Put_Line (Execute_Command ("ls -a -l -h"));
end Spawn_Processes;

This Ada program demonstrates how to spawn external processes and capture their output. Let’s break down the key parts:

  1. We define a function Execute_Command that takes a command string as input, executes it using GNAT.OS_Lib.Spawn, and returns the output as a string.

  2. We start with a simple command that takes no arguments: date. We execute it and print its output.

  3. Next, we demonstrate error handling by trying to execute date -x, which is an invalid command. We check if the execution failed and print an appropriate message.

  4. We then show how to pipe data to a command. In this case, we use echo to pipe input to grep.

  5. Finally, we execute a more complex command: ls -a -l -h.

To run this program, save it as spawn_processes.adb and compile it using your Ada compiler. For example, with GNAT:

$ gnatmake spawn_processes.adb
$ ./spawn_processes

The output will be similar to running these commands directly from the command line:

> date
Fri May 5 22:15:30 PDT 2023

Failed executing: date -x

> grep hello
hello grep

> ls -a -l -h
total 16K
drwxr-xr-x  2 user user 4.0K May  5 22:15 .
drwxr-xr-x 28 user user 4.0K May  5 22:14 ..
-rw-r--r--  1 user user 2.1K May  5 22:15 spawn_processes.adb
-rwxr-xr-x  1 user user 1.2M May  5 22:15 spawn_processes

This example demonstrates how to spawn external processes in Ada, capture their output, and handle potential errors. It’s important to note that Ada’s standard library doesn’t provide as direct support for process spawning as Go does, so we use the GNAT-specific GNAT.OS_Lib package for this functionality.