Commit 09b57dfe by Bob Duff Committed by Arnaud Charlet

sysdep.c (__gnat_has_cap_sys_nice): New function to determine whether the…

sysdep.c (__gnat_has_cap_sys_nice): New function to determine whether the current process has the CAP_SYS_NICE...

2017-09-06  Bob Duff  <duff@adacore.com>

	* sysdep.c (__gnat_has_cap_sys_nice): New function to determine
	whether the current process has the CAP_SYS_NICE capability.
	* s-taprop-linux.adb (Get_Ceiling_Support): Update this to allow
	ceiling priorities if the current process has the CAP_SYS_NICE
	capability.

From-SVN: r251777
parent 7d827255
2017-09-06 Bob Duff <duff@adacore.com> 2017-09-06 Bob Duff <duff@adacore.com>
* sysdep.c (__gnat_has_cap_sys_nice): New function to determine
whether the current process has the CAP_SYS_NICE capability.
* s-taprop-linux.adb (Get_Ceiling_Support): Update this to allow
ceiling priorities if the current process has the CAP_SYS_NICE
capability.
2017-09-06 Bob Duff <duff@adacore.com>
* a-comlin.ads, a-comlin.adb (Argument): Move the constraint * a-comlin.ads, a-comlin.adb (Argument): Move the constraint
check back to the body, because SPARK is not yet ready for check back to the body, because SPARK is not yet ready for
"or else raise Constraint_Error". "or else raise Constraint_Error".
......
...@@ -165,6 +165,13 @@ package body System.Task_Primitives.Operations is ...@@ -165,6 +165,13 @@ package body System.Task_Primitives.Operations is
pragma Import pragma Import
(C, GNAT_pthread_condattr_setup, "__gnat_pthread_condattr_setup"); (C, GNAT_pthread_condattr_setup, "__gnat_pthread_condattr_setup");
function GNAT_has_cap_sys_nice return C.int;
pragma Import
(C, GNAT_has_cap_sys_nice, "__gnat_has_cap_sys_nice");
-- We do not have pragma Linker_Options ("-lcap"); here, because this
-- library is not present on many Linux systems. 'libcap' is the Linux
-- "capabilities" library, called by __gnat_has_cap_sys_nice.
function Prio_To_Linux_Prio (Prio : Any_Priority) return C.int is function Prio_To_Linux_Prio (Prio : Any_Priority) return C.int is
(C.int (Prio) + 1); (C.int (Prio) + 1);
-- Convert Ada priority to Linux priority. Priorities are 1 .. 99 on -- Convert Ada priority to Linux priority. Priorities are 1 .. 99 on
...@@ -172,24 +179,26 @@ package body System.Task_Primitives.Operations is ...@@ -172,24 +179,26 @@ package body System.Task_Primitives.Operations is
function Get_Ceiling_Support return Boolean; function Get_Ceiling_Support return Boolean;
-- Get the value of the Ceiling_Support constant (see below). -- Get the value of the Ceiling_Support constant (see below).
-- ???For now, we're returning True only if running as superuser, -- Note well: If this function or related code is modified, it should be
-- and ignore capabilities. -- tested by hand, because automated testing doesn't exercise it.
function Get_Ceiling_Support return Boolean is function Get_Ceiling_Support return Boolean is
Ceiling_Support : Boolean := False; Ceiling_Support : Boolean := False;
begin begin
if Locking_Policy = 'C' then if Locking_Policy /= 'C' then
declare return False;
function geteuid return Integer;
pragma Import (C, geteuid, "geteuid");
Superuser : constant Boolean := geteuid = 0;
begin
if Superuser then
Ceiling_Support := True;
end if;
end;
end if; end if;
declare
function geteuid return Integer;
pragma Import (C, geteuid, "geteuid");
Superuser : constant Boolean := geteuid = 0;
Has_Cap : constant C.int := GNAT_has_cap_sys_nice;
pragma Assert (Has_Cap in 0 | 1);
begin
Ceiling_Support := Superuser or else Has_Cap = 1;
end;
return Ceiling_Support; return Ceiling_Support;
end Get_Ceiling_Support; end Get_Ceiling_Support;
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* * * *
* C Implementation File * * C Implementation File *
* * * *
* Copyright (C) 1992-2016, Free Software Foundation, Inc. * * Copyright (C) 1992-2017, Free Software Foundation, Inc. *
* * * *
* GNAT is free software; you can redistribute it and/or modify it under * * GNAT is free software; you can redistribute it and/or modify it under *
* terms of the GNU General Public License as published by the Free Soft- * * terms of the GNU General Public License as published by the Free Soft- *
...@@ -919,6 +919,76 @@ __gnat_is_file_not_found_error (int errno_val) { ...@@ -919,6 +919,76 @@ __gnat_is_file_not_found_error (int errno_val) {
} }
} }
#if defined (__linux__)
/* HAVE_CAPABILITY is defined if sys/capability.h exists on the system where
this is being compiled.
*/
#if defined (HAVE_CAPABILITY)
#include <sys/capability.h>
/* Note well: If this code is modified, it should be tested by hand,
because automated testing doesn't exercise it.
*/
/* __gnat_has_cap_sys_nice returns 1 if the current process has the
CAP_SYS_NICE capability. This capability is necessary to use the
Ceiling_Locking policy. Returns 0 otherwise. Note that this is
defined only for Linux.
*/
/* Define these as weak symbols, so if support for capabilities is not present,
programs can still link. On Ubuntu, support for capabilities can be
installed via "sudo apt-get --assume-yes install libcap-dev".
In addition, the user must link with "-lcap", or else these
symbols will be 0, and __gnat_has_cap_sys_nice will return 0.
*/
static cap_t cap_get_proc_weak() __attribute__ ((weakref ("cap_get_proc")));
static int cap_get_flag_weak() __attribute__ ((weakref ("cap_get_flag")));
static int cap_free_weak() __attribute__ ((weakref ("cap_free")));
int
__gnat_has_cap_sys_nice () {
/* If the address of cap_get_proc_weak is 0, this means support for
capabilities is not present, so we return 0. */
if (&cap_get_proc_weak == 0)
return 0;
cap_t caps = cap_get_proc_weak();
cap_flag_value_t value;
if (caps == NULL)
return 0;
if (cap_get_flag_weak(caps, CAP_SYS_NICE, CAP_EFFECTIVE, &value) == -1)
return 0;
if (cap_free_weak(caps) == -1)
return 0;
if (value == CAP_SET)
return 1;
return 0;
}
#else
/* HAVE_CAPABILITY is not defined, so sys/capability.h does not exist, so
simply indicate that the current process does not have the CAP_SYS_NICE
capability.
*/
int
__gnat_has_cap_sys_nice () {
return 0;
}
#endif
#endif
#ifdef __ANDROID__ #ifdef __ANDROID__
/* Provide extern symbols for sig* as needed by the tasking run-time, instead /* Provide extern symbols for sig* as needed by the tasking run-time, instead
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment