Version 1.1 of ais/ai-00371.txt
!standard A.18 04-02-05 AI95-00371/01
!class amendment 03-12-30
!status work item 03-12-30
!status received 03-12-30
!priority Medium
!difficulty Medium
!subject New hierarchy for OS-dependent services
!summary
A new root package for language defined units is added to the language.
It contains information about the underlying operating system, and its
descendents are assumed to provide operating-system dependent
operations.
!problem
Currently, children of Ada are units whose definition does not depend on
the target system, and children of System are units whose definition has
dependencies on the hardware.
There is no hierachy for units that depend on the host operating system.
There was only one of these (Command_Line) in Ada95, but more such units
are bound to appear in Ada05 (Directories, possibly others).
!proposal
Add a new package named "OS" to serve as the root of OS-dependent
services. It is understood that part of the semantics of the units
rooted at OS can have variations according to the underlying operating
system.
Packages that fall under this definition (Command_Line, Directories) are
made children of OS.
Moreover, packages providing access to commonly found services of
operating systems, like environment variables and process execution,
are proposed.
!wording
The following package exists:
package OS is
function OS_Name return String;
function OS_Version return String;
Unsupported : exception;
end OS;
Both OS_Name and OS_Version return implementation-defined strings, with
lower bound of 1. The string returned by OS_Name should not change when
the underlying operating system changes version. The string returned by
OS_Version should change when the underlying operating system changes
version.
The exception Unsupported is raised by subprograms in this package or
its children whenever an operation cannot be provided by the operating
system.
Packages Command_Line and Directories are children of OS, i.e. they are
named OS.Command_Line and OS.Directories. The following renaming exists:
with OS.Command_Line;
package Ada.Command_Line renames OS.Command_Line;
The following package exists:
package Environment is
procedure Set_Variable (Name : String; To : String);
function Get_Variable (Name : String) return String;
function Path return String;
function Locate_Executable (Name : String) return String;
function Locate_Regular_File (Name : String; Path : String := "")
return String;
end Environment;
This package provides access to environment variables. An environment
variable is a value external to the program, which has a name.
If the operating system does not support the notion of environment
variables, calls to Get_Variable will always return the null string, and
calls to Set_Variable will raise Unsupported.
The function Path returns an implementation defined string which defines
the location of executable files. If the operating system does not
support the notion of path, the null string is returned.
The function Locate_Executable returns a string corresponding to the
full name of the specified executable name, following the operating
system's conventions for locating executables.
The exception Ada.IO_Exceptions.Name_Error is raised if no executable
with the given name can be identified.
The function Locate_Regular_File returns a string corresponding to the
full name of the specified file name, following the operating system's
conventions for locating data files.
The exception Ada.IO_Exceptions.Name_Error is raised if no file with the
given name can be identified.
The following package exists:
with OS.Command_Line;
package Processes is
type Process_ID is private;
Null_Process_ID : constant Process_ID;
procedure Spawn (Command : in String;
Parameters : in String := "";
Result : out OS.Command_Line.Exit_Status);
function Non_Blocking_Spawn (Command : in String;
Parameters : in String = "")
return Process_ID;
procedure Execute(Command_Line : in String;
Result : out OS.Command_Line.Exit_Status);
function Non_Blocking_Execute
(Command_Line : in String;
Result : out OS.Command_Line.Exit_Status)
return Process_ID;
procedure Wait_Process (Pid : in Process_Id;
Result : out OS.Command_Line.Exit_Status);
procedure Wait_Any_Process
(Pid : out Process_Id;
Result : out OS.Command_Line.Exit_Status);
No_Such_Pid : exception;
private
--
end Processes;
A value of the type Process_ID identifies a subprocess, as started by
the Spawn, Non_Blocking_Spawn, Execute and Non_Blocking_Execute
subprograms in this package. The constant Null_Process_ID does not
identify any process.
Each object of the type Process_ID is default initialized to the value
Null_Process_ID.
The procedure Spawn starts a new process, executing the executable whose
name is given as Command, with a parameter string given by Parameters.
It blocks until the process terminates. The exit status of the process
is returned in Result. It is implementation defined if the name given in
Command is subject to the rules for finding executables. If the process
could not be started (for example because Command does not identify an
executable, of for OS dependent reasons), Failure is returned in Result.
The procedure Non_Blocking Spawn starts a new process, executing the
executable whose name is given as Command, with a parameter string given
by Parameters. It blocks until the process has started, and returns the
Process_IO of the child process. If the process could not be started
(for example because Command does not identify an executable, of for
OS dependent reasons), Null_Task_ID is returned.
The subprograms Execute and Non_Blocking_Execute behave like Spawn and
Non_Blocking_Spawn respectively, except that the process is started by a
string given as the Command_Line parameter, with the syntax of Shell
commands appropriate to the operating system. The syntax of the
Command_Line parameter is implementation defined. On operating systems
where it makes sense, it is expected that the process is started as a
shell command.
The procedure Wait_Process blocks until the process specified by Pid has
terminated. The exit status of the process is returned in Result. If Pid
is Null_Pid, or identifies a process for which Wait_Process has already
been called, or which has been already returned by Wait_Any_Process, the
exception No_Such_Pid is raised.
The procedure Wait_Any_Process blocks until one of the processes
previously started by one of the Non_Blocking_Spawn or
Non_Blocking_Execute procedures has terminated. The exit status of the
process is returned in Result. If Pid is Null_Pid, or there is no more
process to wait for, the exception No_Such_Pid is raised.
Implementation requirement
The implementation of Wait_Process must be task safe in the following
sense:
if two tasks call Wait_Process simultaneously on the same Pid, one of
them receives No_Such_Pid, and the other one behaves as specified. Which
task receives the exception is implementation defined.
The implementation of Wait_Any_Process must be task safe in the
following sense:
if two tasks call Wait_Any_Process simultaneously, they will never
receive the same Pid.
!discussion
OS_Version is often referred to as one or two numbers, like major
version number and minor version number. But all operating systems do
not necessarily follow this convention, and there are sometimes
variants, like in 3.2a. Providing a string that can be parsed if necessary
seemed the most general solution.
!example
--!corrigendum
!ACATS test
!appendix
From: Randy Brukardt
Sent: Thursday, February 5, 2004 10:12 PM
A couple of comments on this proposal (now AI-371).
...
> Currently, children of Ada are units whose definition does not depend on
> the target system, and children of System are units whose definition has
> dependencies on the hardware.
I don't see where you get this statement from. The existence of Command_Line
certainly says it's not true, but even ignoring Command_Line, claiming that
any of the IO packages "do not depend on the target system" requires an
amazing stretch of imagination.
> There is no hierachy for units that depend on the host operating system.
> There was only one of these (Command_Line) in Ada95, but more such units
> are bound to appear in Ada05 (Directories, possibly others).
Certainly Directories belongs with the other IO packages! It's all about
manipulating file names - it's pretty useless without being able to do
something with the names afterwards.
> !proposal
>
> Add a new package named "OS" to serve as the root of OS-dependent
> services. It is understood that part of the semantics of the units
> rooted at OS can have variations according to the underlying operating
> system.
Creating new top-level packages is exactly what the Ada root was intended to
avoid. With this proposal, any program that has a package named OS is
instantantly unable to use Ada 200Y.
Children of Ada are essentially reserved for the Standard (and to a lesser
extent, implementers) to use, so adding new packages there is much less to
cause harm. (And we can fairly quickly find out about any conflicts.)
Moreover, the proposed name implies that an operating system is present, but
certainly at least some of the facilities can make useful sense without one
(on a bare-machine implementation of Ada).
Finally, there doesn't seem to be enough contents in this hierarchy to
justify a new root. Just put the additional packages into Ada.
---
The Environment package was also proposed by David Wheeler via SIGAda (see
AI-370), so I expect that we'll end up discussing it in the context of that
AI. I don't much like either proposal, for different reasons, but if I had
to choose one, I'd prefer this one. But, in any case, the functionality is
useful (this was the third of the three "packages to standardize" that I
identified when we started the amendment process - I never had enough energy
to propose one.
Spawn functionality makes sense. I'm not sure I'd go as far as this package
does (we just provide Spawn, with a non-blocking flag, and a Wait for the
non-blocking version; Execute is interesting, but very hard to implement
portably on Windows).
****************************************************************
Questions? Ask the ACAA Technical Agent