Design of Operating System Interface Implementation: OSI_Exceptions This package exports all the exceptions used throughout the OSI packages. The package does not contain any routines. OSI_Error_Handler This package is an internal OSI package. It is used to handle any errors occurred during the execution of an OSI routine. It exports the following subprogram: subprogram Map_Last_Error 1. get Errorno of last error 2. map the error to its corresponding exception 3. raise exception OSI_Standard subprogram TO_OSI_String in The_String : String out The_OSI_String : OSI_String 1. declare The_OSI_String of range equal to the The_String range 2. for Index in The_String range loop The_OSI_String ( Index ) := OSI_Character ( The_String ( Index ) ) ; end loop ; 3. return The_OSI_String subprogram To_String in The_OSI_String : OSI_String ; out The_String : String ; 1. declare The_String of range equal to the The_OSI_String range 2. for Index in The_OSI_String range loop The_String ( Index ) := Character ( The_OSI_String ( Index ) ) ; end loop ; 3. return The_String subprogram "&" in Left : String Right : OSI_String out OSI_String 1. convert Left to an OSI_String by calling subprogram To_OSI_String 2. concatenate resulting OSI_String with imported Right 3. return concatenated OSI_String subprogram "&" in Left : Character Right : OSI_String out OSI_String 1. convert Character to OSI_Character by explicit conversion 2. concatenate resulting OSI_Character with imported OSI_String 3. return concatenated OSI_String OSI_Files The interfaces to the AIX system services will be declared in the internal subprograms. The following are the external subprograms: subprogram Create_Directory in Directory_Name : OSI_String {contains name of new directory} no out parameters 1. validate Directory_Name as a legal filename 2. mkdir ( path => OSI_Standard.To_String ( Directory_Name ) , mode => TBD ) {system service which creates a new directory. path contains the name of the new directory. mode contains the access mode to the directory} 3. if unsuccessful then invoke OSI_Error_Handler.Map_Last_Error 4. exit subprogram Unlink in File_Name : OSI_String {contains directory entry to be removed} no out parameters 1. validate File_Name as a legal filename 2. unlink ( path => OSI_Standard.To_String ( File_Name ) ) {system service which removes the the directory entry specified by path parameter. When all links to a file are removed and no process has the file open, the space allocated for the file is freed and the file ceases to exist} 3. if unsuccessful then invoke OSI_Error_Handler.Map_Last_Error 4. exit subprogram Remove_Directory in File_Name : OSI_String {contains name of directory to be removed} no out parameters 1. validate File_Name as a legal filename 2. rmdir ( path => OSI_Standard.To_String ( File_Name ) ) {system service which removes the directory file specified by path. The directory must be empty and you must have write access to it.} 3. if unsuccessful then invoke OSI_Error_Handler.Map_Last_Error 4. exit subprogram Rename in File_Name : OSI_String New_File_Name : OSI_String no out parameters 1. validate File_Name and New_File_Name as legal filenames 2. rename ( frompath => OSI_Standard.To_String ( File_Name ) , topath => OSI_Standard.To_String ( New_File_Name ) ) {system service which renames a file within a system.} 3. if unsuccessful then invoke OSI_Error_Handler.Map_Last_Error 4. exit subprogram Copy_File in File_Name : OSI_String New_File_Name : OSI_String no out parameters 1. validate File_Name and New_File_Name as legal filenames 2. on error invoke OSI_Error_Handler.Map_Last_Error 3. declare The_Buffer as an array of bytes 4. open ( path => OSI_Standard.To_String ( File_Name ) {Source File} , oflag => O_RDONLY {Open for reading} , mode => Dummy {not needed when opening a file} ) {system service which opens the file given by File_Name for reading} 5. open ( path => OSI_Standard.To_String ( New_File_Name ) {Target File} , oflag => O_WRONLY {Open for writing} + O_CREAT {Create the file if it does not exist} + O_TRUNC {Truncate the file length to 0 if it exist} , mode => TBD ) 6. iterate read into The_Buffer from the Source File write The_Buffer to the Target File {system services read and write are used to perform these operations} until the end of file of the Source File is encountered {Last byte contains a 0} 7. close Source File {system service close} 8. close Target File {system service close} 9. Get mode of source file 10. Set mode of target file := mode of source file {chmod} 11. exit The next two subprograms (Is_File and Is_Directory) are similar with the exception that one determines whether a file is a regular file and the other one determines if a file identifies a directory. The following internal subprogram will be used to implement both subprograms: subprogram Assert in File_Name : OSI_String The_File_Type : Stat_Type.ST_Type out Boolean 1. statx ( path => OSI_Standard.To_String ( File_Name ) , buf => The_File_Statistics , len => The_File_Statistics'Length , cmd => TBD ) {The statx system service returns information about a file in the buffer buf.} 2. if unsuccessful then return False else if The_File_Statistics.ST_Type = File_Type then return true else return False end if ; end if ; subprogram Is_File in File_Name : OSI_String out Boolean 1. validate File_Name as a legal filename 2. if Assert ( File_Name => File_Name , File_Type => VREG ) then return True else return False end if 3. exit subprogram Is_Directory in File_Name : OSI_String out Boolean 1. validate File_Name as a legal filename 2. if Assert ( File_Name => File_Name , File_Type => VDIR ) then return True else return False end if 3. exit subprogram Directory_Reader in Directory_Name : OSI_String subprogram Action no out parameters 1. validate Directory_Name as a legal filename. 2. on error invoke OSI_Error_Handler.Map_Last_Error 3. opendir ( dirname => OSI_Standard.To_String ( Directory_Name ) ) {system service which opens the directory given by dirname and associates a directory stream with it} 4. iterate read next directory entry {system service readdir} exit if no more directory entries (value returned from read = null ) execute the imported subprogram Action on the selected directory entry 5. close the directory identified by Directory_Name {system service closedir} 6. exit subprogram Accessible in File_Name : OSI_String Permissions : Access_Mode_Set no out parameters 1. validate File_Name as a legal filename 2. The_Access_Mode := Mapping of Permissions to integer which represents the given access modes. 3. access ( path => OSI_Standard.To_String ( File_Name ) , mode => The_Access_Mode ) {system service which determines whether the file identified by path is accessible with the given mode.} 4. if unsuccessful invoke OSI_Error_Handler.Map_Last_Error 5. exit subprogram Host_Name_Of in File_Name : OSI_String out String 1. validate File_Name as a legal filename 1. The_String := OSI_Standard.To_String ( File_Name ) 2. return The_String 3. exit OSI_Processes subprogram Invoke_Process in File_Name : OSI_String Parameter_List : OSI_String no out parameters 1. validate File_Name as a legal filename 2. on error invoke OSI_Handle_Error.Map_Last_Error 3. fork () {The fork system service creates a new process. The new process is an exact copy of the calling process.} 4. execlp ( File => OSI_Standard.To_String ( File_Name ) , arg0 .. argn => Parameters_List ) {The execlp system service executes a file. The service will try to execute the file as an executable image. If it fails, the service assumes that the file is a shell script and invokes a known command interpreter to interpret the file.} 5. wait3 ( status,options,rusage => TBD ) {This system service waits for a child process to terminate.} 6. exit subprogram Parameter_List no in parameters out String At this point, we are not sure that this operation can be implemented in multiple platforms. We will continue our research on this. We have two fallbacks: a) Don't support the routine and make the user depend on environment variables to store this information. b) Support the routine and reserve one environment variable to contain the process parameters. subprogram Environment_Value_Of in Name : OSI_String out String 1. The_String := getenv ( name => name ) {system service which gets the value of the environment variable given by Name.} 2. return The_String 3. exit subprogram Get_Effective_User_Login_Name no in parameters out String 1. The_String := getlogin {system service which gets the name of the user executing the current process.} 3. return The_String 4. exit