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>
* 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
check back to the body, because SPARK is not yet ready for
"or else raise Constraint_Error".
......
......@@ -165,6 +165,13 @@ package body System.Task_Primitives.Operations is
pragma Import
(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
(C.int (Prio) + 1);
-- Convert Ada priority to Linux priority. Priorities are 1 .. 99 on
......@@ -172,24 +179,26 @@ package body System.Task_Primitives.Operations is
function Get_Ceiling_Support return Boolean;
-- Get the value of the Ceiling_Support constant (see below).
-- ???For now, we're returning True only if running as superuser,
-- and ignore capabilities.
-- Note well: If this function or related code is modified, it should be
-- tested by hand, because automated testing doesn't exercise it.
function Get_Ceiling_Support return Boolean is
Ceiling_Support : Boolean := False;
begin
if Locking_Policy = 'C' then
declare
function geteuid return Integer;
pragma Import (C, geteuid, "geteuid");
Superuser : constant Boolean := geteuid = 0;
begin
if Superuser then
Ceiling_Support := True;
end if;
end;
if Locking_Policy /= 'C' then
return False;
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;
end Get_Ceiling_Support;
......
......@@ -6,7 +6,7 @@
* *
* 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 *
* 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) {
}
}
#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__
/* 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