This is an appendix to Understanding Unix/Linux
Programming
written for people interested in Ada programming on POSIX
systems.
Here is the code for tinybc.adb, a simple
version of bc that parses input and speaks with
dc through two pipes:
% gnatmake tinybc [...] % ./tinybc tinybc: 2+2 2 + 2 = 4 tinybc: 55^5 55 ^ 5 = 503284375 tinybc:
There is nothing properly equivalent to fdopen in the
Ada POSIX interface.
There is nothing properly equivalent to popen in the Ada
POSIX interface, but we can write it ourselves.
POSIX.IO.Open opens a connection to a named file:
declare
F : POSIX.IO.File_Descriptor;
begin
F := POSIX.IO.Open (Name => "some_file",
Mode => POSIX.IO.Read_Only);
[...]
POSIX.IO.Close (File => F);
end;
We want to write a similar function, Open_Process,
which opens a connection to a process running a shell command:
declare
F : POSIX.IO.File_Descriptor;
begin
F := Open_Process (Name => "ls -l",
Mode => POSIX.IO.Read_Only);
[...]
Close_Process (File => F);
end;
Here we have a program, in which the command who | sort
is a source of data, where we use Open_Process to obtain a
sorted list of users: popendemo.adb
This second example uses Open_Process to connect to the
mail program and notify some users of system trouble: popen_ex3.adb
Close_Process is requiredWhen you are done reading from (or writing to) a connection created
by Open_Process, you should call
Close_Process rather than POSIX.IO.Close to
close the connection.
Here is the source code for Open_Process and
Close_Process:
Unfortunately the POSIX Ada interface included with Debian and Ubuntu doesn't include networking, so we have to manage with a non-standard interface.
Here is the code: timeserv.adb
procedure
GNAT.Sockets.Create_Socket:procedure
GNAT.Sockets.Bind_Socket:procedure
GNAT.Sockets.Listen_Socket:procedure
GNAT.Sockets.Accept_Socket:We can now compile and run our time server:
% make timeserv [...] % ./timeserv & [1] 17335 %
We can connect to our server using telnet:
% telnet localhost 13000 Trying 127.0.0.1... Connected to localhost. Escape character is '^]'. Wow! Got a call! The time here is 11:19. Connection closed by foreign host. % telnet 10.0.1.202 13000 Trying 10.0.1.202... Connected to 10.0.1.202. Escape character is '^]'. Wow! Got a call! The time here is 11:24. Connection closed by foreign host. %
[...] The server will continue to run until we kill it:
% kill 17335 [1] + terminated ./timeserv %
Here is the code: timeclnt.adb
procedure
GNAT.Sockets.Connect_Socket:(already done)
Write an Ada program, which tests if pipes created by
POSIX.IO.Create_Pipe are bidirectional. [...]
Go to next chapter.
Understanding Unix/Linux Programming, Bruce Molay,
ISBN 0-13-008396-8.