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

时间:2015-09-19 01:36:26

标签: shell ada gnat

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

  1. POSIX系统调用,可能是最不可靠的。
  2. 将参数传递给C系统(),我没有真正希望这样做,因为这是关于在Ada中编写模拟器而不是 C.
  3. 使用GNAT的运行时库。
  4. 我选择了最后一个选项,考虑到这是最像" Ada-like"的选择。我在RosettaCode here上找到了一个代码段。我复制并粘贴它并在更改" cmd.exe"之后编译它。到" ls"并删除第二个参数定义。但是,当我运行可执行文件时没有任何反应。 shell只是回到提示符。我在两台不同的计算机上测试了这个,一台运行Fedora 21,另一台运行Debian Jessie。以下是我为测试而做的事情:

    • 如果缺少参数字符串导致它
    • 检查GNAT库中的任何文件描述符是否命名错误
    • 将stderr和stdin重定向到stdout只是为了看看GNAT是否正在将它们转储到错误的FD中。
    • 彻底查看了System.OS_lib库文件,似乎没有理由。
    • 用Google搜索,但是GCC网站上的GNAT自己的页面记录很差。

    现在我在编写shell时使用C.Interface系统,但我对此不满意。我是Ada的新手,现在只修补了一个月左右,所以如果在这里有某种Ada智慧可以帮助我不在其中。

    更新:我尝试使用绝对路径运行它,包括/ usr / bin和/ bin位置,但它不起作用。有趣的是,操作系统返回的结果代码是1,但我不知道这意味着什么。快速搜索表明它是针对"所有常见错误",另一个网站表明它是针对"错误的功能"。

2 个答案:

答案 0 :(得分:1)

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

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

我尝试使用绝对路径运行它... /usr/bin/bin位置都不起作用。

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

$ which ls
/bin/ls

答案 1 :(得分:1)

我必须稍微调整一下RosettaCode示例才能在Debian Linux上运行/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. my Gnat(来自Debian Jessie的FSF Gnat 4.92)警告System.OS_Lib,推荐Gnat.OS_Lib。 (这只是简单地重命名System.OS_Lib ....为什么??? System.OS_Lib评论:
  2.   

    - 注意:此包位于系统层次结构中,因此可以直接使用    - 由其他预定义的包使用。用户访问此包是通过
       - 在GNAT.OS_Lib(文件g-os_lib.ads)中重命名此包。

    1. 程序名称包括路径。
    2. 参数。我第一次运行它时,它显示了“ls”本身的细节,因为它被赋予了自己的名字作为第一个参数,所以我删除了它以查看当前目录。
    3. 注意:

      1. 可用子程序及其参数的最佳信息通常位于“adainclude”文件夹中的软件包规范中:这是我的Debian安装上的/usr/lib/gcc/x86_64-linux-gnu/4.9/adaincludelocate system.ads会找到你的。s-os_lib.ads。具体文件为:System.OS_Lib用于导出Spawn和Standout的a-textio.ads,以及用于Ada.Text_IO的Standout
      2. Standard_Output不是访问标准输出的首选方式:它是文件描述符(整数),首选方式是来自Ada.Text_IO的{​​{1}}函数,它返回一个文件。但是Spawn似乎没有过载文件(我也不期望在这个低级库中有一个),所以这里使用了较低级别的文件描述符。