|
|
DataMuseum.dkPresents historical artifacts from the history of: Rational R1000/400 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Rational R1000/400 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 9216 (0x2400)
Types: Ada Source
Notes: 03_class, FILE, R1k_Segment, e3_tag, package body U_Env, seg_04b99f
└─⟦8527c1e9b⟧ Bits:30000544 8mm tape, Rational 1000, Arrival backup of disks in PAM's R1000
└─⟦cfc2e13cd⟧ »Space Info Vol 2«
└─⟦this⟧
with Language, Unchecked_Conversion, Unchecked_Deallocation;
with System, A_Strings, C_Strings;
use System, A_Strings, C_Strings;
package body U_Env is
procedure Free is new Unchecked_Deallocation (Str_Vector, Argv_Ptr);
Bytes_For_Address : constant Integer := Address'Size / 8;
-- This is the structure that the register sp points to when a unix process
-- starts up. The first kargc pointers in kargv point to the argv strings.
-- This is followed by a null pointer and then an array of pointers to the
-- environment strings.
type Kframe is
record
Kargc : Integer;
Kfirst_Arg : Address; -- more arg pointers follow
end record;
type Kframe_Ptr is access Kframe;
pragma Local_Access (Kframe_Ptr);
-- This is the contents of the sp register when the process
-- was started.
U_Mainp : Kframe_Ptr; -- set by Ada's startup.s
pragma Interface_Name (U_Mainp, "__u_mainp");
Environ : Address;
pragma Interface_Name (Environ, Language.C_Prefix & "environ");
-- This pointer keeps track of where to get the next string
Next : Address := No_Addr;
type Ptr_To_Address is access C_String;
pragma Local_Access (Ptr_To_Address);
function Cvt_Ptr is new Unchecked_Conversion (Address, Ptr_To_Address);
function Next_Str return A_String is
New_Str : A_String;
Str : C_String;
Str_Size : Integer;
begin
if Next = No_Addr then
Next := U_Mainp.Kfirst_Arg;
end if;
Str := Cvt_Ptr (Next).all;
if Str = null then
-- There is a null pointer separating the argv strings from the
-- env strings.
if Next /= U_Mainp.Kfirst_Arg +
Bytes_For_Address * U_Mainp.Kargc then
return null;
end if;
Next := Next + Bytes_For_Address;
Str := Cvt_Ptr (Next).all;
end if;
New_Str := Convert_C_To_A (Str);
Next := Next + Bytes_For_Address;
return New_Str;
end Next_Str;
function U_Argc return Integer is
begin
return Integer (U_Mainp.Kargc);
end U_Argc;
function U_Envc return Integer is
Count : Integer;
Env_P : Address;
begin
-- Since we know argc, we can calculate where the beginning of
-- the environment string pointers is.
Env_P := U_Mainp.Kfirst_Arg + Bytes_For_Address * (U_Mainp.Kargc + 1);
Environ := Env_P;
Count := 0;
while (Cvt_Ptr (Env_P).all /= null) loop
Env_P := Env_P + Bytes_For_Address;
Count := Count + 1;
end loop;
return Count;
end U_Envc;
procedure Initialize_Globals is
begin
Argc := U_Argc;
Argv := new Str_Vector (0 .. Argc - 1);
for I in 0 .. Argc - 1 loop
Argv (I) := Next_Str;
end loop;
Envc := U_Envc;
Envp := new Str_Vector (0 .. Envc - 1);
for I in 0 .. Envc - 1 loop
Envp (I) := Next_Str;
end loop;
end Initialize_Globals;
pragma Inline_Only (Initialize_Globals);
------------------------------------------
-- functions to be used mainly by POSIX --
------------------------------------------
function Env_Name (Env_Var : A_Strings.A_String)
return A_Strings.A_String is
begin
for I in 1 .. Env_Var.Len loop
if (Env_Var.S (I) = '=') then
return new A_Strings.String_Rec'(I - 1, Env_Var.S (1 .. I - 1));
end if;
end loop;
return Env_Var;
end Env_Name;
function Env_Value (Env_Var : A_Strings.A_String)
return A_Strings.A_String is
Value : A_Strings.A_String;
Index : Integer := 1;
begin
for I in 1 .. Env_Var.Len loop
if (Env_Var.S (I) = '=') then
Value := new A_Strings.String_Rec (Env_Var.Len - I);
for J in (I + 1) .. Env_Var.Len loop
Value.S (Index) := Env_Var.S (J);
Index := Index + 1;
end loop;
return Value;
--\x09\x09\x09\x09RETURN new a_strings.string_rec'(env_var.len-i, env_var.s(i+1..env_var.len));
end if;
end loop;
return A_Strings.To_A ("");
end Env_Value;
function Env_Var_Pos (Name : A_Strings.A_String) return Integer is
Envp_Name : A_Strings.A_String;
begin
for I in 0 .. Envc - 1 loop
Envp_Name := Env_Name (Envp (I));
if (Envp_Name.S = Name.S) then
return I;
end if;
end loop;
return -1;
end Env_Var_Pos;
function Is_Env_Var (Name : A_Strings.A_String) return Boolean is
begin
if (Env_Var_Pos (Name) /= -1) then
return True;
end if;
return False;
end Is_Env_Var;
procedure Putenv is
C_Envp : array (0 .. Envc) of System.Address;
begin
for I in 0 .. Envc - 1 loop
C_Envp (I) := C_Strings.C_To_Address
(C_Strings.Convert_A_To_C (Envp (I)));
end loop;
C_Envp (Envc) := System.No_Addr;
Environ := C_Envp (C_Envp'First)'Address;
end Putenv;
procedure Add_Env_Var (Var : A_Strings.A_String) is
New_Envp : Argv_Ptr;
begin
-- copy information into a temp array
Envc := Envc + 1;
New_Envp := new Str_Vector (0 .. Envc - 1);
for I in 0 .. Envc - 2 loop
New_Envp (I) := Envp (I);
end loop;
New_Envp (Envc - 1) := Var;
-- free up old space
Free (Envp);
-- build new envp
Envp := new Str_Vector (0 .. Envc - 1);
for I in 0 .. Envc - 1 loop
Envp (I) := New_Envp (I);
end loop;
Free (New_Envp);
Putenv;
end Add_Env_Var;
procedure Del_Env_Var (Name : A_Strings.A_String) is
Pos : Integer;
New_Envp : Argv_Ptr;
begin
if (not Is_Env_Var (Name)) then
return;
end if;
Pos := Env_Var_Pos (Name);
Envc := Envc - 1;
-- copy information into a temp array
New_Envp := new Str_Vector (0 .. Envc - 1);
for I in 0 .. Pos - 1 loop
New_Envp (I) := Envp (I);
end loop;
for I in Pos + 1 .. Envc loop
New_Envp (I - 1) := Envp (I);
end loop;
-- free up old space
Free (Envp);
-- build new envp
Envp := new Str_Vector (0 .. Envc - 1);
for I in 0 .. Envc - 1 loop
Envp (I) := New_Envp (I);
end loop;
Free (New_Envp);
Putenv;
end Del_Env_Var;
function Getenv (Var_Name : C_Strings.C_String) return C_Strings.C_String is
Name : A_Strings.A_String := C_Strings.To_A (Var_Name);
Pos : Integer := Env_Var_Pos (Name);
begin
if (Pos /= -1) then
return C_Strings.To_C (Env_Value (Envp (Pos)));
end if;
return null;
end Getenv;
function Getenv (Var_Name : A_Strings.A_String) return A_Strings.A_String is
Pos : Integer := Env_Var_Pos (Var_Name);
begin
if (Pos /= -1) then
return Env_Value (Envp (Pos));
end if;
return null;
end Getenv;
begin
Initialize_Globals;
end U_Env;
nblk1=8
nid=0
hdr6=10
[0x00] rec0=1d rec1=00 rec2=01 rec3=050
[0x01] rec0=1f rec1=00 rec2=02 rec3=006
[0x02] rec0=26 rec1=00 rec2=03 rec3=00e
[0x03] rec0=1e rec1=00 rec2=04 rec3=046
[0x04] rec0=1d rec1=00 rec2=05 rec3=04c
[0x05] rec0=22 rec1=00 rec2=06 rec3=01a
[0x06] rec0=23 rec1=00 rec2=07 rec3=030
[0x07] rec0=1d rec1=00 rec2=08 rec3=000
tail 0x21750bcfa868437e1bb79 0x42a00088462060003