2015-09-19 21 views
1

作为一个小项目的一部分,我正在Ada编写一个shell。因此,当我调查系统调用时,我了解到有三种方法可以做到这一点。为什么我的GNAT的突出文件描述符不起作用?

  1. POSIX系统调用,这可能是最不可靠的。
  2. 传递的参数一起到C的系统(),我没有真的想这样做,因为这是关于写在阿达仿真器和 C.
  3. 使用GNAT的运行时库。

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

  • 观察,如果缺少一个参数字符串,导致它
  • 经过如有在GNAT的库文件描述的是错误命名
  • 重定向两个标准错误和标准输入到stdout只是为了看GNAT是否将它们倾销到错误的FD。
  • 透彻地看透了System.OS_lib库文件,似乎没有任何理由。
  • 用Google搜索了一下,但是GCC网站上的GNAT自己的页面记录很差。

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

更新:我试着用绝对路径运行它,都到/ usr/bin和/ bin位置,并且它不起作用。有趣的是,操作系统返回的结果代码是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. 我蚋(FSF蚋4.92从Debian的杰西)警告System.OS_Lib,建议Gnat.OS_Lib代替。 (这只是重命名System.OS_Lib ....为什么???
    System.OS_Lib评论:

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

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

    1. 的最佳信息加时赛可用的子程序和它们的参数通常是在包装规范自己在“adainclude”文件夹:这是/usr/lib/gcc/x86_64-linux-gnu/4.9/adainclude我的Debian安装,locate system.ads会找到你。具体文件为:s-os_lib.adsSystem.OS_Lib,它导出Spawn和Standout,a-textio.ads用于Ada.Text_IO。
    2. Standout不是访问标准输出的首选方式:它是一个文件描述符(整数),首选的方法是函数从Ada.Text_IO返回一个文件。然而,Spawn需要一个文件(我也不期望在这个低级库中有一个文件),所以在这里使用较低级别的文件描述符。
    1

    没有一个明确的外壳,你需要自己搜索PATH或指定一个完整路径所需的可执行文件:

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

    我曾尝试用绝对路径运行它既不......也不/usr/bin位置/bin工作。

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

    $ which ls 
    /bin/ls 
    
    +0

    实际上想过想要添加PATH变量,我觉得没有尝试过这种方法是愚蠢的。我会尽快尝试 – Bronze

    +0

    @Bronze:你可以使用'Getenv'来询问继承的PATH。 – trashgod

    相关问题