为什么我的 GNAT 出色的文件描述符不起作用?

Why isn't my GNAT's standout file descriptor working?

作为一个小项目的一部分,我正在用 Ada 编写 shell。因此,当我调查系统调用时,我了解到可以使用三种方法。

  1. POSIX 系统调用,这可能是最不可靠的。
  2. 将参数传递给 C 的 system(),我真的不想这样做,因为这是关于在 Ada 和 中编写模拟器不是 C.
  3. 使用 GNAT 的运行时间库。

考虑到这是最多 "Ada-like" 的选择,我选择了最后一个选项。我在 RosettaCode here 上找到了一个代码片段。在将 "cmd.exe" 更改为 "ls" 并删除第二个参数定义后,我复制并粘贴并编译了它。但是,当我 运行 可执行文件时没有任何反应。 shell 直接返回到提示符。我已经在两台不同的计算机上对此进行了测试,一台是 运行ning Fedora 21,另一台是 Debian Jessie。这是我为测试它所做的工作:

目前我正在使用C.Interface系统来准备我的shell,但我对此并不满意。我是 Ada 的新手,现在只用了一个月左右的时间来修补它,所以如果这里有某种 Ada 智慧可以帮助我,我就不参与了。

更新: 我已经尝试 运行 使用绝对路径将其连接到 /usr/bin 和 /bin 位置,但它不起作用。有趣的是,操作系统返回的result code是1,但不知道是什么意思。快速搜索表明它适用于 "all general errors",另一个站点表明它适用于 "incorrect functions"。

缺少 shell,您需要自己搜索 PATH 或指定所需可执行文件的完整路径:

Spawn (
   Program_Name => "/bin/ls",
   …
);

I have tried running it with absolute path…neither /usr/bin nor /bin locations work.

使用which确定可执行文件的完整路径:

$ which ls
/bin/ls

我不得不在 Debian Linux 上将 RosettaCode 示例稍微调整为 运行 /bin/ls,但它确实如预期的那样 运行...

with Ada.Text_IO;     use Ada.Text_IO;
with Gnat.OS_Lib;   use Gnat.OS_Lib;

procedure Execute_Synchronously is
   Result    : Integer;
   Arguments : Argument_List :=
                 (  1=> new String'("-al")
                 );
begin
   Spawn
   (  Program_Name           => "/bin/ls",
      Args                   => Arguments,
      Output_File_Descriptor => Standout,
      Return_Code            => Result
   );
   for Index in Arguments'Range loop
      Free (Arguments (Index)); 
   end loop;
end Execute_Synchronously;

变化:

  1. 我的 Gnat(来自 Debian Jessie 的 FSF Gnat 4.92)警告了 System.OS_Lib,建议改为 Gnat.OS_Lib。 (这只是重命名 System.OS_Lib .... 为什么???
    System.OS_Lib 评论:

-- Note: this package is in the System hierarchy so that it can be directly
-- be used by other predefined packages. User access to this package is via
-- a renaming of this package in GNAT.OS_Lib (file g-os_lib.ads).

  1. 包含路径的程序名称。
  2. 参数。我第一次 运行 它显示了 "ls" 本身的详细信息,因为它被赋予了自己的名称作为第一个参数,所以我删除了它以查看当前目录。

备注:

  1. 关于可用子程序及其参数的最佳信息通常在 "adainclude" 文件夹中的包规范中:这是 /usr/lib/gcc/x86_64-linux-gnu/4.9/adainclude 在我的 Debian 安装中,locate system.ads 会找到你的。具体文件是:s-os_lib.ads for System.OS_Lib which exports Spawn and Standout, and a-textio.ads for Ada.Text_IO.
  2. Standout 不是访问标准输出的首选方式:它是一个文件描述符(整数),首选方式是 Ada.Text_IO 中的 Standard_Output 函数,其中 returns 一个文件。但是,似乎没有 Spawn 的重载需要一个文件(我也不希望在这个低级库中有一个)所以这里使用了较低级的文件描述符。