2015-09-19 24 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

    相關問題