As part of a little project, I'm writing a shell in Ada. As such, when I was investigating the system calls, I learned that there are three ways to do it.
- The POSIX system calls, which are probably the least reliable.
- Passing the arguments along to C's system(), which I didn't really want to do, since this was about writing the emulator in Ada and not C.
- Using GNAT's runtime libraries.
I chose to go for the last option, considering this to be the most "Ada-like" of the choices. I found a code snippet on RosettaCode here. I copied and pasted it and compiled it after changing the "cmd.exe" to "ls" and removing the second argument definition. However, nothing happens when I run the executable. The shell just goes right back to the prompt. I have tested this on two different computers, one running Fedora 21, the other Debian Jessie. Here's what I've done to test it:
- Seen if lacking an arguments string caused it
- Checked if any of the file descriptors in GNAT's libraries are mis-named
- Redirected both stderr and stdin to stdout just to see if GNAT was dumping them to the wrong FD anyway.
- Looked thoroughly through the System.OS_lib library file, and there seems to be no reason.
- Googled it, but GNAT's own page on the GCC website is very poorly documented.
For now I'm using the C.Interface system in the preparation of my shell, but I'm dissatisfied with this. I'm new to Ada and have only been tinkering with it for a month or so now, so if there's some kind of Ada wisdom here that would help I'm not in on it.
UPDATE: I have tried running it with absolute path, both to /usr/bin and /bin locations, and it doesn't work. Interestingly, the result code returned by the operating system is 1, but I don't know what that means. A quick search suggests that it's for "all general errors", and another site suggests that it's for "incorrect functions".
Absent a shell, you'll need to search the
PATH
yourself or specify a full path for the desired executable:Use
which
to determine the full path to the executable:I had to tweak the RosettaCode example a little to run
/bin/ls
on Debian Linux, but it does run as expected...Changes :
System.OS_Lib
, recommendingGnat.OS_Lib
instead. (Which simply renames System.OS_Lib .... why???System.OS_Lib comments:
Notes :
/usr/lib/gcc/x86_64-linux-gnu/4.9/adainclude
on my Debian installation,locate system.ads
will find yours. The specific files are:s-os_lib.ads
forSystem.OS_Lib
which exports Spawn and Standout, anda-textio.ads
for Ada.Text_IO.Standout
is not the preferred way of accessing Standard Output : it's a file descriptor (integer), the preferred way would be theStandard_Output
function fromAda.Text_IO
which returns a File. However there doesn't seem to be an overload forSpawn
which takes a File (nor would I expect one in this low level library) so the lower level file descriptor is used here.