diff options
author | Arnaud Charlet <charlet@gcc.gnu.org> | 2017-09-11 12:12:05 +0200 |
---|---|---|
committer | Arnaud Charlet <charlet@gcc.gnu.org> | 2017-09-11 12:12:05 +0200 |
commit | a0713cb6beb00ca850e7c20f287d32f1e1a14a49 (patch) | |
tree | c3c846308e8396ca48bd205ca87021e5afd9a0f0 /gcc/ada/libgnat/s-mmosin__unix.adb | |
parent | 6f77df7260f6f1ce89ecb2ee82d9f40447d813bc (diff) | |
download | gcc-a0713cb6beb00ca850e7c20f287d32f1e1a14a49.zip gcc-a0713cb6beb00ca850e7c20f287d32f1e1a14a49.tar.gz gcc-a0713cb6beb00ca850e7c20f287d32f1e1a14a49.tar.bz2 |
libgnat: Rename ?-[a-z]*-* into ?-[a-z]*__*
2017-09-11 Jerome Lambourg <lambourg@adacore.com>
* libgnat: Rename ?-[a-z]*-* into ?-[a-z]*__*
* gcc-interface/Makefile.in, gcc-interface/Make-lang.in: Take this
renaming into account.
From-SVN: r251968
Diffstat (limited to 'gcc/ada/libgnat/s-mmosin__unix.adb')
-rw-r--r-- | gcc/ada/libgnat/s-mmosin__unix.adb | 229 |
1 files changed, 229 insertions, 0 deletions
diff --git a/gcc/ada/libgnat/s-mmosin__unix.adb b/gcc/ada/libgnat/s-mmosin__unix.adb new file mode 100644 index 0000000..aec2538 --- /dev/null +++ b/gcc/ada/libgnat/s-mmosin__unix.adb @@ -0,0 +1,229 @@ +------------------------------------------------------------------------------ +-- -- +-- GNAT RUN-TIME COMPONENTS -- +-- -- +-- S Y S T E M . M M A P . O S _ I N T E R F A C E -- +-- -- +-- B o d y -- +-- -- +-- Copyright (C) 2007-2017, AdaCore -- +-- -- +-- This library is free software; you can redistribute it and/or modify it -- +-- under terms of the GNU General Public License as published by the Free -- +-- Software Foundation; either version 3, or (at your option) any later -- +-- version. This library is distributed in the hope that it will be useful, -- +-- but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- -- +-- TABILITY or FITNESS FOR A PARTICULAR PURPOSE. -- +-- -- +-- As a special exception under Section 7 of GPL version 3, you are granted -- +-- additional permissions described in the GCC Runtime Library Exception, -- +-- version 3.1, as published by the Free Software Foundation. -- +-- -- +-- You should have received a copy of the GNU General Public License and -- +-- a copy of the GCC Runtime Library Exception along with this program; -- +-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- +-- <http://www.gnu.org/licenses/>. -- +-- -- +-- GNAT was originally developed by the GNAT team at New York University. -- +-- Extensive contributions were provided by Ada Core Technologies Inc. -- +-- -- +------------------------------------------------------------------------------ + +with Ada.IO_Exceptions; +with System; use System; + +with System.OS_Lib; use System.OS_Lib; +with System.Mmap.Unix; use System.Mmap.Unix; + +package body System.Mmap.OS_Interface is + + function Align + (Addr : File_Size) return File_Size; + -- Align some offset/length to the lowest page boundary + + function Is_Mapping_Available return Boolean renames + System.Mmap.Unix.Is_Mapping_Available; + -- Wheter memory mapping is actually available on this system. It is an + -- error to use Create_Mapping and Dispose_Mapping if this is False. + + --------------- + -- Open_Read -- + --------------- + + function Open_Read + (Filename : String; + Use_Mmap_If_Available : Boolean := True) return System_File is + Fd : constant File_Descriptor := + Open_Read (Filename, Binary); + begin + if Fd = Invalid_FD then + return Invalid_System_File; + end if; + return + (Fd => Fd, + Mapped => Use_Mmap_If_Available and then Is_Mapping_Available, + Write => False, + Length => File_Size (File_Length (Fd))); + end Open_Read; + + ---------------- + -- Open_Write -- + ---------------- + + function Open_Write + (Filename : String; + Use_Mmap_If_Available : Boolean := True) return System_File is + Fd : constant File_Descriptor := + Open_Read_Write (Filename, Binary); + begin + if Fd = Invalid_FD then + return Invalid_System_File; + end if; + return + (Fd => Fd, + Mapped => Use_Mmap_If_Available and then Is_Mapping_Available, + Write => True, + Length => File_Size (File_Length (Fd))); + end Open_Write; + + ----------- + -- Close -- + ----------- + + procedure Close (File : in out System_File) is + begin + Close (File.Fd); + File.Fd := Invalid_FD; + end Close; + + -------------------- + -- Read_From_Disk -- + -------------------- + + function Read_From_Disk + (File : System_File; + Offset, Length : File_Size) return System.Strings.String_Access + is + Buffer : String_Access := new String (1 .. Integer (Length)); + begin + -- ??? Lseek offset should be a size_t instead of a Long_Integer + + Lseek (File.Fd, Long_Integer (Offset), Seek_Set); + if System.OS_Lib.Read (File.Fd, Buffer.all'Address, Integer (Length)) + /= Integer (Length) + then + System.Strings.Free (Buffer); + raise Ada.IO_Exceptions.Device_Error; + end if; + return Buffer; + end Read_From_Disk; + + ------------------- + -- Write_To_Disk -- + ------------------- + + procedure Write_To_Disk + (File : System_File; + Offset, Length : File_Size; + Buffer : System.Strings.String_Access) is + begin + pragma Assert (File.Write); + Lseek (File.Fd, Long_Integer (Offset), Seek_Set); + if System.OS_Lib.Write (File.Fd, Buffer.all'Address, Integer (Length)) + /= Integer (Length) + then + raise Ada.IO_Exceptions.Device_Error; + end if; + end Write_To_Disk; + + -------------------- + -- Create_Mapping -- + -------------------- + + procedure Create_Mapping + (File : System_File; + Offset, Length : in out File_Size; + Mutable : Boolean; + Mapping : out System_Mapping) + is + Prot : Mmap_Prot; + Flags : Mmap_Flags; + begin + if File.Write then + Prot := PROT_READ + PROT_WRITE; + Flags := MAP_SHARED; + else + Prot := PROT_READ; + if Mutable then + Prot := Prot + PROT_WRITE; + end if; + Flags := MAP_PRIVATE; + end if; + + -- Adjust offset and mapping length to account for the required + -- alignment of offset on page boundary. + + declare + Queried_Offset : constant File_Size := Offset; + begin + Offset := Align (Offset); + + -- First extend the length to compensate the offset shift, then align + -- it on the upper page boundary, so that the whole queried area is + -- covered. + + Length := Length + Queried_Offset - Offset; + Length := Align (Length + Get_Page_Size - 1); + end; + + if Length > File_Size (Integer'Last) then + raise Ada.IO_Exceptions.Device_Error; + else + Mapping := + (Address => System.Mmap.Unix.Mmap + (Offset => off_t (Offset), + Length => Interfaces.C.size_t (Length), + Prot => Prot, + Flags => Flags, + Fd => File.Fd), + Length => Length); + end if; + end Create_Mapping; + + --------------------- + -- Dispose_Mapping -- + --------------------- + + procedure Dispose_Mapping + (Mapping : in out System_Mapping) + is + Ignored : Integer; + pragma Unreferenced (Ignored); + begin + Ignored := Munmap + (Mapping.Address, Interfaces.C.size_t (Mapping.Length)); + Mapping := Invalid_System_Mapping; + end Dispose_Mapping; + + ------------------- + -- Get_Page_Size -- + ------------------- + + function Get_Page_Size return File_Size is + function Internal return Integer; + pragma Import (C, Internal, "getpagesize"); + begin + return File_Size (Internal); + end Get_Page_Size; + + ----------- + -- Align -- + ----------- + + function Align + (Addr : File_Size) return File_Size is + begin + return Addr - Addr mod Get_Page_Size; + end Align; + +end System.Mmap.OS_Interface; |